CORERTL.A 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118
  1. (* Release 3.10 *)
  2. (*-------------------------------------------------------------------------*
  3. * *
  4. * CORERTL.A - compiler helper functions *
  5. * *
  6. * COPYRIGHT (C) 1989..1992 Clarion Software Corporation. *
  7. * All Rights Reserved *
  8. * *
  9. *--------------------------------------------------------------------------*)
  10. include "corelib.inc"
  11. module CoreRTL
  12. (****************************************************************************)
  13. section
  14. segment ORDER(FCODE,68H)
  15. segment ORDER(MIXED,68H)
  16. segment ORDER(DATA,68H)
  17. segment ORDER(M_DATA,68H)
  18. segment ORDER(FAR_DATA,68H)
  19. segment ORDER(FAR_BSS,68H)
  20. segment ORDER(BSS,68H)
  21. segment ORDER(BSSEND,68H)
  22. segment STACK(STACK,68H)
  23. segment HEAP(HEAP,68H)
  24. (****************************************************************************)
  25. (* start of far handlers for compiler generated calls *)
  26. (****************************************************************************)
  27. section
  28. (*%F SameDS *)
  29. segment CORE_TEXT(CODE,28H);
  30. (*%E *)
  31. (*%T SameDS *)
  32. segment _TEXT(CODE,28H);
  33. (*%E *)
  34. public F$UnsMol : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  35. public F$SgnMol :
  36. (* Unsigned/signed multiplication *)
  37. (* On overflow: modulus 2^32 wrap-around *)
  38. push bp
  39. mov bp,sp
  40. mov ax,[bp][High1]
  41. and ax,ax
  42. jnz UnsMol2
  43. add ax,[bp][High2]
  44. jnz UnsMol1
  45. mov ax,[bp][Low1]
  46. mul word [bp][Low2]
  47. pop bp
  48. ret far 8
  49. UnsMol1:
  50. mul word [bp][Low1]
  51. mov dx,[bp][Low1]
  52. mov bp,[bp][Low2]
  53. xchg bp,ax
  54. mul dx
  55. add dx,bp
  56. pop bp
  57. ret far 8
  58. UnsMol2:
  59. mov dx,[bp][High2]
  60. and dx,dx
  61. jnz UnsMol3
  62. mul word [bp][Low2]
  63. mov dx,[bp][Low1]
  64. mov bp,[bp][Low2]
  65. xchg bp,ax
  66. mul dx
  67. add dx,bp
  68. pop bp
  69. ret far 8
  70. UnsMol3:
  71. push cx
  72. mul word [bp][Low2]
  73. mov cx,ax
  74. mov ax,[bp][High2]
  75. mul word [bp][Low1]
  76. add cx,ax
  77. mov ax,[bp][Low1]
  78. mul word [bp][Low2]
  79. add dx,cx
  80. pop cx
  81. pop bp
  82. ret far 8
  83. section
  84. (*%F SameDS *)
  85. segment CORE_TEXT(CODE,28H);
  86. (*%E *)
  87. (*%T SameDS *)
  88. segment _TEXT(CODE,28H);
  89. (*%E *)
  90. extrn F$UnsMul
  91. public F$SgnDiv : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  92. (*Signed division *)
  93. (*On overflow: result MAXINT, OF set *)
  94. push bp
  95. mov bp,sp
  96. push cx
  97. push si
  98. xor si,si
  99. (* DIV / 0 Test *)
  100. mov dx,[bp][High2]
  101. or dx,[bp][Low2]
  102. jnz DivOK
  103. extrn F$CnsDiv
  104. add sp, 6
  105. jmp F$CnsDiv
  106. DivOK:
  107. mov dx,[bp][High1]
  108. and dx,dx
  109. jge SgnDiv5
  110. not si
  111. neg dx
  112. neg word [bp][Low1]
  113. sbb dx,0
  114. mov [bp][High1],dx
  115. SgnDiv5:
  116. mov dx,[bp][High2]
  117. and dx,dx
  118. jg SgnDiv1
  119. jz SgnDiv6
  120. not si
  121. neg dx
  122. neg word [bp][Low2]
  123. sbb dx,0
  124. mov [bp][High2],dx
  125. jnz SgnDiv1
  126. SgnDiv6:
  127. mov cx,[bp][Low2]
  128. jcxz SgnDiv0
  129. mov dx,[bp][High1]
  130. cmp dx,cx
  131. jae SgnDivA
  132. mov ax,[bp][Low1]
  133. div cx
  134. xor dx,dx
  135. SgnDiv9:
  136. add ax,si
  137. adc dx,si
  138. xor ax,si
  139. xor dx,si
  140. SgnDiv7:
  141. pop si
  142. pop cx
  143. pop bp
  144. ret far 8
  145. SgnDivA:
  146. mov ax,dx
  147. xor dx,dx
  148. div cx
  149. mov cx,ax
  150. mov ax,[bp][Low1]
  151. div word [bp][Low2]
  152. mov dx,cx
  153. jmp SgnDiv9
  154. SgnDiv1:
  155. push bx
  156. mov cx,dx
  157. mov bx,[bp][Low2]
  158. mov dx,[bp][High1]
  159. mov ax,[bp][Low1]
  160. push cx
  161. push bx
  162. SgnDiv2:
  163. shr dx,1
  164. rcr ax,1
  165. shr cx,1
  166. rcr bx,1
  167. and cx,cx
  168. jnz SgnDiv2
  169. div bx
  170. mov bx,ax
  171. push cx
  172. push ax
  173. call far F$UnsMul
  174. jo SgnDiv3
  175. cmp dx,[bp][High1]
  176. ja SgnDiv3
  177. jb SgnDiv4
  178. cmp ax,[bp][Low1]
  179. jbe SgnDiv4
  180. SgnDiv3:
  181. dec bx
  182. SgnDiv4:
  183. mov ax,bx
  184. xor dx,dx
  185. pop bx
  186. jmp SgnDiv9
  187. SgnDiv0:
  188. mov al,100
  189. add al,al
  190. mov ax,0FFFFH
  191. mov dx,07FFFH
  192. jmp SgnDiv7
  193. section
  194. (*%F SameDS *)
  195. segment CORE_TEXT(CODE,28H);
  196. (*%E *)
  197. (*%T SameDS *)
  198. segment _TEXT(CODE,28H);
  199. (*%E *)
  200. extrn F$UnsMul
  201. public F$UnsDiv : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  202. (*Unsigned division *)
  203. (*On overflow: result MAXCARD, OF set *)
  204. push bp
  205. mov bp,sp
  206. push cx
  207. (* DIV / 0 Test *)
  208. mov cx,[bp][High2]
  209. or cx,[bp][Low2]
  210. jnz DivOK
  211. extrn F$CnsDiv
  212. add sp, 4
  213. jmp F$CnsDiv
  214. DivOK:
  215. mov cx,[bp][High2]
  216. and cx,cx
  217. jnz UnsDiv1
  218. add cx,[bp][Low2]
  219. jz UnsDiv0
  220. mov dx,[bp][High1]
  221. cmp dx,cx
  222. jae UnsDiv7 (*!!!!New special case *)
  223. mov ax,[bp][Low1]
  224. div cx
  225. xor dx,dx
  226. UnsDiv8:
  227. and ax,ax
  228. UnsDiv9:
  229. pop cx
  230. pop bp
  231. ret far 8
  232. UnsDiv7:
  233. mov ax,dx
  234. xor dx,dx
  235. div cx
  236. mov cx,ax
  237. mov ax,[bp][Low1]
  238. div word [bp][Low2]
  239. mov dx,cx
  240. jmp UnsDiv8
  241. UnsDiv1:
  242. push bx
  243. mov dx,[bp][High1]
  244. mov ax,[bp][Low1]
  245. mov bx,[bp][Low2]
  246. push cx
  247. push bx
  248. UnsDiv2:
  249. shr dx,1
  250. rcr ax,1
  251. shr cx,1
  252. rcr bx,1
  253. and cx,cx
  254. jnz UnsDiv2
  255. div bx
  256. mov bx,ax
  257. push cx
  258. push ax
  259. call far F$UnsMul
  260. jo UnsDiv3
  261. cmp dx,[bp][High1]
  262. jb UnsDiv4
  263. ja UnsDiv3
  264. cmp ax,[bp][Low1]
  265. jbe UnsDiv4
  266. UnsDiv3:
  267. dec bx
  268. UnsDiv4:
  269. mov ax,bx
  270. xor dx,dx
  271. pop bx
  272. jmp UnsDiv8
  273. UnsDiv0:
  274. mov al,100
  275. add al,al
  276. mov ax,0FFFFH
  277. mov dx,ax
  278. jmp UnsDiv9
  279. section
  280. (*%F SameDS *)
  281. segment CORE_TEXT(CODE,28H);
  282. (*%E *)
  283. (*%T SameDS *)
  284. segment _TEXT(CODE,28H);
  285. (*%E *)
  286. extrn F$UnsMul
  287. public F$SgnRem : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  288. (*Signed remainder *)
  289. (*On overflow: result 0, OF set *)
  290. push bp
  291. mov bp,sp
  292. push cx
  293. push si
  294. (* DIV / 0 Test *)
  295. mov dx,[bp][High2]
  296. or dx,[bp][Low2]
  297. jnz DivOK
  298. extrn F$CnsDiv
  299. add sp, 6
  300. jmp F$CnsDiv
  301. DivOK:
  302. xor si,si
  303. mov dx,[bp][High1]
  304. and dx,dx
  305. jge SgnRem5
  306. not si
  307. neg dx
  308. neg word [bp][Low1]
  309. sbb dx,0
  310. mov [bp][High1],dx
  311. SgnRem5:
  312. mov dx,[bp][High2]
  313. and dx,dx
  314. jg SgnRem1
  315. jz SgnRem6
  316. neg dx
  317. neg word [bp][Low2]
  318. sbb dx,0
  319. mov [bp][High2],dx
  320. jnz SgnRem1
  321. SgnRem6:
  322. mov cx,[bp][Low2]
  323. jcxz SgnRem0
  324. mov ax,[bp][High1]
  325. div cx
  326. mov ax,[bp][Low1]
  327. div cx
  328. mov ax,dx
  329. xor dx,dx
  330. SgnRem9:
  331. add ax,si
  332. adc dx,si
  333. xor ax,si
  334. xor dx,si
  335. SgnRem7:
  336. pop si
  337. pop cx
  338. pop bp
  339. ret far 8
  340. SgnRem1:
  341. push bx
  342. mov cx,dx
  343. mov bx,[bp][Low2]
  344. mov dx,[bp][High1]
  345. mov ax,[bp][Low1]
  346. push cx
  347. push bx
  348. SgnRem2:
  349. shr dx,1
  350. rcr ax,1
  351. shr cx,1
  352. rcr bx,1
  353. and cx,cx
  354. jnz SgnRem2
  355. div bx
  356. push cx
  357. push ax
  358. call far F$UnsMul
  359. cmp dx,[bp][High1]
  360. ja SgnRem3
  361. jb SgnRem4
  362. cmp ax,[bp][Low1]
  363. jbe SgnRem4
  364. SgnRem3:
  365. sub ax,[bp][Low2]
  366. sbb dx,[bp][High2]
  367. SgnRem4:
  368. sub ax,[bp][Low1]
  369. sbb dx,[bp][High1]
  370. neg dx
  371. neg ax
  372. sbb dx,cx
  373. pop bx
  374. jmp SgnRem9
  375. SgnRem0:
  376. sub dx,dx
  377. mov al,100
  378. add al,al
  379. mov ax,dx
  380. jmp SgnRem7
  381. section
  382. (*%F SameDS *)
  383. segment CORE_TEXT(CODE,28H);
  384. (*%E *)
  385. (*%T SameDS *)
  386. segment _TEXT(CODE,28H);
  387. (*%E *)
  388. extrn F$UnsMul
  389. public F$SgnMod : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  390. (*Signed modulus *)
  391. (*On overflow: result 0, OF set *)
  392. push bp
  393. mov bp,sp
  394. push cx
  395. push bx
  396. (* DIV / 0 Test *)
  397. mov dx,[bp][High2]
  398. or dx,[bp][Low2]
  399. jnz DivOK
  400. extrn F$CnsDiv
  401. add sp, 6
  402. jmp F$CnsDiv
  403. DivOK:
  404. mov dx,[bp][High1]
  405. mov bh, dh
  406. and dx,dx
  407. jge SgnMod5
  408. neg dx
  409. neg word [bp][Low1]
  410. sbb dx,0
  411. mov [bp][High1],dx
  412. SgnMod5:
  413. mov dx,[bp][High2]
  414. mov bl,dh
  415. and dx,dx
  416. jg SgnMod1
  417. jz SgnMod6
  418. neg dx
  419. neg word [bp][Low2]
  420. sbb dx,0
  421. mov [bp][High2],dx
  422. jnz SgnMod1
  423. SgnMod6:
  424. mov cx,[bp][Low2]
  425. jcxz SgnMod0
  426. mov ax,[bp][High1]
  427. div cx
  428. mov ax,[bp][Low1]
  429. div cx
  430. mov ax,dx
  431. xor dx,dx
  432. SgnMod9:
  433. mov cx,ax
  434. or cx,dx
  435. jz SgnMod7
  436. xor bh,bl
  437. jge SgnMod10
  438. sub ax,[bp][Low2]
  439. sbb dx,[bp][High2]
  440. not bl
  441. SgnMod10:
  442. shl bl,1
  443. jnc SgnMod7
  444. neg dx
  445. neg ax
  446. sbb dx,0
  447. SgnMod7:
  448. pop bx
  449. pop cx
  450. pop bp
  451. ret far 8
  452. SgnMod1:
  453. push si
  454. mov cx,dx
  455. mov si,[bp][Low2]
  456. mov dx,[bp][High1]
  457. mov ax,[bp][Low1]
  458. push cx
  459. push si
  460. SgnMod2:
  461. shr dx,1
  462. rcr ax,1
  463. shr cx,1
  464. rcr si,1
  465. and cx,cx
  466. jnz SgnMod2
  467. div si
  468. push cx
  469. push ax
  470. call far F$UnsMul
  471. cmp dx,[bp][High1]
  472. ja SgnMod3
  473. jb SgnMod4
  474. cmp ax,[bp][Low1]
  475. jbe SgnMod4
  476. SgnMod3:
  477. sub ax,[bp][Low2]
  478. sbb dx,[bp][High2]
  479. SgnMod4:
  480. sub ax,[bp][Low1]
  481. sbb dx,[bp][High1]
  482. neg dx
  483. neg ax
  484. sbb dx,cx
  485. pop si
  486. jmp SgnMod9
  487. SgnMod0: (* overflow *)
  488. sub dx,dx
  489. mov al,100
  490. add al,al
  491. mov ax,dx
  492. jmp SgnMod7
  493. section
  494. (*%F SameDS *)
  495. segment CORE_TEXT(CODE,28H);
  496. (*%E *)
  497. (*%T SameDS *)
  498. segment _TEXT(CODE,28H);
  499. (*%E *)
  500. extrn F$UnsMul
  501. public F$UnsRem : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  502. (*Unsigned remainder/modulus *)
  503. (*On overflow: result 0, OF set *)
  504. push bp
  505. mov bp,sp
  506. push cx
  507. (* DIV / 0 Test *)
  508. mov cx,[bp][High2]
  509. or cx,[bp][Low2]
  510. jnz DivOK
  511. extrn F$CnsDiv
  512. add sp, 4
  513. jmp F$CnsDiv
  514. DivOK:
  515. mov cx,[bp][High2]
  516. and cx,cx
  517. jnz UnsRem1
  518. add cx,[bp][Low2]
  519. jz UnsRem0
  520. mov ax,[bp][High1]
  521. xor dx,dx
  522. div cx
  523. mov ax,[bp][Low1]
  524. div cx
  525. mov ax,dx
  526. xor dx,dx
  527. UnsRem9:
  528. pop cx
  529. pop bp
  530. ret far 8
  531. UnsRem1:
  532. push bx
  533. mov dx,[bp][High1]
  534. mov ax,[bp][Low1]
  535. mov bx,[bp][Low2]
  536. push cx
  537. push bx
  538. UnsRem2:
  539. shr dx,1
  540. rcr ax,1
  541. shr cx,1
  542. rcr bx,1
  543. and cx,cx
  544. jnz UnsRem2
  545. div bx
  546. sub ax,1
  547. adc ax,0
  548. push cx
  549. push ax
  550. call far F$UnsMul
  551. add ax,[bp][Low2]
  552. adc dx,[bp][High2]
  553. jc UnsRem3
  554. cmp dx,[bp][High1]
  555. jb UnsRem4
  556. ja UnsRem3
  557. cmp ax,[bp][Low1]
  558. jbe UnsRem4
  559. UnsRem3:
  560. sub ax,[bp][Low2]
  561. sbb dx,[bp][High2]
  562. UnsRem4:
  563. sub ax,[bp][Low1]
  564. sbb dx,[bp][High1]
  565. neg dx
  566. neg ax
  567. sbb dx,cx
  568. and ax,ax
  569. pop bx
  570. jmp UnsRem9
  571. UnsRem0:
  572. xor dx,dx
  573. mov al,100
  574. add al,al
  575. mov ax,dx
  576. jmp UnsRem9
  577. section
  578. (*%F SameDS *)
  579. segment CORE_TEXT(CODE,28H);
  580. (*%E *)
  581. (*%T SameDS *)
  582. segment _TEXT(CODE,28H);
  583. (*%E *)
  584. public F$UnsMul : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  585. (*Unsigned multiplication *)
  586. (*On overflow: result MAXCARD, OF set *)
  587. push bp
  588. mov bp,sp
  589. mov ax,[bp][High1]
  590. and ax,ax
  591. jnz UnsMul1
  592. add ax,[bp][High2]
  593. jnz UnsMul2
  594. mov ax,[bp][Low1]
  595. mul word [bp][Low2]
  596. UnsMul8:
  597. and ax,ax
  598. UnsMul9:
  599. pop bp
  600. ret far 8
  601. UnsMul1:
  602. cmp word [bp][High2],0
  603. jnz UnsMul0
  604. mul word [bp][Low2]
  605. jmp UnsMul3
  606. UnsMul2:
  607. mul word [bp][Low1]
  608. UnsMul3:
  609. jc UnsMul0
  610. mov dx,[bp][Low1]
  611. mov bp,[bp][Low2]
  612. xchg ax,bp
  613. mul dx
  614. add dx,bp
  615. jnc UnsMul8
  616. UnsMul0:
  617. mov al,100
  618. add al,al
  619. stc
  620. mov ax,0FFFFH
  621. mov dx,ax
  622. jmp UnsMul9
  623. section
  624. (*%F SameDS *)
  625. segment CORE_TEXT(CODE,28H);
  626. (*%E *)
  627. (*%T SameDS *)
  628. segment _TEXT(CODE,28H);
  629. (*%E *)
  630. public F$SgnMul : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  631. (*Signed multiplication *)
  632. (*On overflow: result MAXINT, OF set *)
  633. push bp
  634. mov bp,sp
  635. push si
  636. xor si,si
  637. mov dx,[bp][High1]
  638. and dx,dx
  639. jge SgnMul5
  640. not si
  641. neg dx
  642. neg word [bp][Low1]
  643. sbb dx,0
  644. mov [bp][High1],dx
  645. SgnMul5:
  646. mov dx,[bp][High2]
  647. and dx,dx
  648. jg SgnMul6
  649. jz SgnMul1
  650. not si
  651. neg dx
  652. neg word [bp][Low2]
  653. sbb dx,0
  654. jz SgnMul1
  655. SgnMul6:
  656. cmp word [bp][High1],0
  657. jnz SgnMul0
  658. mov ax,dx
  659. mul word [bp][Low1]
  660. jmp SgnMul2
  661. SgnMul1:
  662. mov ax,[bp][High1]
  663. and ax,ax
  664. jz SgnMul2
  665. mul word [bp][Low2]
  666. SgnMul2:
  667. jc SgnMul0
  668. mov dx,[bp][Low1]
  669. mov bp,[bp][Low2]
  670. xchg ax,bp
  671. mul dx
  672. add dx,bp
  673. jc SgnMul0
  674. js SgnMul0
  675. add ax,si
  676. adc dx,si
  677. xor ax,si
  678. xor dx,si
  679. SgnMul7:
  680. pop si
  681. pop bp
  682. ret far 8
  683. SgnMul0:
  684. mov al,100
  685. add al,al
  686. mov ax,0FFFFH
  687. mov dx,07FFFH
  688. jmp SgnMul7
  689. section
  690. (*%F SameDS *)
  691. segment CORE_TEXT(CODE,28H);
  692. (*%E *)
  693. (*%T SameDS *)
  694. segment _TEXT(CODE,28H);
  695. (*%E *)
  696. public F$LngShl :
  697. (*%T _DLLOVL *)
  698. push bp
  699. mov bp, sp
  700. (*%E *)
  701. xor ch,ch
  702. jcxz $lshl1
  703. $lshl2:
  704. shl ax,1
  705. rcl dx,1
  706. loop $lshl2
  707. $lshl1:
  708. (*%T _DLLOVL *)
  709. pop bp
  710. (*%E *)
  711. ret far 0
  712. section
  713. (*%F SameDS *)
  714. segment CORE_TEXT(CODE,28H);
  715. (*%E *)
  716. (*%T SameDS *)
  717. segment _TEXT(CODE,28H);
  718. (*%E *)
  719. public F$LngShr :
  720. (*%T _DLLOVL *)
  721. push bp
  722. mov bp, sp
  723. (*%E *)
  724. xor ch,ch
  725. jcxz $lshr1
  726. $lshr2:
  727. sar dx,1
  728. rcr ax,1
  729. loop $lshr2
  730. $lshr1:
  731. (*%T _DLLOVL *)
  732. pop bp
  733. (*%E *)
  734. ret far 0
  735. section
  736. (*%F SameDS *)
  737. segment CORE_TEXT(CODE,28H);
  738. (*%E *)
  739. (*%T SameDS *)
  740. segment _TEXT(CODE,28H);
  741. (*%E *)
  742. public F$ULngShr :
  743. (*%T _DLLOVL *)
  744. push bp
  745. mov bp, sp
  746. (*%E *)
  747. xor ch,ch
  748. jcxz $ulshr1
  749. $ulshr2: shr dx,1
  750. rcr ax,1
  751. loop $ulshr2
  752. $ulshr1:
  753. (*%T _DLLOVL *)
  754. pop bp
  755. (*%E *)
  756. ret far 0
  757. section
  758. (*%F SameDS *)
  759. segment CORE_TEXT(CODE,28H);
  760. (*%E *)
  761. (*%T SameDS *)
  762. segment _TEXT(CODE,28H);
  763. (*%E *)
  764. public F$MovByt : SourceSeg =lframe+8; SourceOff = lframe+6; DestSeg = lframe+4; DestOff = lframe+2; Count = lframe
  765. push bp
  766. mov bp,sp
  767. push cx; push si; push di; push es; push ds;
  768. mov cx, [bp][Count]
  769. les di, [bp][DestOff]
  770. lds si, [bp][SourceOff]
  771. rep; movsb;
  772. pop ds; pop es; pop di; pop si; pop cx
  773. pop bp
  774. ret far 10
  775. section
  776. (*%F SameDS *)
  777. segment CORE_TEXT(CODE,28H);
  778. (*%E *)
  779. (*%T SameDS *)
  780. segment _TEXT(CODE,28H);
  781. (*%E *)
  782. public F$PushByt : SourceSeg = lframe+4; SourceOff = lframe+2; Count = lframe
  783. push bp
  784. mov bp,sp
  785. sub sp, [bp][Count]
  786. (*%F NearCall*) push [bp][4] (* return cs *) (*%E*)
  787. push [bp][2] (* return ip *)
  788. push cx; push si; push di; push es; push ds;
  789. lds si, [bp][SourceOff]
  790. mov cx, [bp][Count]
  791. mov bp, [bp] (* restore bp *)
  792. mov di, sp
  793. add di, lframe+lframe+14
  794. push ss
  795. pop es
  796. rep; movsb
  797. pop ds; pop es; pop di; pop si; pop cx
  798. ret far lframe+6
  799. section
  800. (*%F SameDS *)
  801. segment CORE_TEXT(CODE,28H);
  802. (*%E *)
  803. (*%T SameDS *)
  804. segment _TEXT(CODE,28H);
  805. (*%E *)
  806. public F$PopByt : Data = lframe+6; DestSeg = lframe+4; DestOff = lframe+2; Count = lframe
  807. push bp
  808. mov bp,sp
  809. push cx; push si; push di; push es; push ds
  810. mov cx, [bp][Count]
  811. les di, [bp][DestOff]
  812. lea si, [bp][Data]
  813. push ss; pop ds
  814. rep; movsb
  815. lea bp, [si][-lframe]
  816. pop ds; pop es; pop di; pop si; pop cx
  817. pop [bp]
  818. pop [bp][2]
  819. (*%F NearCall*) pop [bp][4] (*%E*)
  820. mov sp, bp
  821. pop bp
  822. ret far 0
  823. section
  824. (*%F SameDS *)
  825. segment CORE_TEXT(CODE,28H);
  826. (*%E *)
  827. (*%T SameDS *)
  828. segment _TEXT(CODE,28H);
  829. (*%E *)
  830. public F$SetOr : Data = lframe+2; Count = lframe
  831. push bp
  832. mov bp, sp
  833. push [bp][4]
  834. push ax; push bx; push cx; push si
  835. mov cx, [bp][Count]
  836. lea bp, [bp][Data]
  837. mov si, cx
  838. $loop:
  839. mov al, [bp]
  840. or [bp][si], al
  841. inc bp
  842. loop $loop
  843. sub bp, frame
  844. pop si; pop cx; pop bx; pop ax
  845. pop [bp][4]
  846. pop [bp]
  847. pop [bp][2]
  848. mov sp, bp
  849. pop bp
  850. ret far 0
  851. section
  852. (*%F NearCall *)
  853. segment CORE_TEXT(CODE,28H);
  854. (*%E *)
  855. (*%T NearCall *)
  856. segment _TEXT(CODE,28H);
  857. (*%E *)
  858. (*%F NearCall *)
  859. select CORE_TEXT
  860. (*%E *)
  861. (*%T NearCall *)
  862. select _TEXT
  863. (*%E *)
  864. public F$SetDif : Data = lframe+2; Count = lframe
  865. push bp
  866. mov bp, sp
  867. push [bp][4]
  868. push ax; push bx; push cx; push si
  869. mov cx, [bp][Count]
  870. lea bp, [bp][Data]
  871. mov si, cx
  872. $loop:
  873. mov al, [bp]
  874. not al
  875. and [bp][si], al
  876. inc bp
  877. loop $loop
  878. sub bp, frame
  879. pop si; pop cx; pop bx; pop ax
  880. pop [bp][4]
  881. pop [bp]
  882. pop [bp][2]
  883. mov sp, bp
  884. pop bp
  885. ret far 0
  886. section
  887. (*%F NearCall *)
  888. segment CORE_TEXT(CODE,28H);
  889. (*%E *)
  890. (*%T NearCall *)
  891. segment _TEXT(CODE,28H);
  892. (*%E *)
  893. (*%F NearCall *)
  894. select CORE_TEXT
  895. (*%E *)
  896. (*%T NearCall *)
  897. select _TEXT
  898. (*%E *)
  899. public F$SetXor : Data = lframe+2; Count = lframe
  900. push bp
  901. mov bp, sp
  902. push [bp][4]
  903. push ax; push bx; push cx; push si
  904. mov cx, [bp][Count]
  905. lea bp, [bp][Data]
  906. mov si, cx
  907. $loop:
  908. mov al, [bp]
  909. xor [bp][si], al
  910. inc bp
  911. loop $loop
  912. sub bp, frame
  913. pop si; pop cx; pop bx; pop ax
  914. pop [bp][4]
  915. pop [bp]
  916. pop [bp][2]
  917. mov sp, bp
  918. pop bp
  919. ret far 0
  920. section
  921. (*%F NearCall *)
  922. segment CORE_TEXT(CODE,28H);
  923. (*%E *)
  924. (*%T NearCall *)
  925. segment _TEXT(CODE,28H);
  926. (*%E *)
  927. (*%F NearCall *)
  928. select CORE_TEXT
  929. (*%E *)
  930. (*%T NearCall *)
  931. select _TEXT
  932. (*%E *)
  933. public F$SetAnd : Data = lframe+2; Count = lframe
  934. push bp
  935. mov bp, sp
  936. push [bp][4]
  937. push ax; push bx; push cx; push si
  938. mov cx, [bp][Count]
  939. lea bp, [bp][Data]
  940. mov si, cx
  941. $loop:
  942. mov al, [bp]
  943. and [bp][si], al
  944. inc bp
  945. loop $loop
  946. sub bp, frame
  947. pop si; pop cx; pop bx; pop ax
  948. pop [bp][4]
  949. pop [bp]
  950. pop [bp][2]
  951. mov sp, bp
  952. pop bp
  953. ret far 0
  954. section
  955. (*%F NearCall *)
  956. segment CORE_TEXT(CODE,28H);
  957. (*%E *)
  958. (*%T NearCall *)
  959. segment _TEXT(CODE,28H);
  960. (*%E *)
  961. (*%F NearCall *)
  962. select CORE_TEXT
  963. (*%E *)
  964. (*%T NearCall *)
  965. select _TEXT
  966. (*%E *)
  967. public F$DupByt : Seg = lframe+6; Off = lframe+4; Data = lframe+2; Count = lframe
  968. push bp
  969. mov bp,sp
  970. push es; push di; push cx; push ax
  971. mov al, [bp][Data]
  972. mov cx, [bp][Count]
  973. les di, [bp][Off]
  974. mov ah, al
  975. shr cx,1
  976. rep; stosw
  977. jnc $DupBytExit
  978. stosb
  979. $DupBytExit:
  980. pop ax; pop cx; pop di; pop es
  981. pop bp
  982. ret far 8
  983. section
  984. (*%F NearCall *)
  985. segment CORE_TEXT(CODE,28H);
  986. (*%E *)
  987. (*%T NearCall *)
  988. segment _TEXT(CODE,28H);
  989. (*%E *)
  990. (*%F NearCall *)
  991. select CORE_TEXT
  992. (*%E *)
  993. (*%T NearCall *)
  994. select _TEXT
  995. (*%E *)
  996. public F$EquByte : Data = lframe+2; Count = lframe
  997. (* result in flags and ax *)
  998. push bp
  999. mov bp, sp
  1000. push cx; push si; push di; push ds; push es
  1001. mov cx, [bp][Count]
  1002. lea si, [bp][Data]
  1003. mov di, si
  1004. add di, cx
  1005. mov bp, di
  1006. add bp, cx
  1007. mov ax, ss
  1008. mov es, ax
  1009. mov ds, ax
  1010. repz; cmpsb
  1011. $exit:
  1012. pop es; pop ds; pop di; pop si; pop cx (* pop was wrong order *)
  1013. lea bp, [bp][-frame] (* build return link, preserve flags!!*)
  1014. pop [bp]
  1015. pop [bp][2]
  1016. pop [bp][4]
  1017. mov sp, bp
  1018. pop bp
  1019. mov ax,0
  1020. jnz $not_equal
  1021. mov al, 1
  1022. $not_equal:
  1023. ret far 0
  1024. public F$NotEquByte : Data = lframe+2; Count = lframe
  1025. (* result in flags and ax *)
  1026. push bp
  1027. mov bp, sp
  1028. push cx; push si; push di; push ds; push es
  1029. mov cx, [bp][Count]
  1030. lea si, [bp][Data]
  1031. mov di, si
  1032. add di, cx
  1033. mov bp, di
  1034. add bp, cx
  1035. mov ax, ss
  1036. mov es, ax
  1037. mov ds, ax
  1038. repz; cmpsb
  1039. pop es; pop ds; pop di; pop si; pop cx (* pop was wrong order *)
  1040. lea bp, [bp][-lframe] (* build return link, preserve flags!!*)
  1041. pop [bp]
  1042. pop [bp][2]
  1043. (*%F NearCall*) pop [bp][4] (*%E*)
  1044. mov sp, bp
  1045. pop bp
  1046. mov ax,0
  1047. jz $equal
  1048. inc ax
  1049. $equal:
  1050. ret far 0
  1051. section
  1052. (*%F SameDS *)
  1053. segment CORE_TEXT(CODE,28H);
  1054. (*%E *)
  1055. (*%T SameDS *)
  1056. segment _TEXT(CODE,28H);
  1057. (*%E *)
  1058. extrn DOSHUGESHIFT
  1059. public F$HugeSub : p = lframe+4; q = lframe
  1060. push bp
  1061. mov bp, sp
  1062. push bx; push cx
  1063. mov ax, [bp][p]
  1064. mov dx, [bp][p][2]
  1065. mov bx, [bp][q][2]
  1066. mov cx, DOSHUGESHIFT
  1067. shr bx, cl
  1068. shr dx, cl
  1069. sub ax, [bp][q]
  1070. sbb dx, bx
  1071. pop cx; pop bx
  1072. pop bp
  1073. ret far 8
  1074. section
  1075. (*%F SameDS *)
  1076. segment CORE_TEXT(CODE,28H);
  1077. (*%E *)
  1078. (*%T SameDS *)
  1079. segment _TEXT(CODE,28H);
  1080. (*%E *)
  1081. public F$LngRol :
  1082. (*%T _DLLOVL *)
  1083. push bp
  1084. mov bp, sp
  1085. (*%E *)
  1086. push bx
  1087. and cx, 31
  1088. cmp cx, 16
  1089. jb $1
  1090. sub cx, 16
  1091. xchg ax,dx
  1092. $1:
  1093. rol ax, cl
  1094. rol dx, cl
  1095. mov bx, 1
  1096. rol bx, cl
  1097. dec bx
  1098. mov cx, ax
  1099. xor cx, dx
  1100. and cx, bx
  1101. xor ax, cx
  1102. xor dx, cx
  1103. pop bx
  1104. (*%T _DLLOVL *)
  1105. pop bp
  1106. (*%E *)
  1107. ret far 0
  1108. section
  1109. (*%F SameDS *)
  1110. segment CORE_TEXT(CODE,28H);
  1111. (*%E *)
  1112. (*%T SameDS *)
  1113. segment _TEXT(CODE,28H);
  1114. (*%E *)
  1115. public F$SetRng : Start = lframe+4; Stop = lframe+2; Count = lframe
  1116. push bp
  1117. mov bp, sp
  1118. sub sp, [bp][Count]
  1119. (*%F NearCall*) push [bp][4] (* return cs *) (*%E*)
  1120. push [bp][2] (* return ip *)
  1121. push ax; push bx; push cx; push dx; push si; push di; push es;
  1122. mov bx, [bp][Count]
  1123. mov si, [bp][Start]
  1124. mov dx, [bp][Stop]
  1125. mov bp, [bp]
  1126. mov di, sp; add di, lframe+lframe+18; push ss; pop es (* set up es:di *)
  1127. add bx, di (*End*)
  1128. mov ax, si (*Start*)
  1129. cmp ax, dx (*Stop*)
  1130. ja $lastpart
  1131. mov cx, ax
  1132. shr cx, 1; shr cx, 1; shr cx, 1
  1133. sub al, al
  1134. rep; stosb
  1135. mov cl, si (*Start*)
  1136. and cl, 7
  1137. mov al, 0FFH
  1138. shl al, cl
  1139. stosb
  1140. mov cx, dx (*Stop*)
  1141. shr cx, 1; shr cx, 1; shr cx, 1
  1142. mov ax, si (*Start*)
  1143. shr ax, 1; shr ax, 1; shr ax, 1
  1144. sub cx, ax
  1145. jz $one_byte_non_zero
  1146. dec cx
  1147. mov al, 0FFH
  1148. rep; stosb
  1149. $done_all_ones:
  1150. mov cl, 7
  1151. sub cl, dl (*Stop*)
  1152. and cl, 7
  1153. mov al, 0FFH
  1154. shr al, cl
  1155. stosb
  1156. $lastpart:
  1157. mov cx, bx (*End*)
  1158. sub cx, di
  1159. sub al,al
  1160. rep; stosb
  1161. pop es; pop di; pop si; pop dx; pop cx; pop bx; pop ax;
  1162. ret far lframe+6
  1163. $one_byte_non_zero:
  1164. mov cl, 7
  1165. sub cl, dl (*Stop*)
  1166. and cl, 7
  1167. mov al, 0FFH
  1168. shr al, cl
  1169. and es:[di][-1], al
  1170. jmp $lastpart
  1171. section
  1172. (*%F SameDS *)
  1173. segment SIG_TEXT(CODE,28H);
  1174. (* Have to use a fixed segment for this as bp is used for a parameter *)
  1175. (*%E *)
  1176. (*%T SameDS *)
  1177. segment _TEXT(CODE,28H);
  1178. (*%E *)
  1179. segment _DATA(DATA, 28H)
  1180. extrn __FatalError
  1181. extrn __stk_base
  1182. (*%F SameDS *)
  1183. select SIG_TEXT
  1184. (*%E *)
  1185. (*%T SameDS *)
  1186. select _TEXT
  1187. (*%E *)
  1188. CSVar = 2
  1189. IPVar = 0
  1190. Dgrp : dw _DATA
  1191. public F$StkChk :
  1192. push es
  1193. mov es, cs:[Dgrp]
  1194. add bp, es:[__stk_base]
  1195. pop es
  1196. jc stackError
  1197. cmp sp, bp
  1198. jb stackError
  1199. ret far 0
  1200. stackError:
  1201. mov bx, sp
  1202. mov ax, 1
  1203. push ax
  1204. push ss:[bx][IPVar]
  1205. push ss:[bx][CSVar]
  1206. call far __FatalError
  1207. section
  1208. (*%F SameDS *)
  1209. segment CORE_TEXT(CODE,28H);
  1210. (*%E *)
  1211. (*%T SameDS *)
  1212. segment _TEXT(CODE,28H);
  1213. (*%E *)
  1214. extrn __FatalError
  1215. CSVar = 12
  1216. IPVar = 10
  1217. public F$CnsStk : push ax; mov ax, 1 ; jmp F$cns
  1218. public F$CnsPtr : push ax; mov ax, 2 ; jmp F$cns
  1219. public F$CnsIdx : push ax; mov ax, 9 ; jmp F$cns
  1220. public F$CnsOvr : push ax; mov ax, 4 ; jmp F$cns
  1221. public F$CnsRng : push ax; mov ax, 5 ; jmp F$cns
  1222. public F$CnsRet : push ax; mov ax, 6 ; jmp F$cns
  1223. public F$CnsCase : push ax; mov ax, 7 ; jmp F$cns
  1224. public F$CnsDiv : push ax; mov ax, 8 ; jmp F$cns
  1225. public F$CnsPVC : push ax; mov ax, 0AH ; jmp F$cns
  1226. F$cns:
  1227. push bx
  1228. push cx
  1229. push dx
  1230. push ds
  1231. mov bx, sp
  1232. mov cx, ax
  1233. push cx
  1234. push ss:[bx][IPVar]
  1235. push ss:[bx][CSVar]
  1236. extrn CoreSig@CnsHandler
  1237. (*%F _WINDOWS *)
  1238. mov dx, seg CoreSig@CnsHandler
  1239. mov ds, dx
  1240. (*%E *)
  1241. cmp word [CoreSig@CnsHandler][2], 0
  1242. je noHandler
  1243. call far [CoreSig@CnsHandler]
  1244. or al, al
  1245. jnz retFromCns
  1246. noHandler:
  1247. push cx
  1248. push ss:[bx][IPVar]
  1249. push ss:[bx][CSVar]
  1250. call far __FatalError
  1251. retFromCns:
  1252. pop ds
  1253. pop dx
  1254. pop cx
  1255. pop bx
  1256. pop ax
  1257. ret far 0
  1258. (****************************************************************************)
  1259. (* end of handlers for far compiler generated calls *)
  1260. (****************************************************************************)
  1261. (****************************************************************************)
  1262. (* start of iopl handlers for compiler generated calls *)
  1263. (****************************************************************************)
  1264. section
  1265. segment IOPL_TEXT(CODE,28H);
  1266. public I$UnsMol : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  1267. public I$SgnMol :
  1268. (* Unsigned/signed multiplication *)
  1269. (* On overflow: modulus 2^32 wrap-around *)
  1270. push bp
  1271. mov bp,sp
  1272. mov ax,[bp][High1]
  1273. and ax,ax
  1274. jnz UnsMol2
  1275. add ax,[bp][High2]
  1276. jnz UnsMol1
  1277. mov ax,[bp][Low1]
  1278. mul word [bp][Low2]
  1279. pop bp
  1280. ret far 8
  1281. UnsMol1:
  1282. mul word [bp][Low1]
  1283. mov dx,[bp][Low1]
  1284. mov bp,[bp][Low2]
  1285. xchg bp,ax
  1286. mul dx
  1287. add dx,bp
  1288. pop bp
  1289. ret far 8
  1290. UnsMol2:
  1291. mov dx,[bp][High2]
  1292. and dx,dx
  1293. jnz UnsMol3
  1294. mul word [bp][Low2]
  1295. mov dx,[bp][Low1]
  1296. mov bp,[bp][Low2]
  1297. xchg bp,ax
  1298. mul dx
  1299. add dx,bp
  1300. pop bp
  1301. ret far 8
  1302. UnsMol3:
  1303. push cx
  1304. mul word [bp][Low2]
  1305. mov cx,ax
  1306. mov ax,[bp][High2]
  1307. mul word [bp][Low1]
  1308. add cx,ax
  1309. mov ax,[bp][Low1]
  1310. mul word [bp][Low2]
  1311. add dx,cx
  1312. pop cx
  1313. pop bp
  1314. ret far 8
  1315. section
  1316. segment IOPL_TEXT(CODE,28H);
  1317. extrn I$UnsMul
  1318. public I$SgnDiv : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  1319. (*Signed division *)
  1320. (*On overflow: result MAXINT, OF set *)
  1321. push bp
  1322. mov bp,sp
  1323. push cx
  1324. push si
  1325. xor si,si
  1326. (* DIV / 0 Test *)
  1327. mov dx,[bp][High2]
  1328. or dx,[bp][Low2]
  1329. jnz DivOK
  1330. extrn I$CnsDiv
  1331. add sp, 6
  1332. jmp I$CnsDiv
  1333. DivOK:
  1334. mov dx,[bp][High1]
  1335. and dx,dx
  1336. jge SgnDiv5
  1337. not si
  1338. neg dx
  1339. neg word [bp][Low1]
  1340. sbb dx,0
  1341. mov [bp][High1],dx
  1342. SgnDiv5:
  1343. mov dx,[bp][High2]
  1344. and dx,dx
  1345. jg SgnDiv1
  1346. jz SgnDiv6
  1347. not si
  1348. neg dx
  1349. neg word [bp][Low2]
  1350. sbb dx,0
  1351. mov [bp][High2],dx
  1352. jnz SgnDiv1
  1353. SgnDiv6:
  1354. mov cx,[bp][Low2]
  1355. jcxz SgnDiv0
  1356. mov dx,[bp][High1]
  1357. cmp dx,cx
  1358. jae SgnDivA
  1359. mov ax,[bp][Low1]
  1360. div cx
  1361. xor dx,dx
  1362. SgnDiv9:
  1363. add ax,si
  1364. adc dx,si
  1365. xor ax,si
  1366. xor dx,si
  1367. SgnDiv7:
  1368. pop si
  1369. pop cx
  1370. pop bp
  1371. ret far 8
  1372. SgnDivA:
  1373. mov ax,dx
  1374. xor dx,dx
  1375. div cx
  1376. mov cx,ax
  1377. mov ax,[bp][Low1]
  1378. div word [bp][Low2]
  1379. mov dx,cx
  1380. jmp SgnDiv9
  1381. SgnDiv1:
  1382. push bx
  1383. mov cx,dx
  1384. mov bx,[bp][Low2]
  1385. mov dx,[bp][High1]
  1386. mov ax,[bp][Low1]
  1387. push cx
  1388. push bx
  1389. SgnDiv2:
  1390. shr dx,1
  1391. rcr ax,1
  1392. shr cx,1
  1393. rcr bx,1
  1394. and cx,cx
  1395. jnz SgnDiv2
  1396. div bx
  1397. mov bx,ax
  1398. push cx
  1399. push ax
  1400. call far I$UnsMul
  1401. jo SgnDiv3
  1402. cmp dx,[bp][High1]
  1403. ja SgnDiv3
  1404. jb SgnDiv4
  1405. cmp ax,[bp][Low1]
  1406. jbe SgnDiv4
  1407. SgnDiv3:
  1408. dec bx
  1409. SgnDiv4:
  1410. mov ax,bx
  1411. xor dx,dx
  1412. pop bx
  1413. jmp SgnDiv9
  1414. SgnDiv0:
  1415. mov al,100
  1416. add al,al
  1417. mov ax,0FFFFH
  1418. mov dx,07FFFH
  1419. jmp SgnDiv7
  1420. section
  1421. segment IOPL_TEXT(CODE,28H);
  1422. extrn I$UnsMul
  1423. public I$UnsDiv : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  1424. (*Unsigned division *)
  1425. (*On overflow: result MAXCARD, OF set *)
  1426. push bp
  1427. mov bp,sp
  1428. push cx
  1429. (* DIV / 0 Test *)
  1430. mov cx,[bp][High2]
  1431. or cx,[bp][Low2]
  1432. jnz DivOK
  1433. extrn I$CnsDiv
  1434. add sp, 4
  1435. jmp I$CnsDiv
  1436. DivOK:
  1437. mov cx,[bp][High2]
  1438. and cx,cx
  1439. jnz UnsDiv1
  1440. add cx,[bp][Low2]
  1441. jz UnsDiv0
  1442. mov dx,[bp][High1]
  1443. cmp dx,cx
  1444. jae UnsDiv7 (*!!!!New special case *)
  1445. mov ax,[bp][Low1]
  1446. div cx
  1447. xor dx,dx
  1448. UnsDiv8:
  1449. and ax,ax
  1450. UnsDiv9:
  1451. pop cx
  1452. pop bp
  1453. ret far 8
  1454. UnsDiv7:
  1455. mov ax,dx
  1456. xor dx,dx
  1457. div cx
  1458. mov cx,ax
  1459. mov ax,[bp][Low1]
  1460. div word [bp][Low2]
  1461. mov dx,cx
  1462. jmp UnsDiv8
  1463. UnsDiv1:
  1464. push bx
  1465. mov dx,[bp][High1]
  1466. mov ax,[bp][Low1]
  1467. mov bx,[bp][Low2]
  1468. push cx
  1469. push bx
  1470. UnsDiv2:
  1471. shr dx,1
  1472. rcr ax,1
  1473. shr cx,1
  1474. rcr bx,1
  1475. and cx,cx
  1476. jnz UnsDiv2
  1477. div bx
  1478. mov bx,ax
  1479. push cx
  1480. push ax
  1481. call far I$UnsMul
  1482. jo UnsDiv3
  1483. cmp dx,[bp][High1]
  1484. jb UnsDiv4
  1485. ja UnsDiv3
  1486. cmp ax,[bp][Low1]
  1487. jbe UnsDiv4
  1488. UnsDiv3:
  1489. dec bx
  1490. UnsDiv4:
  1491. mov ax,bx
  1492. xor dx,dx
  1493. pop bx
  1494. jmp UnsDiv8
  1495. UnsDiv0:
  1496. mov al,100
  1497. add al,al
  1498. mov ax,0FFFFH
  1499. mov dx,ax
  1500. jmp UnsDiv9
  1501. section
  1502. segment IOPL_TEXT(CODE,28H);
  1503. extrn I$UnsMul
  1504. public I$SgnRem : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  1505. (*Signed remainder *)
  1506. (*On overflow: result 0, OF set *)
  1507. push bp
  1508. mov bp,sp
  1509. push cx
  1510. push si
  1511. (* DIV / 0 Test *)
  1512. mov dx,[bp][High2]
  1513. or dx,[bp][Low2]
  1514. jnz DivOK
  1515. extrn I$CnsDiv
  1516. add sp, 6
  1517. jmp I$CnsDiv
  1518. DivOK:
  1519. xor si,si
  1520. mov dx,[bp][High1]
  1521. and dx,dx
  1522. jge SgnRem5
  1523. not si
  1524. neg dx
  1525. neg word [bp][Low1]
  1526. sbb dx,0
  1527. mov [bp][High1],dx
  1528. SgnRem5:
  1529. mov dx,[bp][High2]
  1530. and dx,dx
  1531. jg SgnRem1
  1532. jz SgnRem6
  1533. neg dx
  1534. neg word [bp][Low2]
  1535. sbb dx,0
  1536. mov [bp][High2],dx
  1537. jnz SgnRem1
  1538. SgnRem6:
  1539. mov cx,[bp][Low2]
  1540. jcxz SgnRem0
  1541. mov ax,[bp][High1]
  1542. div cx
  1543. mov ax,[bp][Low1]
  1544. div cx
  1545. mov ax,dx
  1546. xor dx,dx
  1547. SgnRem9:
  1548. add ax,si
  1549. adc dx,si
  1550. xor ax,si
  1551. xor dx,si
  1552. SgnRem7:
  1553. pop si
  1554. pop cx
  1555. pop bp
  1556. ret far 8
  1557. SgnRem1:
  1558. push bx
  1559. mov cx,dx
  1560. mov bx,[bp][Low2]
  1561. mov dx,[bp][High1]
  1562. mov ax,[bp][Low1]
  1563. push cx
  1564. push bx
  1565. SgnRem2:
  1566. shr dx,1
  1567. rcr ax,1
  1568. shr cx,1
  1569. rcr bx,1
  1570. and cx,cx
  1571. jnz SgnRem2
  1572. div bx
  1573. push cx
  1574. push ax
  1575. call far I$UnsMul
  1576. cmp dx,[bp][High1]
  1577. ja SgnRem3
  1578. jb SgnRem4
  1579. cmp ax,[bp][Low1]
  1580. jbe SgnRem4
  1581. SgnRem3:
  1582. sub ax,[bp][Low2]
  1583. sbb dx,[bp][High2]
  1584. SgnRem4:
  1585. sub ax,[bp][Low1]
  1586. sbb dx,[bp][High1]
  1587. neg dx
  1588. neg ax
  1589. sbb dx,cx
  1590. pop bx
  1591. jmp SgnRem9
  1592. SgnRem0:
  1593. sub dx,dx
  1594. mov al,100
  1595. add al,al
  1596. mov ax,dx
  1597. jmp SgnRem7
  1598. section
  1599. segment IOPL_TEXT(CODE,28H);
  1600. extrn I$UnsMul
  1601. public I$SgnMod : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  1602. (*Signed modulus *)
  1603. (*On overflow: result 0, OF set *)
  1604. push bp
  1605. mov bp,sp
  1606. push cx
  1607. push bx
  1608. (* DIV / 0 Test *)
  1609. mov dx,[bp][High2]
  1610. or dx,[bp][Low2]
  1611. jnz DivOK
  1612. extrn I$CnsDiv
  1613. add sp, 6
  1614. jmp I$CnsDiv
  1615. DivOK:
  1616. mov dx,[bp][High1]
  1617. mov bh, dh
  1618. and dx,dx
  1619. jge SgnMod5
  1620. neg dx
  1621. neg word [bp][Low1]
  1622. sbb dx,0
  1623. mov [bp][High1],dx
  1624. SgnMod5:
  1625. mov dx,[bp][High2]
  1626. mov bl,dh
  1627. and dx,dx
  1628. jg SgnMod1
  1629. jz SgnMod6
  1630. neg dx
  1631. neg word [bp][Low2]
  1632. sbb dx,0
  1633. mov [bp][High2],dx
  1634. jnz SgnMod1
  1635. SgnMod6:
  1636. mov cx,[bp][Low2]
  1637. jcxz SgnMod0
  1638. mov ax,[bp][High1]
  1639. div cx
  1640. mov ax,[bp][Low1]
  1641. div cx
  1642. mov ax,dx
  1643. xor dx,dx
  1644. SgnMod9:
  1645. mov cx,ax
  1646. or cx,dx
  1647. jz SgnMod7
  1648. xor bh,bl
  1649. jge SgnMod10
  1650. sub ax,[bp][Low2]
  1651. sbb dx,[bp][High2]
  1652. not bl
  1653. SgnMod10:
  1654. shl bl,1
  1655. jnc SgnMod7
  1656. neg dx
  1657. neg ax
  1658. sbb dx,0
  1659. SgnMod7:
  1660. pop bx
  1661. pop cx
  1662. pop bp
  1663. ret far 8
  1664. SgnMod1:
  1665. push si
  1666. mov cx,dx
  1667. mov si,[bp][Low2]
  1668. mov dx,[bp][High1]
  1669. mov ax,[bp][Low1]
  1670. push cx
  1671. push si
  1672. SgnMod2:
  1673. shr dx,1
  1674. rcr ax,1
  1675. shr cx,1
  1676. rcr si,1
  1677. and cx,cx
  1678. jnz SgnMod2
  1679. div si
  1680. push cx
  1681. push ax
  1682. call far I$UnsMul
  1683. cmp dx,[bp][High1]
  1684. ja SgnMod3
  1685. jb SgnMod4
  1686. cmp ax,[bp][Low1]
  1687. jbe SgnMod4
  1688. SgnMod3:
  1689. sub ax,[bp][Low2]
  1690. sbb dx,[bp][High2]
  1691. SgnMod4:
  1692. sub ax,[bp][Low1]
  1693. sbb dx,[bp][High1]
  1694. neg dx
  1695. neg ax
  1696. sbb dx,cx
  1697. pop si
  1698. jmp SgnMod9
  1699. SgnMod0: (* overflow *)
  1700. sub dx,dx
  1701. mov al,100
  1702. add al,al
  1703. mov ax,dx
  1704. jmp SgnMod7
  1705. section
  1706. segment IOPL_TEXT(CODE,28H);
  1707. extrn I$UnsMul
  1708. public I$UnsRem : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  1709. (*Unsigned remainder/modulus *)
  1710. (*On overflow: result 0, OF set *)
  1711. push bp
  1712. mov bp,sp
  1713. push cx
  1714. (* DIV / 0 Test *)
  1715. mov cx,[bp][High2]
  1716. or cx,[bp][Low2]
  1717. jnz DivOK
  1718. extrn I$CnsDiv
  1719. add sp, 4
  1720. jmp I$CnsDiv
  1721. DivOK:
  1722. mov cx,[bp][High2]
  1723. and cx,cx
  1724. jnz UnsRem1
  1725. add cx,[bp][Low2]
  1726. jz UnsRem0
  1727. mov ax,[bp][High1]
  1728. xor dx,dx
  1729. div cx
  1730. mov ax,[bp][Low1]
  1731. div cx
  1732. mov ax,dx
  1733. xor dx,dx
  1734. UnsRem9:
  1735. pop cx
  1736. pop bp
  1737. ret far 8
  1738. UnsRem1:
  1739. push bx
  1740. mov dx,[bp][High1]
  1741. mov ax,[bp][Low1]
  1742. mov bx,[bp][Low2]
  1743. push cx
  1744. push bx
  1745. UnsRem2:
  1746. shr dx,1
  1747. rcr ax,1
  1748. shr cx,1
  1749. rcr bx,1
  1750. and cx,cx
  1751. jnz UnsRem2
  1752. div bx
  1753. sub ax,1
  1754. adc ax,0
  1755. push cx
  1756. push ax
  1757. call far I$UnsMul
  1758. add ax,[bp][Low2]
  1759. adc dx,[bp][High2]
  1760. jc UnsRem3
  1761. cmp dx,[bp][High1]
  1762. jb UnsRem4
  1763. ja UnsRem3
  1764. cmp ax,[bp][Low1]
  1765. jbe UnsRem4
  1766. UnsRem3:
  1767. sub ax,[bp][Low2]
  1768. sbb dx,[bp][High2]
  1769. UnsRem4:
  1770. sub ax,[bp][Low1]
  1771. sbb dx,[bp][High1]
  1772. neg dx
  1773. neg ax
  1774. sbb dx,cx
  1775. and ax,ax
  1776. pop bx
  1777. jmp UnsRem9
  1778. UnsRem0:
  1779. xor dx,dx
  1780. mov al,100
  1781. add al,al
  1782. mov ax,dx
  1783. jmp UnsRem9
  1784. section
  1785. segment IOPL_TEXT(CODE,28H);
  1786. public I$UnsMul : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  1787. (*Unsigned multiplication *)
  1788. (*On overflow: result MAXCARD, OF set *)
  1789. push bp
  1790. mov bp,sp
  1791. mov ax,[bp][High1]
  1792. and ax,ax
  1793. jnz UnsMul1
  1794. add ax,[bp][High2]
  1795. jnz UnsMul2
  1796. mov ax,[bp][Low1]
  1797. mul word [bp][Low2]
  1798. UnsMul8:
  1799. and ax,ax
  1800. UnsMul9:
  1801. pop bp
  1802. ret far 8
  1803. UnsMul1:
  1804. cmp word [bp][High2],0
  1805. jnz UnsMul0
  1806. mul word [bp][Low2]
  1807. jmp UnsMul3
  1808. UnsMul2:
  1809. mul word [bp][Low1]
  1810. UnsMul3:
  1811. jc UnsMul0
  1812. mov dx,[bp][Low1]
  1813. mov bp,[bp][Low2]
  1814. xchg ax,bp
  1815. mul dx
  1816. add dx,bp
  1817. jnc UnsMul8
  1818. UnsMul0:
  1819. mov al,100
  1820. add al,al
  1821. stc
  1822. mov ax,0FFFFH
  1823. mov dx,ax
  1824. jmp UnsMul9
  1825. section
  1826. segment IOPL_TEXT(CODE,28H);
  1827. public I$SgnMul : High1 = lframe+6; Low1 = lframe+4; High2 = lframe+2; Low2 = lframe
  1828. (*Signed multiplication *)
  1829. (*On overflow: result MAXINT, OF set *)
  1830. push bp
  1831. mov bp,sp
  1832. push si
  1833. xor si,si
  1834. mov dx,[bp][High1]
  1835. and dx,dx
  1836. jge SgnMul5
  1837. not si
  1838. neg dx
  1839. neg word [bp][Low1]
  1840. sbb dx,0
  1841. mov [bp][High1],dx
  1842. SgnMul5:
  1843. mov dx,[bp][High2]
  1844. and dx,dx
  1845. jg SgnMul6
  1846. jz SgnMul1
  1847. not si
  1848. neg dx
  1849. neg word [bp][Low2]
  1850. sbb dx,0
  1851. jz SgnMul1
  1852. SgnMul6:
  1853. cmp word [bp][High1],0
  1854. jnz SgnMul0
  1855. mov ax,dx
  1856. mul word [bp][Low1]
  1857. jmp SgnMul2
  1858. SgnMul1:
  1859. mov ax,[bp][High1]
  1860. and ax,ax
  1861. jz SgnMul2
  1862. mul word [bp][Low2]
  1863. SgnMul2:
  1864. jc SgnMul0
  1865. mov dx,[bp][Low1]
  1866. mov bp,[bp][Low2]
  1867. xchg ax,bp
  1868. mul dx
  1869. add dx,bp
  1870. jc SgnMul0
  1871. js SgnMul0
  1872. add ax,si
  1873. adc dx,si
  1874. xor ax,si
  1875. xor dx,si
  1876. SgnMul7:
  1877. pop si
  1878. pop bp
  1879. ret far 8
  1880. SgnMul0:
  1881. mov al,100
  1882. add al,al
  1883. mov ax,0FFFFH
  1884. mov dx,07FFFH
  1885. jmp SgnMul7
  1886. section
  1887. segment IOPL_TEXT(CODE,28H);
  1888. public I$LngShl :
  1889. (*%T _DLLOVL *)
  1890. push bp
  1891. mov bp, sp
  1892. (*%E *)
  1893. xor ch,ch
  1894. jcxz $lshl1
  1895. $lshl2:
  1896. shl ax,1
  1897. rcl dx,1
  1898. loop $lshl2
  1899. $lshl1:
  1900. (*%T _DLLOVL *)
  1901. pop bp
  1902. (*%E *)
  1903. ret far 0
  1904. section
  1905. segment IOPL_TEXT(CODE,28H);
  1906. public I$LngShr :
  1907. (*%T _DLLOVL *)
  1908. push bp
  1909. mov bp, sp
  1910. (*%E *)
  1911. xor ch,ch
  1912. jcxz $lshr1
  1913. $lshr2:
  1914. sar dx,1
  1915. rcr ax,1
  1916. loop $lshr2
  1917. $lshr1:
  1918. (*%T _DLLOVL *)
  1919. pop bp
  1920. (*%E *)
  1921. ret far 0
  1922. section
  1923. segment IOPL_TEXT(CODE,28H);
  1924. public I$ULngShr :
  1925. (*%T _DLLOVL *)
  1926. push bp
  1927. mov bp, sp
  1928. (*%E *)
  1929. xor ch,ch
  1930. jcxz $ulshr1
  1931. $ulshr2: shr dx,1
  1932. rcr ax,1
  1933. loop $ulshr2
  1934. $ulshr1:
  1935. (*%T _DLLOVL *)
  1936. pop bp
  1937. (*%E *)
  1938. ret far 0
  1939. section
  1940. segment IOPL_TEXT(CODE,28H);
  1941. public I$MovByt : SourceSeg =lframe+8; SourceOff = lframe+6; DestSeg = lframe+4; DestOff = lframe+2; Count = lframe
  1942. push bp
  1943. mov bp,sp
  1944. push cx; push si; push di; push es; push ds;
  1945. mov cx, [bp][Count]
  1946. les di, [bp][DestOff]
  1947. lds si, [bp][SourceOff]
  1948. rep; movsb;
  1949. pop ds; pop es; pop di; pop si; pop cx
  1950. pop bp
  1951. ret far 10
  1952. section
  1953. segment IOPL_TEXT(CODE,28H);
  1954. public I$PushByt : SourceSeg = lframe+4; SourceOff = lframe+2; Count = lframe
  1955. push bp
  1956. mov bp,sp
  1957. sub sp, [bp][Count]
  1958. (*%F NearCall*) push [bp][4] (* return cs *) (*%E*)
  1959. push [bp][2] (* return ip *)
  1960. push cx; push si; push di; push es; push ds;
  1961. lds si, [bp][SourceOff]
  1962. mov cx, [bp][Count]
  1963. mov bp, [bp] (* restore bp *)
  1964. mov di, sp
  1965. add di, lframe+lframe+14
  1966. push ss
  1967. pop es
  1968. rep; movsb
  1969. pop ds; pop es; pop di; pop si; pop cx
  1970. ret far lframe+6
  1971. section
  1972. segment IOPL_TEXT(CODE,28H);
  1973. public I$PopByt : Data = lframe+6; DestSeg = lframe+4; DestOff = lframe+2; Count = lframe
  1974. push bp
  1975. mov bp,sp
  1976. push cx; push si; push di; push es; push ds
  1977. mov cx, [bp][Count]
  1978. les di, [bp][DestOff]
  1979. lea si, [bp][Data]
  1980. push ss; pop ds
  1981. rep; movsb
  1982. lea bp, [si][-lframe]
  1983. pop ds; pop es; pop di; pop si; pop cx
  1984. pop [bp]
  1985. pop [bp][2]
  1986. (*%F NearCall*) pop [bp][4] (*%E*)
  1987. mov sp, bp
  1988. pop bp
  1989. ret far 0
  1990. section
  1991. segment IOPL_TEXT(CODE,28H);
  1992. public I$SetOr : Data = lframe+2; Count = lframe
  1993. push bp
  1994. mov bp, sp
  1995. push [bp][4]
  1996. push ax; push bx; push cx; push si
  1997. mov cx, [bp][Count]
  1998. lea bp, [bp][Data]
  1999. mov si, cx
  2000. $loop:
  2001. mov al, [bp]
  2002. or [bp][si], al
  2003. inc bp
  2004. loop $loop
  2005. sub bp, frame
  2006. pop si; pop cx; pop bx; pop ax
  2007. pop [bp][4]
  2008. pop [bp]
  2009. pop [bp][2]
  2010. mov sp, bp
  2011. pop bp
  2012. ret far 0
  2013. section
  2014. segment IOPL_TEXT(CODE,28H);
  2015. public I$SetDif : Data = lframe+2; Count = lframe
  2016. push bp
  2017. mov bp, sp
  2018. push [bp][4]
  2019. push ax; push bx; push cx; push si
  2020. mov cx, [bp][Count]
  2021. lea bp, [bp][Data]
  2022. mov si, cx
  2023. $loop:
  2024. mov al, [bp]
  2025. not al
  2026. and [bp][si], al
  2027. inc bp
  2028. loop $loop
  2029. sub bp, frame
  2030. pop si; pop cx; pop bx; pop ax
  2031. pop [bp][4]
  2032. pop [bp]
  2033. pop [bp][2]
  2034. mov sp, bp
  2035. pop bp
  2036. ret far 0
  2037. section
  2038. segment IOPL_TEXT(CODE,28H);
  2039. public I$SetXor : Data = lframe+2; Count = lframe
  2040. push bp
  2041. mov bp, sp
  2042. push [bp][4]
  2043. push ax; push bx; push cx; push si
  2044. mov cx, [bp][Count]
  2045. lea bp, [bp][Data]
  2046. mov si, cx
  2047. $loop:
  2048. mov al, [bp]
  2049. xor [bp][si], al
  2050. inc bp
  2051. loop $loop
  2052. sub bp, frame
  2053. pop si; pop cx; pop bx; pop ax
  2054. pop [bp][4]
  2055. pop [bp]
  2056. pop [bp][2]
  2057. mov sp, bp
  2058. pop bp
  2059. ret far 0
  2060. section
  2061. segment IOPL_TEXT(CODE,28H);
  2062. public I$SetAnd : Data = lframe+2; Count = lframe
  2063. push bp
  2064. mov bp, sp
  2065. push [bp][4]
  2066. push ax; push bx; push cx; push si
  2067. mov cx, [bp][Count]
  2068. lea bp, [bp][Data]
  2069. mov si, cx
  2070. $loop:
  2071. mov al, [bp]
  2072. and [bp][si], al
  2073. inc bp
  2074. loop $loop
  2075. sub bp, frame
  2076. pop si; pop cx; pop bx; pop ax
  2077. pop [bp][4]
  2078. pop [bp]
  2079. pop [bp][2]
  2080. mov sp, bp
  2081. pop bp
  2082. ret far 0
  2083. section
  2084. segment IOPL_TEXT(CODE,28H);
  2085. public I$DupByt : Seg = lframe+6; Off = lframe+4; Data = lframe+2; Count = lframe
  2086. push bp
  2087. mov bp,sp
  2088. push es; push di; push cx; push ax
  2089. mov al, [bp][Data]
  2090. mov cx, [bp][Count]
  2091. les di, [bp][Off]
  2092. mov ah, al
  2093. shr cx,1
  2094. rep; stosw
  2095. jnc $DupBytExit
  2096. stosb
  2097. $DupBytExit:
  2098. pop ax; pop cx; pop di; pop es
  2099. pop bp
  2100. ret far 8
  2101. section
  2102. segment IOPL_TEXT(CODE,28H);
  2103. public I$EquByte : Data = lframe+2; Count = lframe
  2104. (* result in flags and ax *)
  2105. push bp
  2106. mov bp, sp
  2107. push cx; push si; push di; push ds; push es
  2108. mov cx, [bp][Count]
  2109. lea si, [bp][Data]
  2110. mov di, si
  2111. add di, cx
  2112. mov bp, di
  2113. add bp, cx
  2114. mov ax, ss
  2115. mov es, ax
  2116. mov ds, ax
  2117. repz; cmpsb
  2118. $exit:
  2119. pop es; pop ds; pop di; pop si; pop cx (* pop was wrong order *)
  2120. lea bp, [bp][-frame] (* build return link, preserve flags!!*)
  2121. pop [bp]
  2122. pop [bp][2]
  2123. pop [bp][4]
  2124. mov sp, bp
  2125. pop bp
  2126. mov ax,0
  2127. jnz $not_equal
  2128. mov al, 1
  2129. $not_equal:
  2130. ret far 0
  2131. public I$NotEquByte : Data = lframe+2; Count = lframe
  2132. (* result in flags and ax *)
  2133. push bp
  2134. mov bp, sp
  2135. push cx; push si; push di; push ds; push es
  2136. mov cx, [bp][Count]
  2137. lea si, [bp][Data]
  2138. mov di, si
  2139. add di, cx
  2140. mov bp, di
  2141. add bp, cx
  2142. mov ax, ss
  2143. mov es, ax
  2144. mov ds, ax
  2145. repz; cmpsb
  2146. pop es; pop ds; pop di; pop si; pop cx (* pop was wrong order *)
  2147. lea bp, [bp][-lframe] (* build return link, preserve flags!!*)
  2148. pop [bp]
  2149. pop [bp][2]
  2150. (*%F NearCall*) pop [bp][4] (*%E*)
  2151. mov sp, bp
  2152. pop bp
  2153. mov ax,0
  2154. jz $equal
  2155. inc ax
  2156. $equal:
  2157. ret far 0
  2158. section
  2159. segment IOPL_TEXT(CODE,28H);
  2160. extrn DOSHUGESHIFT
  2161. public I$HugeSub : p = lframe+4; q = lframe
  2162. push bp
  2163. mov bp, sp
  2164. push bx; push cx
  2165. mov ax, [bp][p]
  2166. mov dx, [bp][p][2]
  2167. mov bx, [bp][q][2]
  2168. mov cx, DOSHUGESHIFT
  2169. shr bx, cl
  2170. shr dx, cl
  2171. sub ax, [bp][q]
  2172. sbb dx, bx
  2173. pop cx; pop bx
  2174. pop bp
  2175. ret far 8
  2176. section
  2177. segment IOPL_TEXT(CODE,28H);
  2178. public I$LngRol :
  2179. (*%T _DLLOVL *)
  2180. push bp
  2181. mov bp, sp
  2182. (*%E *)
  2183. push bx
  2184. and cx, 31
  2185. cmp cx, 16
  2186. jb $1
  2187. sub cx, 16
  2188. xchg ax,dx
  2189. $1:
  2190. rol ax, cl
  2191. rol dx, cl
  2192. mov bx, 1
  2193. rol bx, cl
  2194. dec bx
  2195. mov cx, ax
  2196. xor cx, dx
  2197. and cx, bx
  2198. xor ax, cx
  2199. xor dx, cx
  2200. pop bx
  2201. (*%T _DLLOVL *)
  2202. pop bp
  2203. (*%E *)
  2204. ret far 0
  2205. section
  2206. segment IOPL_TEXT(CODE,28H);
  2207. public I$SetRng : Start = lframe+4; Stop = lframe+2; Count = lframe
  2208. push bp
  2209. mov bp, sp
  2210. sub sp, [bp][Count]
  2211. (*%F NearCall*) push [bp][4] (* return cs *) (*%E*)
  2212. push [bp][2] (* return ip *)
  2213. push ax; push bx; push cx; push dx; push si; push di; push es;
  2214. mov bx, [bp][Count]
  2215. mov si, [bp][Start]
  2216. mov dx, [bp][Stop]
  2217. mov bp, [bp]
  2218. mov di, sp; add di, lframe+lframe+18; push ss; pop es (* set up es:di *)
  2219. add bx, di (*End*)
  2220. mov ax, si (*Start*)
  2221. cmp ax, dx (*Stop*)
  2222. ja $lastpart
  2223. mov cx, ax
  2224. shr cx, 1; shr cx, 1; shr cx, 1
  2225. sub al, al
  2226. rep; stosb
  2227. mov cl, si (*Start*)
  2228. and cl, 7
  2229. mov al, 0FFH
  2230. shl al, cl
  2231. stosb
  2232. mov cx, dx (*Stop*)
  2233. shr cx, 1; shr cx, 1; shr cx, 1
  2234. mov ax, si (*Start*)
  2235. shr ax, 1; shr ax, 1; shr ax, 1
  2236. sub cx, ax
  2237. jz $one_byte_non_zero
  2238. dec cx
  2239. mov al, 0FFH
  2240. rep; stosb
  2241. $done_all_ones:
  2242. mov cl, 7
  2243. sub cl, dl (*Stop*)
  2244. and cl, 7
  2245. mov al, 0FFH
  2246. shr al, cl
  2247. stosb
  2248. $lastpart:
  2249. mov cx, bx (*End*)
  2250. sub cx, di
  2251. sub al,al
  2252. rep; stosb
  2253. pop es; pop di; pop si; pop dx; pop cx; pop bx; pop ax;
  2254. ret far lframe+6
  2255. $one_byte_non_zero:
  2256. mov cl, 7
  2257. sub cl, dl (*Stop*)
  2258. and cl, 7
  2259. mov al, 0FFH
  2260. shr al, cl
  2261. and es:[di][-1], al
  2262. jmp $lastpart
  2263. section
  2264. segment IOPL_TEXT(CODE,28H);
  2265. segment _DATA(DATA, 28H)
  2266. extrn __FatalError
  2267. extrn __stk_base
  2268. select IOPL_TEXT
  2269. CSVar = 2
  2270. IPVar = 0
  2271. Dgrp : dw _DATA
  2272. public I$StkChk :
  2273. push es
  2274. mov es, cs:[Dgrp]
  2275. add bp, es:[__stk_base]
  2276. pop es
  2277. jc stackError
  2278. cmp sp, bp
  2279. jb stackError
  2280. ret far 0
  2281. stackError:
  2282. mov bx, sp
  2283. mov ax, 1
  2284. push ax
  2285. push ss:[bx][IPVar]
  2286. push ss:[bx][CSVar]
  2287. call far __FatalError
  2288. section
  2289. segment IOPL_TEXT(CODE,28H);
  2290. extrn __FatalError
  2291. CSVar = 12
  2292. IPVar = 10
  2293. public I$CnsStk : push ax; mov ax, 1 ; jmp I$cns
  2294. public I$CnsPtr : push ax; mov ax, 2 ; jmp I$cns
  2295. public I$CnsIdx : push ax; mov ax, 9 ; jmp I$cns
  2296. public I$CnsOvr : push ax; mov ax, 4 ; jmp I$cns
  2297. public I$CnsRng : push ax; mov ax, 5 ; jmp I$cns
  2298. public I$CnsRet : push ax; mov ax, 6 ; jmp I$cns
  2299. public I$CnsCase : push ax; mov ax, 7 ; jmp I$cns
  2300. public I$CnsDiv : push ax; mov ax, 8 ; jmp I$cns
  2301. I$cns:
  2302. push bx
  2303. push cx
  2304. push dx
  2305. push ds
  2306. mov bx, sp
  2307. mov cx, ax
  2308. push cx
  2309. push ss:[bx][IPVar]
  2310. push ss:[bx][CSVar]
  2311. extrn CoreSig@CnsHandler
  2312. (*%F _WINDOWS *)
  2313. mov dx, seg CoreSig@CnsHandler
  2314. mov ds, dx
  2315. (*%E *)
  2316. cmp word [CoreSig@CnsHandler], 0
  2317. je noHandler
  2318. call far [CoreSig@CnsHandler]
  2319. or al, al
  2320. jnz retFromCns
  2321. noHandler:
  2322. push cx
  2323. push ss:[bx][IPVar]
  2324. push ss:[bx][CSVar]
  2325. call far __FatalError
  2326. retFromCns:
  2327. pop ds
  2328. pop dx
  2329. pop cx
  2330. pop bx
  2331. pop ax
  2332. ret far 0
  2333. (****************************************************************************)
  2334. (* end of handlers for iopl compiler generated calls *)
  2335. (****************************************************************************)
  2336. (****************************************************************************)
  2337. (* start of near handlers for compiler generated calls *)
  2338. (****************************************************************************)
  2339. section
  2340. segment _TEXT(CODE,28H);
  2341. public N$StdRet :
  2342. pop ax
  2343. pop bx
  2344. pop cx
  2345. pop dx
  2346. pop si
  2347. pop di
  2348. mov sp, bp
  2349. pop bp
  2350. ret 0
  2351. section
  2352. segment _TEXT(CODE,28H);
  2353. public N$UnsMol : High1 = sframe+6; Low1 = sframe+4; High2 = sframe+2; Low2 = sframe
  2354. public N$SgnMol :
  2355. (* Unsigned/signed multiplication *)
  2356. (* On overflow: modulus 2^32 wrap-around *)
  2357. push bp
  2358. mov bp,sp
  2359. mov ax,[bp][High1]
  2360. and ax,ax
  2361. jnz UnsMol2
  2362. add ax,[bp][High2]
  2363. jnz UnsMol1
  2364. mov ax,[bp][Low1]
  2365. mul word [bp][Low2]
  2366. pop bp
  2367. ret near 8
  2368. UnsMol1:
  2369. mul word [bp][Low1]
  2370. mov dx,[bp][Low1]
  2371. mov bp,[bp][Low2]
  2372. xchg bp,ax
  2373. mul dx
  2374. add dx,bp
  2375. pop bp
  2376. ret near 8
  2377. UnsMol2:
  2378. mov dx,[bp][High2]
  2379. and dx,dx
  2380. jnz UnsMol3
  2381. mul word [bp][Low2]
  2382. mov dx,[bp][Low1]
  2383. mov bp,[bp][Low2]
  2384. xchg bp,ax
  2385. mul dx
  2386. add dx,bp
  2387. pop bp
  2388. ret near 8
  2389. UnsMol3:
  2390. push cx
  2391. mul word [bp][Low2]
  2392. mov cx,ax
  2393. mov ax,[bp][High2]
  2394. mul word [bp][Low1]
  2395. add cx,ax
  2396. mov ax,[bp][Low1]
  2397. mul word [bp][Low2]
  2398. add dx,cx
  2399. pop cx
  2400. pop bp
  2401. ret near 8
  2402. section
  2403. segment _TEXT(CODE,28H);
  2404. extrn N$UnsMul
  2405. public N$SgnDiv : High1 = sframe+6; Low1 = sframe+4; High2 = sframe+2; Low2 = sframe
  2406. (*Signed division *)
  2407. (*On overflow: result MAXINT, OF set *)
  2408. push bp
  2409. mov bp,sp
  2410. push cx
  2411. push si
  2412. xor si,si
  2413. (* DIV / 0 Test *)
  2414. mov dx,[bp][High2]
  2415. or dx,[bp][Low2]
  2416. jnz DivOK
  2417. extrn N$CnsDiv
  2418. add sp, 6
  2419. jmp N$CnsDiv
  2420. DivOK:
  2421. mov dx,[bp][High1]
  2422. and dx,dx
  2423. jge SgnDiv5
  2424. not si
  2425. neg dx
  2426. neg word [bp][Low1]
  2427. sbb dx,0
  2428. mov [bp][High1],dx
  2429. SgnDiv5:
  2430. mov dx,[bp][High2]
  2431. and dx,dx
  2432. jg SgnDiv1
  2433. jz SgnDiv6
  2434. not si
  2435. neg dx
  2436. neg word [bp][Low2]
  2437. sbb dx,0
  2438. mov [bp][High2],dx
  2439. jnz SgnDiv1
  2440. SgnDiv6:
  2441. mov cx,[bp][Low2]
  2442. jcxz SgnDiv0
  2443. mov dx,[bp][High1]
  2444. cmp dx,cx
  2445. jae SgnDivA
  2446. mov ax,[bp][Low1]
  2447. div cx
  2448. xor dx,dx
  2449. SgnDiv9:
  2450. add ax,si
  2451. adc dx,si
  2452. xor ax,si
  2453. xor dx,si
  2454. SgnDiv7:
  2455. pop si
  2456. pop cx
  2457. pop bp
  2458. ret near 8
  2459. SgnDivA:
  2460. mov ax,dx
  2461. xor dx,dx
  2462. div cx
  2463. mov cx,ax
  2464. mov ax,[bp][Low1]
  2465. div word [bp][Low2]
  2466. mov dx,cx
  2467. jmp SgnDiv9
  2468. SgnDiv1:
  2469. push bx
  2470. mov cx,dx
  2471. mov bx,[bp][Low2]
  2472. mov dx,[bp][High1]
  2473. mov ax,[bp][Low1]
  2474. push cx
  2475. push bx
  2476. SgnDiv2:
  2477. shr dx,1
  2478. rcr ax,1
  2479. shr cx,1
  2480. rcr bx,1
  2481. and cx,cx
  2482. jnz SgnDiv2
  2483. div bx
  2484. mov bx,ax
  2485. push cx
  2486. push ax
  2487. call near N$UnsMul
  2488. jo SgnDiv3
  2489. cmp dx,[bp][High1]
  2490. ja SgnDiv3
  2491. jb SgnDiv4
  2492. cmp ax,[bp][Low1]
  2493. jbe SgnDiv4
  2494. SgnDiv3:
  2495. dec bx
  2496. SgnDiv4:
  2497. mov ax,bx
  2498. xor dx,dx
  2499. pop bx
  2500. jmp SgnDiv9
  2501. SgnDiv0:
  2502. mov al,100
  2503. add al,al
  2504. mov ax,0FFFFH
  2505. mov dx,07FFFH
  2506. jmp SgnDiv7
  2507. section
  2508. segment _TEXT(CODE,28H);
  2509. extrn N$UnsMul
  2510. public N$UnsDiv : High1 = sframe+6; Low1 = sframe+4; High2 = sframe+2; Low2 = sframe
  2511. (*Unsigned division *)
  2512. (*On overflow: result MAXCARD, OF set *)
  2513. push bp
  2514. mov bp,sp
  2515. push cx
  2516. (* DIV / 0 Test *)
  2517. mov cx,[bp][High2]
  2518. or cx,[bp][Low2]
  2519. jnz DivOK
  2520. extrn N$CnsDiv
  2521. add sp, 4
  2522. jmp N$CnsDiv
  2523. DivOK:
  2524. mov cx,[bp][High2]
  2525. and cx,cx
  2526. jnz UnsDiv1
  2527. add cx,[bp][Low2]
  2528. jz UnsDiv0
  2529. mov dx,[bp][High1]
  2530. cmp dx,cx
  2531. jae UnsDiv7 (*!!!!New special case *)
  2532. mov ax,[bp][Low1]
  2533. div cx
  2534. xor dx,dx
  2535. UnsDiv8:
  2536. and ax,ax
  2537. UnsDiv9:
  2538. pop cx
  2539. pop bp
  2540. ret near 8
  2541. UnsDiv7:
  2542. mov ax,dx
  2543. xor dx,dx
  2544. div cx
  2545. mov cx,ax
  2546. mov ax,[bp][Low1]
  2547. div word [bp][Low2]
  2548. mov dx,cx
  2549. jmp UnsDiv8
  2550. UnsDiv1:
  2551. push bx
  2552. mov dx,[bp][High1]
  2553. mov ax,[bp][Low1]
  2554. mov bx,[bp][Low2]
  2555. push cx
  2556. push bx
  2557. UnsDiv2:
  2558. shr dx,1
  2559. rcr ax,1
  2560. shr cx,1
  2561. rcr bx,1
  2562. and cx,cx
  2563. jnz UnsDiv2
  2564. div bx
  2565. mov bx,ax
  2566. push cx
  2567. push ax
  2568. call near N$UnsMul
  2569. jo UnsDiv3
  2570. cmp dx,[bp][High1]
  2571. jb UnsDiv4
  2572. ja UnsDiv3
  2573. cmp ax,[bp][Low1]
  2574. jbe UnsDiv4
  2575. UnsDiv3:
  2576. dec bx
  2577. UnsDiv4:
  2578. mov ax,bx
  2579. xor dx,dx
  2580. pop bx
  2581. jmp UnsDiv8
  2582. UnsDiv0:
  2583. mov al,100
  2584. add al,al
  2585. mov ax,0FFFFH
  2586. mov dx,ax
  2587. jmp UnsDiv9
  2588. section
  2589. segment _TEXT(CODE,28H);
  2590. extrn N$UnsMul
  2591. public N$SgnRem : High1 = sframe+6; Low1 = sframe+4; High2 = sframe+2; Low2 = sframe
  2592. (*Signed remainder *)
  2593. (*On overflow: result 0, OF set *)
  2594. push bp
  2595. mov bp,sp
  2596. push cx
  2597. push si
  2598. (* DIV / 0 Test *)
  2599. mov dx,[bp][High2]
  2600. or dx,[bp][Low2]
  2601. jnz DivOK
  2602. extrn N$CnsDiv
  2603. add sp, 6
  2604. jmp N$CnsDiv
  2605. DivOK:
  2606. xor si,si
  2607. mov dx,[bp][High1]
  2608. and dx,dx
  2609. jge SgnRem5
  2610. not si
  2611. neg dx
  2612. neg word [bp][Low1]
  2613. sbb dx,0
  2614. mov [bp][High1],dx
  2615. SgnRem5:
  2616. mov dx,[bp][High2]
  2617. and dx,dx
  2618. jg SgnRem1
  2619. jz SgnRem6
  2620. neg dx
  2621. neg word [bp][Low2]
  2622. sbb dx,0
  2623. mov [bp][High2],dx
  2624. jnz SgnRem1
  2625. SgnRem6:
  2626. mov cx,[bp][Low2]
  2627. jcxz SgnRem0
  2628. mov ax,[bp][High1]
  2629. div cx
  2630. mov ax,[bp][Low1]
  2631. div cx
  2632. mov ax,dx
  2633. xor dx,dx
  2634. SgnRem9:
  2635. add ax,si
  2636. adc dx,si
  2637. xor ax,si
  2638. xor dx,si
  2639. SgnRem7:
  2640. pop si
  2641. pop cx
  2642. pop bp
  2643. ret near 8
  2644. SgnRem1:
  2645. push bx
  2646. mov cx,dx
  2647. mov bx,[bp][Low2]
  2648. mov dx,[bp][High1]
  2649. mov ax,[bp][Low1]
  2650. push cx
  2651. push bx
  2652. SgnRem2:
  2653. shr dx,1
  2654. rcr ax,1
  2655. shr cx,1
  2656. rcr bx,1
  2657. and cx,cx
  2658. jnz SgnRem2
  2659. div bx
  2660. push cx
  2661. push ax
  2662. call near N$UnsMul
  2663. cmp dx,[bp][High1]
  2664. ja SgnRem3
  2665. jb SgnRem4
  2666. cmp ax,[bp][Low1]
  2667. jbe SgnRem4
  2668. SgnRem3:
  2669. sub ax,[bp][Low2]
  2670. sbb dx,[bp][High2]
  2671. SgnRem4:
  2672. sub ax,[bp][Low1]
  2673. sbb dx,[bp][High1]
  2674. neg dx
  2675. neg ax
  2676. sbb dx,cx
  2677. pop bx
  2678. jmp SgnRem9
  2679. SgnRem0:
  2680. sub dx,dx
  2681. mov al,100
  2682. add al,al
  2683. mov ax,dx
  2684. jmp SgnRem7
  2685. section
  2686. segment _TEXT(CODE,28H);
  2687. extrn N$UnsMul
  2688. public N$SgnMod : High1 = sframe+6; Low1 = sframe+4; High2 = sframe+2; Low2 = sframe
  2689. (*Signed modulus *)
  2690. (*On overflow: result 0, OF set *)
  2691. push bp
  2692. mov bp,sp
  2693. push cx
  2694. push bx
  2695. (* DIV / 0 Test *)
  2696. mov dx,[bp][High2]
  2697. or dx,[bp][Low2]
  2698. jnz DivOK
  2699. extrn N$CnsDiv
  2700. add sp, 6
  2701. jmp N$CnsDiv
  2702. DivOK:
  2703. mov dx,[bp][High1]
  2704. mov bh, dh
  2705. and dx,dx
  2706. jge SgnMod5
  2707. neg dx
  2708. neg word [bp][Low1]
  2709. sbb dx,0
  2710. mov [bp][High1],dx
  2711. SgnMod5:
  2712. mov dx,[bp][High2]
  2713. mov bl,dh
  2714. and dx,dx
  2715. jg SgnMod1
  2716. jz SgnMod6
  2717. neg dx
  2718. neg word [bp][Low2]
  2719. sbb dx,0
  2720. mov [bp][High2],dx
  2721. jnz SgnMod1
  2722. SgnMod6:
  2723. mov cx,[bp][Low2]
  2724. jcxz SgnMod0
  2725. mov ax,[bp][High1]
  2726. div cx
  2727. mov ax,[bp][Low1]
  2728. div cx
  2729. mov ax,dx
  2730. xor dx,dx
  2731. SgnMod9:
  2732. mov cx,ax
  2733. or cx,dx
  2734. jz SgnMod7
  2735. xor bh,bl
  2736. jge SgnMod10
  2737. sub ax,[bp][Low2]
  2738. sbb dx,[bp][High2]
  2739. not bl
  2740. SgnMod10:
  2741. shl bl,1
  2742. jnc SgnMod7
  2743. neg dx
  2744. neg ax
  2745. sbb dx,0
  2746. SgnMod7:
  2747. pop bx
  2748. pop cx
  2749. pop bp
  2750. ret near 8
  2751. SgnMod1:
  2752. push si
  2753. mov cx,dx
  2754. mov si,[bp][Low2]
  2755. mov dx,[bp][High1]
  2756. mov ax,[bp][Low1]
  2757. push cx
  2758. push si
  2759. SgnMod2:
  2760. shr dx,1
  2761. rcr ax,1
  2762. shr cx,1
  2763. rcr si,1
  2764. and cx,cx
  2765. jnz SgnMod2
  2766. div si
  2767. push cx
  2768. push ax
  2769. call near N$UnsMul
  2770. cmp dx,[bp][High1]
  2771. ja SgnMod3
  2772. jb SgnMod4
  2773. cmp ax,[bp][Low1]
  2774. jbe SgnMod4
  2775. SgnMod3:
  2776. sub ax,[bp][Low2]
  2777. sbb dx,[bp][High2]
  2778. SgnMod4:
  2779. sub ax,[bp][Low1]
  2780. sbb dx,[bp][High1]
  2781. neg dx
  2782. neg ax
  2783. sbb dx,cx
  2784. pop si
  2785. jmp SgnMod9
  2786. SgnMod0: (* overflow *)
  2787. sub dx,dx
  2788. mov al,100
  2789. add al,al
  2790. mov ax,dx
  2791. jmp SgnMod7
  2792. section
  2793. segment _TEXT(CODE,28H);
  2794. extrn N$UnsMul
  2795. public N$UnsRem : High1 = sframe+6; Low1 = sframe+4; High2 = sframe+2; Low2 = sframe
  2796. (*Unsigned remainder/modulus *)
  2797. (*On overflow: result 0, OF set *)
  2798. push bp
  2799. mov bp,sp
  2800. push cx
  2801. (* DIV / 0 Test *)
  2802. mov cx,[bp][High2]
  2803. or cx,[bp][Low2]
  2804. jnz DivOK
  2805. extrn N$CnsDiv
  2806. add sp, 4
  2807. jmp N$CnsDiv
  2808. DivOK:
  2809. mov cx,[bp][High2]
  2810. and cx,cx
  2811. jnz UnsRem1
  2812. add cx,[bp][Low2]
  2813. jz UnsRem0
  2814. mov ax,[bp][High1]
  2815. xor dx,dx
  2816. div cx
  2817. mov ax,[bp][Low1]
  2818. div cx
  2819. mov ax,dx
  2820. xor dx,dx
  2821. UnsRem9:
  2822. pop cx
  2823. pop bp
  2824. ret near 8
  2825. UnsRem1:
  2826. push bx
  2827. mov dx,[bp][High1]
  2828. mov ax,[bp][Low1]
  2829. mov bx,[bp][Low2]
  2830. push cx
  2831. push bx
  2832. UnsRem2:
  2833. shr dx,1
  2834. rcr ax,1
  2835. shr cx,1
  2836. rcr bx,1
  2837. and cx,cx
  2838. jnz UnsRem2
  2839. div bx
  2840. sub ax,1
  2841. adc ax,0
  2842. push cx
  2843. push ax
  2844. call near N$UnsMul
  2845. add ax,[bp][Low2]
  2846. adc dx,[bp][High2]
  2847. jc UnsRem3
  2848. cmp dx,[bp][High1]
  2849. jb UnsRem4
  2850. ja UnsRem3
  2851. cmp ax,[bp][Low1]
  2852. jbe UnsRem4
  2853. UnsRem3:
  2854. sub ax,[bp][Low2]
  2855. sbb dx,[bp][High2]
  2856. UnsRem4:
  2857. sub ax,[bp][Low1]
  2858. sbb dx,[bp][High1]
  2859. neg dx
  2860. neg ax
  2861. sbb dx,cx
  2862. and ax,ax
  2863. pop bx
  2864. jmp UnsRem9
  2865. UnsRem0:
  2866. xor dx,dx
  2867. mov al,100
  2868. add al,al
  2869. mov ax,dx
  2870. jmp UnsRem9
  2871. section
  2872. segment _TEXT(CODE,28H);
  2873. public N$UnsMul : High1 = sframe+6; Low1 = sframe+4; High2 = sframe+2; Low2 = sframe
  2874. (*Unsigned multiplication *)
  2875. (*On overflow: result MAXCARD, OF set *)
  2876. push bp
  2877. mov bp,sp
  2878. mov ax,[bp][High1]
  2879. and ax,ax
  2880. jnz UnsMul1
  2881. add ax,[bp][High2]
  2882. jnz UnsMul2
  2883. mov ax,[bp][Low1]
  2884. mul word [bp][Low2]
  2885. UnsMul8:
  2886. and ax,ax
  2887. UnsMul9:
  2888. pop bp
  2889. ret near 8
  2890. UnsMul1:
  2891. cmp word [bp][High2],0
  2892. jnz UnsMul0
  2893. mul word [bp][Low2]
  2894. jmp UnsMul3
  2895. UnsMul2:
  2896. mul word [bp][Low1]
  2897. UnsMul3:
  2898. jc UnsMul0
  2899. mov dx,[bp][Low1]
  2900. mov bp,[bp][Low2]
  2901. xchg ax,bp
  2902. mul dx
  2903. add dx,bp
  2904. jnc UnsMul8
  2905. UnsMul0:
  2906. mov al,100
  2907. add al,al
  2908. stc
  2909. mov ax,0FFFFH
  2910. mov dx,ax
  2911. jmp UnsMul9
  2912. section
  2913. segment _TEXT(CODE,28H);
  2914. public N$SgnMul : High1 = sframe+6; Low1 = sframe+4; High2 = sframe+2; Low2 = sframe
  2915. (*Signed multiplication *)
  2916. (*On overflow: result MAXINT, OF set *)
  2917. push bp
  2918. mov bp,sp
  2919. push si
  2920. xor si,si
  2921. mov dx,[bp][High1]
  2922. and dx,dx
  2923. jge SgnMul5
  2924. not si
  2925. neg dx
  2926. neg word [bp][Low1]
  2927. sbb dx,0
  2928. mov [bp][High1],dx
  2929. SgnMul5:
  2930. mov dx,[bp][High2]
  2931. and dx,dx
  2932. jg SgnMul6
  2933. jz SgnMul1
  2934. not si
  2935. neg dx
  2936. neg word [bp][Low2]
  2937. sbb dx,0
  2938. jz SgnMul1
  2939. SgnMul6:
  2940. cmp word [bp][High1],0
  2941. jnz SgnMul0
  2942. mov ax,dx
  2943. mul word [bp][Low1]
  2944. jmp SgnMul2
  2945. SgnMul1:
  2946. mov ax,[bp][High1]
  2947. and ax,ax
  2948. jz SgnMul2
  2949. mul word [bp][Low2]
  2950. SgnMul2:
  2951. jc SgnMul0
  2952. mov dx,[bp][Low1]
  2953. mov bp,[bp][Low2]
  2954. xchg ax,bp
  2955. mul dx
  2956. add dx,bp
  2957. jc SgnMul0
  2958. js SgnMul0
  2959. add ax,si
  2960. adc dx,si
  2961. xor ax,si
  2962. xor dx,si
  2963. SgnMul7:
  2964. pop si
  2965. pop bp
  2966. ret near 8
  2967. SgnMul0:
  2968. mov al,100
  2969. add al,al
  2970. mov ax,0FFFFH
  2971. mov dx,07FFFH
  2972. jmp SgnMul7
  2973. section
  2974. segment _TEXT(CODE,28H);
  2975. public N$LngShl :
  2976. (*%T _DLLOVL *)
  2977. push bp
  2978. mov bp, sp
  2979. (*%E *)
  2980. xor ch,ch
  2981. jcxz $lshl1
  2982. $lshl2:
  2983. shl ax,1
  2984. rcl dx,1
  2985. loop $lshl2
  2986. $lshl1:
  2987. (*%T _DLLOVL *)
  2988. pop bp
  2989. (*%E *)
  2990. ret near 0
  2991. section
  2992. segment _TEXT(CODE,28H);
  2993. public N$LngShr :
  2994. (*%T _DLLOVL *)
  2995. push bp
  2996. mov bp, sp
  2997. (*%E *)
  2998. xor ch,ch
  2999. jcxz $lshr1
  3000. $lshr2:
  3001. sar dx,1
  3002. rcr ax,1
  3003. loop $lshr2
  3004. $lshr1:
  3005. (*%T _DLLOVL *)
  3006. pop bp
  3007. (*%E *)
  3008. ret near 0
  3009. section
  3010. segment _TEXT(CODE,28H);
  3011. public N$ULngShr :
  3012. (*%T _DLLOVL *)
  3013. push bp
  3014. mov bp, sp
  3015. (*%E *)
  3016. xor ch,ch
  3017. jcxz $ulshr1
  3018. $ulshr2: shr dx,1
  3019. rcr ax,1
  3020. loop $ulshr2
  3021. $ulshr1:
  3022. (*%T _DLLOVL *)
  3023. pop bp
  3024. (*%E *)
  3025. ret near 0
  3026. section
  3027. segment _TEXT(CODE,28H);
  3028. public N$MovByt : SourceSeg =sframe+8; SourceOff = sframe+6; DestSeg = sframe+4; DestOff = sframe+2; Count = sframe
  3029. push bp
  3030. mov bp,sp
  3031. push cx; push si; push di; push es; push ds;
  3032. mov cx, [bp][Count]
  3033. les di, [bp][DestOff]
  3034. lds si, [bp][SourceOff]
  3035. rep; movsb;
  3036. pop ds; pop es; pop di; pop si; pop cx
  3037. pop bp
  3038. ret near 10
  3039. section
  3040. segment _TEXT(CODE,28H);
  3041. public N$PushByt : SourceSeg = sframe+4; SourceOff = sframe+2; Count = sframe
  3042. push bp
  3043. mov bp,sp
  3044. sub sp, [bp][Count]
  3045. (*%F NearCall*) push [bp][4] (* return cs *) (*%E*)
  3046. push [bp][2] (* return ip *)
  3047. push cx; push si; push di; push es; push ds;
  3048. lds si, [bp][SourceOff]
  3049. mov cx, [bp][Count]
  3050. mov bp, [bp] (* restore bp *)
  3051. mov di, sp
  3052. add di, sframe+sframe+14
  3053. push ss
  3054. pop es
  3055. rep; movsb
  3056. pop ds; pop es; pop di; pop si; pop cx
  3057. ret near sframe+6
  3058. section
  3059. segment _TEXT(CODE,28H);
  3060. public N$PopByt : Data = sframe+6; DestSeg = sframe+4; DestOff = sframe+2; Count = sframe
  3061. push bp
  3062. mov bp,sp
  3063. push cx; push si; push di; push es; push ds
  3064. mov cx, [bp][Count]
  3065. les di, [bp][DestOff]
  3066. lea si, [bp][Data]
  3067. push ss; pop ds
  3068. rep; movsb
  3069. lea bp, [si][-sframe]
  3070. pop ds; pop es; pop di; pop si; pop cx
  3071. pop [bp]
  3072. pop [bp][2]
  3073. (*%F NearCall*) pop [bp][4] (*%E*)
  3074. mov sp, bp
  3075. pop bp
  3076. ret near 0
  3077. section
  3078. segment _TEXT(CODE,28H);
  3079. public N$SetOr : Data = sframe+2; Count = sframe
  3080. push bp
  3081. mov bp, sp
  3082. push ax; push bx; push cx; push si
  3083. mov cx, [bp][Count]
  3084. lea bp, [bp][Data]
  3085. mov si, cx
  3086. $loop:
  3087. mov al, [bp]
  3088. or [bp][si], al
  3089. inc bp
  3090. loop $loop
  3091. sub bp, sframe
  3092. pop si; pop cx; pop bx; pop ax
  3093. pop [bp]
  3094. pop [bp][2]
  3095. mov sp, bp
  3096. pop bp
  3097. ret near 0
  3098. section
  3099. segment _TEXT(CODE,28H);
  3100. public N$SetDif : Data = sframe+2; Count = sframe
  3101. push bp
  3102. mov bp, sp
  3103. push ax; push bx; push cx; push si
  3104. mov cx, [bp][Count]
  3105. lea bp, [bp][Data]
  3106. mov si, cx
  3107. $loop:
  3108. mov al, [bp]
  3109. not al
  3110. and [bp][si], al
  3111. inc bp
  3112. loop $loop
  3113. sub bp, sframe
  3114. pop si; pop cx; pop bx; pop ax
  3115. pop [bp]
  3116. pop [bp][2]
  3117. mov sp, bp
  3118. pop bp
  3119. ret near 0
  3120. section
  3121. segment _TEXT(CODE,28H);
  3122. public N$SetXor : Data = sframe+2; Count = sframe
  3123. push bp
  3124. mov bp, sp
  3125. push ax; push bx; push cx; push si
  3126. mov cx, [bp][Count]
  3127. lea bp, [bp][Data]
  3128. mov si, cx
  3129. $loop:
  3130. mov al, [bp]
  3131. xor [bp][si], al
  3132. inc bp
  3133. loop $loop
  3134. sub bp, sframe
  3135. pop si; pop cx; pop bx; pop ax
  3136. pop [bp]
  3137. pop [bp][2]
  3138. mov sp, bp
  3139. pop bp
  3140. ret near 0
  3141. section
  3142. segment _TEXT(CODE,28H);
  3143. public N$SetAnd : Data = sframe+2; Count = sframe
  3144. push bp
  3145. mov bp, sp
  3146. push ax; push bx; push cx; push si
  3147. mov cx, [bp][Count]
  3148. lea bp, [bp][Data]
  3149. mov si, cx
  3150. $loop:
  3151. mov al, [bp]
  3152. and [bp][si], al
  3153. inc bp
  3154. loop $loop
  3155. sub bp, sframe
  3156. pop si; pop cx; pop bx; pop ax
  3157. pop [bp]
  3158. pop [bp][2]
  3159. mov sp, bp
  3160. pop bp
  3161. ret near 0
  3162. section
  3163. segment _TEXT(CODE,28H);
  3164. public N$DupByt : Seg = sframe+6; Off = sframe+4; Data = sframe+2; Count = sframe
  3165. push bp
  3166. mov bp,sp
  3167. push es; push di; push cx; push ax
  3168. mov al, [bp][Data]
  3169. mov cx, [bp][Count]
  3170. les di, [bp][Off]
  3171. mov ah, al
  3172. shr cx,1
  3173. rep; stosw
  3174. jnc $DupBytExit
  3175. stosb
  3176. $DupBytExit:
  3177. pop ax; pop cx; pop di; pop es
  3178. pop bp
  3179. ret near 8
  3180. section
  3181. segment _TEXT(CODE,28H);
  3182. public N$EquByte : Data = sframe+2; Count = sframe
  3183. (* result in flags and ax *)
  3184. push bp
  3185. mov bp, sp
  3186. push cx; push si; push di; push ds; push es
  3187. mov cx, [bp][Count]
  3188. lea si, [bp][Data]
  3189. mov di, si
  3190. add di, cx
  3191. mov bp, di
  3192. add bp, cx
  3193. mov ax, ss
  3194. mov es, ax
  3195. mov ds, ax
  3196. repz; cmpsb
  3197. $exit:
  3198. pop es; pop ds; pop di; pop si; pop cx (* pop was wrong order *)
  3199. lea bp, [bp][-sframe] (* build return link, preserve flags!!*)
  3200. pop [bp]
  3201. pop [bp][2]
  3202. mov sp, bp
  3203. pop bp
  3204. mov ax,0
  3205. jnz $not_equal
  3206. mov al, 1
  3207. $not_equal:
  3208. ret near 0
  3209. segment _TEXT(CODE,28H);
  3210. public N$NotEquByte : Data = sframe+2; Count = sframe
  3211. (* result in flags and ax *)
  3212. push bp
  3213. mov bp, sp
  3214. push cx; push si; push di; push ds; push es
  3215. mov cx, [bp][Count]
  3216. lea si, [bp][Data]
  3217. mov di, si
  3218. add di, cx
  3219. mov bp, di
  3220. add bp, cx
  3221. mov ax, ss
  3222. mov es, ax
  3223. mov ds, ax
  3224. repz; cmpsb
  3225. pop es; pop ds; pop di; pop si; pop cx (* pop was wrong order *)
  3226. lea bp, [bp][-sframe] (* build return link, preserve flags!!*)
  3227. pop [bp]
  3228. pop [bp][2]
  3229. (*%F NearCall*) pop [bp][4] (*%E*)
  3230. mov sp, bp
  3231. pop bp
  3232. mov ax,0
  3233. jz $equal
  3234. inc ax
  3235. $equal:
  3236. ret near 0
  3237. section
  3238. segment _TEXT(CODE,28H);
  3239. extrn DOSHUGESHIFT
  3240. public N$HugeSub : p = sframe+4; q = sframe
  3241. push bp
  3242. mov bp, sp
  3243. push bx; push cx
  3244. mov ax, [bp][p]
  3245. mov dx, [bp][p][2]
  3246. mov bx, [bp][q][2]
  3247. mov cx, DOSHUGESHIFT
  3248. shr bx, cl
  3249. shr dx, cl
  3250. sub ax, [bp][q]
  3251. sbb dx, bx
  3252. pop cx; pop bx
  3253. pop bp
  3254. ret near 8
  3255. section
  3256. segment _TEXT(CODE,28H);
  3257. public N$LngRol :
  3258. (*%T _DLLOVL *)
  3259. push bp
  3260. mov bp, sp
  3261. (*%E *)
  3262. push bx
  3263. and cx, 31
  3264. cmp cx, 16
  3265. jb $1
  3266. sub cx, 16
  3267. xchg ax,dx
  3268. $1:
  3269. rol ax, cl
  3270. rol dx, cl
  3271. mov bx, 1
  3272. rol bx, cl
  3273. dec bx
  3274. mov cx, ax
  3275. xor cx, dx
  3276. and cx, bx
  3277. xor ax, cx
  3278. xor dx, cx
  3279. pop bx
  3280. (*%T _DLLOVL *)
  3281. pop bp
  3282. (*%E *)
  3283. ret near 0
  3284. section
  3285. segment _TEXT(CODE,28H);
  3286. public N$SetRng : Start = sframe+4; Stop = sframe+2; Count = sframe
  3287. push bp
  3288. mov bp, sp
  3289. sub sp, [bp][Count]
  3290. (*%F NearCall*) push [bp][4] (* return cs *) (*%E*)
  3291. push [bp][2] (* return ip *)
  3292. push ax; push bx; push cx; push dx; push si; push di; push es;
  3293. mov bx, [bp][Count]
  3294. mov si, [bp][Start]
  3295. mov dx, [bp][Stop]
  3296. mov bp, [bp]
  3297. mov di, sp; add di, sframe+sframe+18; push ss; pop es (* set up es:di *)
  3298. add bx, di (*End*)
  3299. mov ax, si (*Start*)
  3300. cmp ax, dx (*Stop*)
  3301. ja $lastpart
  3302. mov cx, ax
  3303. shr cx, 1; shr cx, 1; shr cx, 1
  3304. sub al, al
  3305. rep; stosb
  3306. mov cl, si (*Start*)
  3307. and cl, 7
  3308. mov al, 0FFH
  3309. shl al, cl
  3310. stosb
  3311. mov cx, dx (*Stop*)
  3312. shr cx, 1; shr cx, 1; shr cx, 1
  3313. mov ax, si (*Start*)
  3314. shr ax, 1; shr ax, 1; shr ax, 1
  3315. sub cx, ax
  3316. jz $one_byte_non_zero
  3317. dec cx
  3318. mov al, 0FFH
  3319. rep; stosb
  3320. $done_all_ones:
  3321. mov cl, 7
  3322. sub cl, dl (*Stop*)
  3323. and cl, 7
  3324. mov al, 0FFH
  3325. shr al, cl
  3326. stosb
  3327. $lastpart:
  3328. mov cx, bx (*End*)
  3329. sub cx, di
  3330. sub al,al
  3331. rep; stosb
  3332. pop es; pop di; pop si; pop dx; pop cx; pop bx; pop ax;
  3333. ret near sframe+6
  3334. $one_byte_non_zero:
  3335. mov cl, 7
  3336. sub cl, dl (*Stop*)
  3337. and cl, 7
  3338. mov al, 0FFH
  3339. shr al, cl
  3340. and es:[di][-1], al
  3341. jmp $lastpart
  3342. section
  3343. segment _TEXT(CODE,28H);
  3344. segment _DATA(DATA, 28H)
  3345. extrn __FatalError
  3346. extrn __stk_base
  3347. select _TEXT
  3348. CSVar = 2
  3349. IPVar = 0
  3350. Dgrp : dw _DATA
  3351. public N$StkChk :
  3352. push es
  3353. mov es, cs:[Dgrp]
  3354. add bp, es:[__stk_base]
  3355. pop es
  3356. jc stackError
  3357. cmp sp, bp
  3358. jb stackError
  3359. ret near 0
  3360. stackError:
  3361. mov bx, sp
  3362. mov ax, 1
  3363. push ax
  3364. push ss:[bx][IPVar]
  3365. push cs
  3366. call far __FatalError
  3367. section
  3368. segment _TEXT(CODE,28H);
  3369. extrn __FatalError
  3370. CSVar = 12
  3371. IPVar = 10
  3372. public N$CnsStk : push ax; mov ax, 1 ; jmp N$cns
  3373. public N$CnsPtr : push ax; mov ax, 2 ; jmp N$cns
  3374. public N$CnsIdx : push ax; mov ax, 9 ; jmp N$cns
  3375. public N$CnsOvr : push ax; mov ax, 4 ; jmp N$cns
  3376. public N$CnsRng : push ax; mov ax, 5 ; jmp N$cns
  3377. public N$CnsRet : push ax; mov ax, 6 ; jmp N$cns
  3378. public N$CnsCase : push ax; mov ax, 7 ; jmp N$cns
  3379. public N$CnsDiv : push ax; mov ax, 8 ; jmp N$cns
  3380. public N$CnsPVC : push ax; mov ax, 0AH ; jmp N$cns
  3381. N$cns:
  3382. push bx
  3383. push cx
  3384. push dx
  3385. push ds
  3386. mov bx, sp
  3387. mov cx, ax
  3388. push cx
  3389. push ss:[bx][IPVar]
  3390. push cs
  3391. extrn CoreSig@CnsHandler
  3392. (*%F _WINDOWS *)
  3393. mov dx, seg CoreSig@CnsHandler
  3394. mov ds, dx
  3395. (*%E *)
  3396. cmp word [CoreSig@CnsHandler], 0
  3397. je noHandler
  3398. call far [CoreSig@CnsHandler]
  3399. or al, al
  3400. jnz retFromCns
  3401. noHandler:
  3402. push cx
  3403. push ss:[bx][IPVar]
  3404. push cs
  3405. call far __FatalError
  3406. retFromCns:
  3407. pop ds
  3408. pop dx
  3409. pop cx
  3410. pop bx
  3411. pop ax
  3412. ret 0
  3413. (****************************************************************************)
  3414. (* end of handlers for near compiler generated calls *)
  3415. (****************************************************************************)
  3416. section
  3417. segment _TEXT(CODE,28H)
  3418. segment _DATA(DATA,28H)
  3419. extrn @ExitCode
  3420. extrn _exit
  3421. (*%T _DLLOVL *)
  3422. select _DATA
  3423. $$initm: dd __initm2
  3424. (*%E *)
  3425. select _TEXT
  3426. public __initm :
  3427. (*%T _DLLOVL *)
  3428. push bp
  3429. mov bp,sp
  3430. push [$$initm][2]
  3431. push [$$initm][0]
  3432. jmp $initm
  3433. public __initm2:
  3434. pop bp
  3435. (*%E *)
  3436. (*%F _DLLOVL *)
  3437. push cs
  3438. call $initm
  3439. (*%E *)
  3440. (*%F SameDS *)
  3441. mov ax, _DATA
  3442. mov ds, ax
  3443. (*%E *)
  3444. mov al, [@ExitCode]
  3445. sub ah, ah
  3446. (*%F RegParam *)
  3447. push ax
  3448. (*%E *)
  3449. (*%F NearCall *)
  3450. call far _exit
  3451. (*%E *)
  3452. (*%T NearCall *)
  3453. call _exit
  3454. (*%E *)
  3455. extrn _x_main
  3456. public $initm:
  3457. mov si, [_x_main][0]
  3458. (*%F near_init_data *)
  3459. mov ax, [_x_main][2]
  3460. (*%E*)
  3461. public $initm2 :
  3462. (***************************************************)
  3463. (* Call each of the module initialisation routines *)
  3464. (***************************************************)
  3465. (* The bottom of the stack segment is used for working space
  3466. A stack of 16k gives enough storage for about 1000 modules
  3467. which should be ample. There are logically three arrays;
  3468. a fixed size hash table, an array of graph nodes, and an
  3469. array of lists used for sorting. The latter two are of
  3470. dynamic size and are interleaved, and allocated together.
  3471. Once the order has been determined, the addresses are pushed
  3472. onto the stack, and a return instruction is executed.
  3473. *)
  3474. extrn __stk_base
  3475. (* hash table size *)
  3476. ht = 2 * 59 (* 59 is prime *)
  3477. (* values for state *)
  3478. active = 0
  3479. loop = 1
  3480. done = 2
  3481. (* fields for graph nodes *)
  3482. state = ht + 0
  3483. equal = ht + 1 (* valid when state = loop *)
  3484. ticket = ht + 1 (* valid when state = done *)
  3485. next = ht + 3 (* used for chaining nodes in lists *)
  3486. (* sorting array *)
  3487. list = ht + 5
  3488. link = ht + 7 (* pointer to init code *)
  3489. (*%T near_init_data*)
  3490. alloc_size = 9
  3491. (*%E*)
  3492. (*%F near_init_data*)
  3493. alloc_size = 11
  3494. (*%E*)
  3495. (*%F _WINDOWS *)
  3496. mov cx, seg __stk_base
  3497. (*%E *)
  3498. (*%T _WINDOWS *)
  3499. mov cx, ds
  3500. (*%E *)
  3501. mov es, cx
  3502. mov bx, es:[__stk_base] (* bx = allocator for nodes *)
  3503. (* set hash table to -1 *)
  3504. push es
  3505. mov dx, ax
  3506. mov cx, ht/2
  3507. mov di, bx
  3508. mov ax, ss
  3509. mov es, ax
  3510. mov ax, -1
  3511. cld
  3512. rep; stosw
  3513. mov ax, dx
  3514. pop es
  3515. mov di, bx (* di = allocator for tickets *)
  3516. (* build graph *)
  3517. push bx
  3518. push bp
  3519. call $mark
  3520. pop dx
  3521. pop cx
  3522. (* sort the nodes by inserting each node into *)
  3523. (* the list associated with its ticket *)
  3524. $init_sort:
  3525. sub bx, alloc_size
  3526. cmp bx, cx
  3527. jc $init_final
  3528. mov bp, bx
  3529. call $follow
  3530. mov bp, [bp][ticket]
  3531. mov ax, ss:[bp][list]
  3532. mov ss:[bx][next], ax
  3533. mov ss:[bp][list], bx
  3534. jmp $init_sort
  3535. (* push the address of each initialisation routine *)
  3536. (* onto the stack, in the correct order *)
  3537. $init_final_loop:
  3538. mov bp, ss:[di][list] (* list will always have at least one element *)
  3539. $init_push_list_loop:
  3540. (*%T near_init_data*)
  3541. mov bx, [bp][link]
  3542. (*%E*)
  3543. (*%F near_init_data*)
  3544. lds bx, [bp][link] (* change 10/1/90 *)
  3545. (*%E*)
  3546. (*%F near_init_code*)
  3547. cmp word [bx][2], 0
  3548. je $codeNotInMem
  3549. push [bx][2] (* change 10/1/90 *)
  3550. (*%E*)
  3551. push [bx][0] (* change 10/1/90 *)
  3552. $codeNotInMem:
  3553. mov bp, [bp][next]
  3554. cmp bp, -1
  3555. jne $init_push_list_loop
  3556. $init_final:
  3557. sub di, alloc_size
  3558. cmp di, cx
  3559. jnc $init_final_loop
  3560. public $go :
  3561. mov bp, dx
  3562. cld (* global calling convention *)
  3563. (*%F SameDS *)
  3564. mov ax, _DATA
  3565. mov ds, ax
  3566. (*%E *)
  3567. (*%T near_init_code*)
  3568. ret near 0 (* go to first module to be initialised *)
  3569. (*%E*)
  3570. (*%F near_init_code*)
  3571. ret far 0 (* go to first module to be initialised *)
  3572. (*%E*)
  3573. $follow_loop: (* local procedure for following equal chain *)
  3574. mov bp, [bp][equal]
  3575. $follow:
  3576. cmp byte [bp][state], loop
  3577. je $follow_loop
  3578. ret 0
  3579. $mark:
  3580. (* local procedure to recursively build a copy of the dependency
  3581. graph, and topologically sort it. Loops (i.e. mutually
  3582. recursive modules) are collapsed to a representative node,
  3583. obtained by following the equal chain. Non-representative
  3584. nodes in a loop have state set = loop. A representative
  3585. node has state set = done, and a ticket which gives the ordering.
  3586. in:
  3587. ax:si is pointer to some init code
  3588. ax and si are corrupted
  3589. out:
  3590. bp = index for node
  3591. in/out:
  3592. bx = allocator for nodes
  3593. di = allocator for tickets
  3594. local:
  3595. cx = least active node found
  3596. ds = copy of ax
  3597. dx = temporary (corrupted)
  3598. *)
  3599. (* find list, based on hash of ax and si *)
  3600. push ax
  3601. add ax, si
  3602. sub dx, dx
  3603. mov bp, ht/2
  3604. div bp
  3605. pop ax
  3606. shl dx, 1
  3607. add dx, es:[__stk_base]
  3608. mov bp, dx
  3609. mov bp, [bp] (* access hash table *)
  3610. (* search hash list *)
  3611. jmp $mark_search_entry
  3612. $mark_search_loop:
  3613. cmp [bp][link][0], si
  3614. (*%F near_init_data*)
  3615. jne $mark_search_next
  3616. cmp [bp][link][2], ax
  3617. (*%E*)
  3618. je $mark_ret
  3619. $mark_search_next:
  3620. mov bp, [bp][next]
  3621. $mark_search_entry:
  3622. cmp bp, -1
  3623. jne $mark_search_loop
  3624. (* link into hash table *)
  3625. mov bp, dx
  3626. mov dx, [bp] (* get old list *)
  3627. mov [bp], bx
  3628. (* allocate and initialise storage *)
  3629. mov bp, bx
  3630. add bx, alloc_size
  3631. mov byte [bp][state], active
  3632. mov [bp][link][0], si
  3633. (*%F near_init_data*)
  3634. mov [bp][link][2], ax
  3635. (*%E*)
  3636. mov word [bp][next], dx (* link in old hash list *)
  3637. mov word [bp][list], -1
  3638. (* save work registers *)
  3639. push cx
  3640. push bp
  3641. (* recursively mark imported modules *)
  3642. mov cx, bp
  3643. (*%F near_init_data*)
  3644. push ds
  3645. mov ds, ax
  3646. (*%E*)
  3647. (*%T near_init_code*)
  3648. add si, 2
  3649. (*%E*)
  3650. (*%F near_init_code*)
  3651. add si, 4
  3652. (*%E*)
  3653. $mark_adj_loop:
  3654. mov ax, ds:[si]
  3655. cmp ax, -1
  3656. je $mark_adj_exit
  3657. push si
  3658. (*%T near_init_data*)
  3659. mov si, ax
  3660. (*%E*)
  3661. (*%F near_init_data*)
  3662. mov si, ds:[si][2]
  3663. xchg ax, si
  3664. or ax, ax
  3665. jz $dataNotInMem
  3666. (*%E*)
  3667. call $mark
  3668. $dataNotInMem:
  3669. pop si
  3670. (*%T near_init_data*)
  3671. add si, 2
  3672. (*%E*)
  3673. (*%F near_init_data*)
  3674. add si, 4
  3675. (*%E*)
  3676. call $follow
  3677. cmp byte [bp][state], active
  3678. jne $mark_adj_loop
  3679. cmp bp, cx
  3680. jnb $mark_adj_loop
  3681. mov cx, bp
  3682. jmp $mark_adj_loop
  3683. $mark_adj_exit:
  3684. (*%F near_init_data*)
  3685. pop ds
  3686. (*%E*)
  3687. pop bp
  3688. cmp bp, cx
  3689. je $mark_done
  3690. mov byte [bp][state], loop
  3691. mov [bp][equal], cx
  3692. jmp $restore
  3693. $mark_done:
  3694. mov byte [bp][state], done
  3695. mov [bp][ticket], di
  3696. add di, alloc_size (* allocate a new ticket *)
  3697. $restore:
  3698. pop cx (* restore cx *)
  3699. $mark_ret:
  3700. ret 0
  3701. end
  3702.