rtl.a 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891
  1. (* Copyright (C) 1987 Jensen & Partners International *)
  2. (* Not a normal module, rtl is linked in every program, and contains
  3. the program entry point.
  4. It implements routines required by the compiler for situations
  5. where in-line code would be impractical, such as :
  6. - run time error reporting
  7. - complex set operations
  8. - saving/restoring floating point registers on procedure entry/exit
  9. - long integer multiplication,division,shifting
  10. - initialising break handler
  11. - zeroing global variables ( when (*Z+*) directive is used )
  12. *)
  13. (*
  14. The "ROM" string denotes those sections requiring modification when
  15. creating ROMmable code.
  16. *)
  17. (*ROM
  18. A number of these routines make use of the Int 8 timer tick - they are
  19. marked with an "(*INT8*)" string. If the target machine does not provide
  20. a user timer tick via Int 8, then 1) don't use any of the facilities that
  21. need it; or 2) implement an Int 8.
  22. *)
  23. (*ROM
  24. These two values are used when sending an end-of-interrupt to the interrupt
  25. controller.
  26. *)
  27. eoiport = 20H (* the port to write EOI value to *)
  28. eoivalue = 20H (* the EOI value which will be written *)
  29. module rtl
  30. segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  31. public Standard@CAP:
  32. pop ax
  33. push cs
  34. push ax
  35. public Standard$CAP:
  36. pop bx
  37. pop cx
  38. pop ax
  39. push cx
  40. push bx
  41. cmp al,97 (*'a'*)
  42. jb CapSkip
  43. cmp al,122 (*'z'*)
  44. ja CapSkip
  45. sub al,20H
  46. CapSkip:
  47. ret far 0
  48. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  49. (* entry : cx contains value to be included in set *)
  50. (* result: al = bit, di = offset in set, cx changed *)
  51. public @SetVInc:
  52. mov di,cx
  53. shr di,1
  54. shr di,1
  55. shr di,1
  56. and cl,7
  57. mov al,1
  58. rol al,cl
  59. ret 0
  60. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  61. public $SetVInc:
  62. mov di,cx
  63. shr di,1
  64. shr di,1
  65. shr di,1
  66. and cl,7
  67. mov al,1
  68. rol al,cl
  69. ret far 0
  70. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  71. (* entry : cx contains value to be included in set *)
  72. (* result: al = bit, di = offset in set *)
  73. (* cx changed *)
  74. public @SetVExc:
  75. mov di,cx
  76. shr di,1
  77. shr di,1
  78. shr di,1
  79. and cl,7
  80. mov al,0FEH
  81. rol al,cl
  82. ret 0
  83. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  84. public $SetVExc :
  85. mov di,cx
  86. shr di,1
  87. shr di,1
  88. shr di,1
  89. and cl,7
  90. mov al,0FEH
  91. rol al,cl
  92. ret far 0
  93. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  94. (* entry : bx contains first value to be included in set *)
  95. (* dx contains last value to be included in set *)
  96. (* es:di contains address of set *)
  97. (* result: cx,ax,bx undefined *)
  98. public @SetRInc :
  99. cmp bx,dx
  100. ja retret
  101. mov cl,bl
  102. and cl,7
  103. mov al,1
  104. rol al,cl
  105. mov cx,dx
  106. sub cx,bx
  107. shr bx,1
  108. shr bx,1
  109. shr bx,1
  110. or es:[di][bx],al
  111. jcxz retret
  112. loo1: rol al,1
  113. jnc skip
  114. inc bx
  115. skip: or es:[di][bx],al
  116. loop loo1
  117. retret:
  118. ret 0
  119. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  120. public $SetRInc :
  121. cmp bx,dx
  122. ja fretret
  123. mov cl,bl
  124. and cl,7
  125. mov al,1
  126. rol al,cl
  127. mov cx,dx
  128. sub cx,bx
  129. shr bx,1
  130. shr bx,1
  131. shr bx,1
  132. or es:[di][bx],al
  133. jcxz fretret
  134. floo1: rol al,1
  135. jnc fskip
  136. inc bx
  137. fskip: or es:[di][bx],al
  138. loop floo1
  139. fretret: ret far 0
  140. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  141. public @SetRIn1:
  142. sub dl,bl
  143. jc skip1
  144. inc dl
  145. mov cl,bl
  146. mov si,1
  147. rol si,cl
  148. mov cl,dl
  149. xor ch,ch
  150. incl1:
  151. or ax,si
  152. rol si,1
  153. loop incl1
  154. skip1:
  155. ret 0
  156. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  157. public $SetRIn1 :
  158. sub dl,bl
  159. jc fskip1
  160. inc dl
  161. mov cl,bl
  162. mov si,1
  163. rol si,cl
  164. mov cl,dl
  165. xor ch,ch
  166. fincl1:
  167. or ax,si
  168. rol si,1
  169. loop fincl1
  170. fskip1:
  171. ret far 0
  172. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  173. public @SetRIn4:
  174. sub dl,bl
  175. jc skip4
  176. inc dl
  177. mov cl,bl
  178. mov ax,1
  179. rol ax,cl
  180. cmp cl,15
  181. jae incl4n
  182. mov cl,dl
  183. xor ch,ch
  184. incl4:
  185. or si,ax
  186. rol ax,1
  187. jc incl4nm
  188. loop incl4
  189. skip4:
  190. ret 0
  191. incl4n:
  192. mov cl,dl
  193. xor ch,ch
  194. incl4nl:
  195. or di,ax
  196. rol ax,1
  197. incl4nm:
  198. loop incl4nl
  199. ret 0
  200. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  201. public $SetRIn4 :
  202. sub dl,bl
  203. jc fskip4
  204. inc dl
  205. mov cl,bl
  206. mov ax,1
  207. rol ax,cl
  208. cmp cl,15
  209. jae fincl4n
  210. mov cl,dl
  211. xor ch,ch
  212. fincl4:
  213. or si,ax
  214. rol ax,1
  215. jc fincl4nm
  216. loop fincl4
  217. fskip4:
  218. ret far 0
  219. fincl4n:
  220. mov cl,dl
  221. xor ch,ch
  222. fincl4nl:
  223. or di,ax
  224. rol ax,1
  225. fincl4nm:
  226. loop fincl4nl
  227. ret far 0
  228. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  229. extrn FISRQQ; extrn FJSRQQ; extrn FIWRQQ
  230. public @FltIn:
  231. pop bx
  232. push cs
  233. push bx
  234. public $FltIn:
  235. push bx (* alloc 2 bytes on the stack *)
  236. mov bx,sp
  237. fixup FISRQQ; db 9BH; fixup FJSRQQ; db 36H, 0DDH, 03FH (* fstsw ss:[bx] *)
  238. fixup FIWRQQ; db 90H, 9BH (* fwait *)
  239. pop cx (* cx = status word *)
  240. mov cl,3
  241. shr ch,cl
  242. mov cl,ch
  243. neg cx
  244. and cx,7 (* cx = number of elements on stack *)
  245. mov bx,sp
  246. (* jcxz Easy *) (* might make 8086/8088 go faster *)
  247. mov al,10
  248. mul cl (* ax = size of float registers *)
  249. sub bx,ax
  250. Easy:
  251. pop ax (* return ip *)
  252. pop dx (* return cs *)
  253. xchg bx,sp
  254. add sp,4
  255. push cx
  256. push dx
  257. push ax
  258. jcxz FloatOk
  259. SaveElement:
  260. sub bx,10
  261. fixup FISRQQ; db 9BH; fixup FJSRQQ; db 36H, 0DBH, 3FH (* fstp tenbyte ss:[bx] *)
  262. loop SaveElement
  263. FloatOk :
  264. ret far 0
  265. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  266. extrn FISRQQ; extrn FJSRQQ; extrn FIWRQQ; extrn FIDRQQ
  267. public @FltOutR :
  268. pop bx
  269. push cs
  270. push bx
  271. public $FltOutR :
  272. push bp
  273. mov bp,sp
  274. mov cx,[bp][6]
  275. jcxz $FloatOutResOk
  276. lea bx,[bp][18] (* adress of 2. element *)
  277. dec cx
  278. jcxz $PopFirst
  279. Restore:
  280. fixup FISRQQ; db 9BH; fixup FJSRQQ; db 36H, 0DBH, 2FH (* fld tenbyte ss:[bx] *)
  281. fixup FIWRQQ; db 90H, 9BH (* fwait *)
  282. add bx,10
  283. loop Restore
  284. $PopFirst: (* bx is the stack top when proc is left *)
  285. push bx
  286. lea bx,[bp][8] (* restore 1. element *)
  287. fixup FISRQQ; db 9BH; fixup FJSRQQ; db 36H, 0DBH, 2FH (* fld tenbyte ss:[bx] *)
  288. fixup FIWRQQ; db 90H, 9BH (* fwait *)
  289. mov ax,[bp][6] (* no of elements *)
  290. dec ax
  291. add ax,ax
  292. pop bx (* stack top after proc return *)
  293. pop bp
  294. pop dx (* return address *)
  295. pop cx
  296. mov sp,bx
  297. push cx
  298. push dx
  299. mov bx,ax (* swap result and 1. element *)
  300. jmp cs:[$Exchange][bx]
  301. $Exchange : dw l1, l2, l3, l4, l5, l6, l7
  302. l1: fixup FIDRQQ; db 9BH, 0D9H, 0C9H (* fxch st(1) *) ; ret far 0
  303. l2: fixup FIDRQQ; db 9BH, 0D9H, 0CAH (* fxch st(2) *) ; ret far 0
  304. l3: fixup FIDRQQ; db 9BH, 0D9H, 0CBH (* fxch st(3) *) ; ret far 0
  305. l4: fixup FIDRQQ; db 9BH, 0D9H, 0CCH (* fxch st(4) *) ; ret far 0
  306. l5: fixup FIDRQQ; db 9BH, 0D9H, 0CDH (* fxch st(5) *) ; ret far 0
  307. l6: fixup FIDRQQ; db 9BH, 0D9H, 0CEH (* fxch st(6) *) ; ret far 0
  308. l7: fixup FIDRQQ; db 9BH, 0D9H, 0CFH (* fxch st(7) *) ; ret far 0
  309. $FloatOutResOk:
  310. pop bp
  311. ret far 2
  312. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  313. extrn FISRQQ; extrn FJSRQQ; extrn FIWRQQ
  314. public @FltOut:
  315. pop bx
  316. push cs
  317. push bx
  318. public $FltOut:
  319. push bp
  320. mov bp,sp
  321. mov cx,[bp][6]
  322. jcxz FloatOutOk
  323. lea bx,ss:[bp][8]
  324. Restore2:
  325. fixup FISRQQ; db 9BH; fixup FJSRQQ; db 36H, 0DBH, 2FH (* fld tenbyte ss:[bx] *)
  326. fixup FIWRQQ; db 90H, 9BH (* fwait *)
  327. add bx,10
  328. loop Restore2
  329. pop bp
  330. pop dx
  331. pop cx
  332. mov sp,bx
  333. push cx
  334. push dx
  335. ret far 0
  336. FloatOutOk:
  337. pop bp
  338. ret far 2
  339. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  340. public @UnsMol :
  341. public @SgnMol :
  342. pop ax
  343. push cs
  344. push ax
  345. public $UnsMol : High1=12; Low1=10; High2=8; Low2=6
  346. public $SgnMol :
  347. (* Unsigned/signed multiplication *)
  348. (* On overflow: modulus 2^32 wrap-around *)
  349. push bp
  350. mov bp,sp
  351. mov ax,[bp][High1]
  352. and ax,ax
  353. jnz UnsMol2
  354. add ax,[bp][High2]
  355. jnz UnsMol1
  356. mov ax,[bp][Low1]
  357. mul word [bp][Low2]
  358. pop bp
  359. ret far 8
  360. UnsMol1:
  361. mul word [bp][Low1]
  362. mov dx,[bp][Low1]
  363. mov bp,[bp][Low2]
  364. xchg bp,ax
  365. mul dx
  366. add dx,bp
  367. pop bp
  368. ret far 8
  369. UnsMol2:
  370. mov dx,[bp][High2]
  371. and dx,dx
  372. jnz UnsMol3
  373. mul word [bp][Low2]
  374. mov dx,[bp][Low1]
  375. mov bp,[bp][Low2]
  376. xchg bp,ax
  377. mul dx
  378. add dx,bp
  379. pop bp
  380. ret far 8
  381. UnsMol3:
  382. push cx
  383. mul word [bp][Low2]
  384. mov cx,ax
  385. mov ax,[bp][High2]
  386. mul word [bp][Low1]
  387. add cx,ax
  388. mov ax,[bp][Low1]
  389. mul word [bp][Low2]
  390. add dx,cx
  391. pop cx
  392. pop bp
  393. ret far 8
  394. (*
  395. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  396. public @UnsMol :
  397. pop ax
  398. push cs
  399. push ax
  400. public $UnsMol : High1=12; Low1=10; High2=8; Low2=6
  401. (* Unsigned multiplication *)
  402. (* On overflow: modulus 2^32 wrap-around *)
  403. push bp
  404. mov bp,sp
  405. push bx
  406. mov ax,[bp][Low1]
  407. mul word [bp][High2]
  408. mov bx,ax
  409. mov ax,[bp][Low2]
  410. mul word [bp][High1]
  411. add bx,ax
  412. mov ax,[bp][Low1]
  413. mul word [bp][Low2]
  414. add dx,bx
  415. pop bx
  416. pop bp
  417. ret far 8
  418. *)
  419. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  420. extrn $UnsMul
  421. public @SgnDiv: High1=12; Low1=10; High2=8; Low2=6
  422. pop ax
  423. push cs
  424. push ax
  425. public $SgnDiv:
  426. (*Signed division *)
  427. (*On overflow: result MAXINT, OF set *)
  428. push bp
  429. mov bp,sp
  430. push cx
  431. push si
  432. xor si,si
  433. mov dx,[bp][High1]
  434. and dx,dx
  435. jge SgnDiv5
  436. not si
  437. neg dx
  438. neg word [bp][Low1]
  439. sbb dx,0
  440. mov [bp][High1],dx
  441. SgnDiv5:
  442. mov dx,[bp][High2]
  443. and dx,dx
  444. jg SgnDiv1
  445. jz SgnDiv6
  446. not si
  447. neg dx
  448. neg word [bp][Low2]
  449. sbb dx,0
  450. mov [bp][High2],dx
  451. jnz SgnDiv1
  452. SgnDiv6:
  453. mov cx,[bp][Low2]
  454. jcxz SgnDiv0
  455. mov dx,[bp][High1]
  456. cmp dx,cx
  457. jae SgnDivA
  458. mov ax,[bp][Low1]
  459. div cx
  460. xor dx,dx
  461. SgnDiv9:
  462. add ax,si
  463. adc dx,si
  464. xor ax,si
  465. xor dx,si
  466. SgnDiv7:
  467. pop si
  468. pop cx
  469. pop bp
  470. ret far 8
  471. SgnDivA:
  472. mov ax,dx
  473. xor dx,dx
  474. div cx
  475. mov cx,ax
  476. mov ax,[bp][Low1]
  477. div word [bp][Low2]
  478. mov dx,cx
  479. jmp SgnDiv9
  480. SgnDiv1:
  481. push bx
  482. mov cx,dx
  483. mov bx,[bp][Low2]
  484. mov dx,[bp][High1]
  485. mov ax,[bp][Low1]
  486. push cx
  487. push bx
  488. SgnDiv2:
  489. shr dx,1
  490. rcr ax,1
  491. shr cx,1
  492. rcr bx,1
  493. and cx,cx
  494. jnz SgnDiv2
  495. div bx
  496. mov bx,ax
  497. push cx
  498. push ax
  499. call far $UnsMul
  500. jo SgnDiv3
  501. cmp dx,[bp][High1]
  502. ja SgnDiv3
  503. jb SgnDiv4
  504. cmp ax,[bp][Low1]
  505. jbe SgnDiv4
  506. SgnDiv3:
  507. dec bx
  508. SgnDiv4:
  509. mov ax,bx
  510. xor dx,dx
  511. pop bx
  512. jmp SgnDiv9
  513. SgnDiv0:
  514. mov al,100
  515. add al,al
  516. mov ax,0FFFFH
  517. mov dx,07FFFH
  518. jmp SgnDiv7
  519. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  520. extrn $UnsMul
  521. public @UnsDiv:
  522. pop ax
  523. push cs
  524. push ax
  525. public $UnsDiv: High1=12; Low1=10; High2=8; Low2=6
  526. (*Unsigned division *)
  527. (*On overflow: result MAXCARD, OF set *)
  528. push bp
  529. mov bp,sp
  530. push cx
  531. mov cx,[bp][High2]
  532. and cx,cx
  533. jnz UnsDiv1
  534. add cx,[bp][Low2]
  535. jz UnsDiv0
  536. mov dx,[bp][High1]
  537. cmp dx,cx
  538. jae UnsDiv7 (*!!!!New special case *)
  539. mov ax,[bp][Low1]
  540. div cx
  541. xor dx,dx
  542. UnsDiv8:
  543. and ax,ax
  544. UnsDiv9:
  545. pop cx
  546. pop bp
  547. ret far 8
  548. UnsDiv7:
  549. mov ax,dx
  550. xor dx,dx
  551. div cx
  552. mov cx,ax
  553. mov ax,[bp][Low1]
  554. div word [bp][Low2]
  555. mov dx,cx
  556. jmp UnsDiv8
  557. UnsDiv1:
  558. push bx
  559. mov dx,[bp][High1]
  560. mov ax,[bp][Low1]
  561. mov bx,[bp][Low2]
  562. push cx
  563. push bx
  564. UnsDiv2:
  565. shr dx,1
  566. rcr ax,1
  567. shr cx,1
  568. rcr bx,1
  569. and cx,cx
  570. jnz UnsDiv2
  571. div bx
  572. mov bx,ax
  573. push cx
  574. push ax
  575. call far $UnsMul
  576. jo UnsDiv3
  577. cmp dx,[bp][High1]
  578. jb UnsDiv4
  579. ja UnsDiv3
  580. cmp ax,[bp][Low1]
  581. jbe UnsDiv4
  582. UnsDiv3:
  583. dec bx
  584. UnsDiv4:
  585. mov ax,bx
  586. xor dx,dx
  587. pop bx
  588. jmp UnsDiv8
  589. UnsDiv0:
  590. mov al,100
  591. add al,al
  592. mov ax,0FFFFH
  593. mov dx,ax
  594. jmp UnsDiv9
  595. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  596. extrn $UnsMul
  597. public @SgnRem:
  598. pop ax
  599. push cs
  600. push ax
  601. public $SgnRem: High1=12; Low1=10; High2=8; Low2=6
  602. (*Signed remainder *)
  603. (*On overflow: result 0, OF set *)
  604. push bp
  605. mov bp,sp
  606. push cx
  607. push si
  608. xor si,si
  609. mov dx,[bp][High1]
  610. and dx,dx
  611. jge SgnRem5
  612. not si
  613. neg dx
  614. neg word [bp][Low1]
  615. sbb dx,0
  616. mov [bp][High1],dx
  617. SgnRem5:
  618. mov dx,[bp][High2]
  619. and dx,dx
  620. jg SgnRem1
  621. jz SgnRem6
  622. neg dx
  623. neg word [bp][Low2]
  624. sbb dx,0
  625. mov [bp][High2],dx
  626. jnz SgnRem1
  627. SgnRem6:
  628. mov cx,[bp][Low2]
  629. jcxz SgnRem0
  630. mov ax,[bp][High1]
  631. div cx
  632. mov ax,[bp][Low1]
  633. div cx
  634. mov ax,dx
  635. xor dx,dx
  636. SgnRem9:
  637. add ax,si
  638. adc dx,si
  639. xor ax,si
  640. xor dx,si
  641. SgnRem7:
  642. pop si
  643. pop cx
  644. pop bp
  645. ret far 8
  646. SgnRem1:
  647. push bx
  648. mov cx,dx
  649. mov bx,[bp][Low2]
  650. mov dx,[bp][High1]
  651. mov ax,[bp][Low1]
  652. push cx
  653. push bx
  654. SgnRem2:
  655. shr dx,1
  656. rcr ax,1
  657. shr cx,1
  658. rcr bx,1
  659. and cx,cx
  660. jnz SgnRem2
  661. div bx
  662. push cx
  663. push ax
  664. call far $UnsMul
  665. cmp dx,[bp][High1]
  666. ja SgnRem3
  667. jb SgnRem4
  668. cmp ax,[bp][Low1]
  669. jbe SgnRem4
  670. SgnRem3:
  671. sub ax,[bp][Low2]
  672. sbb dx,[bp][High2]
  673. SgnRem4:
  674. sub ax,[bp][Low1]
  675. sbb dx,[bp][High1]
  676. neg dx
  677. neg ax
  678. sbb dx,cx
  679. pop bx
  680. jmp SgnRem9
  681. SgnRem0:
  682. mov al,100
  683. add al,al
  684. mov ax,0
  685. mov dx,ax
  686. jmp SgnRem7
  687. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  688. extrn $UnsMul
  689. public @UnsRem:
  690. pop ax
  691. push cs
  692. push ax
  693. public $UnsRem: High1=12; Low1=10; High2=8; Low2=6
  694. (*Unsigned remainder/modulus *)
  695. (*On overflow: result 0, OF set *)
  696. push bp
  697. mov bp,sp
  698. push cx
  699. mov cx,[bp][High2]
  700. and cx,cx
  701. jnz UnsRem1
  702. add cx,[bp][Low2]
  703. jz UnsRem0
  704. mov ax,[bp][High1]
  705. xor dx,dx
  706. div cx
  707. mov ax,[bp][Low1]
  708. div cx
  709. mov ax,dx
  710. xor dx,dx
  711. UnsRem9:
  712. pop cx
  713. pop bp
  714. ret far 8
  715. UnsRem1:
  716. push bx
  717. mov dx,[bp][High1]
  718. mov ax,[bp][Low1]
  719. mov bx,[bp][Low2]
  720. push cx
  721. push bx
  722. UnsRem2:
  723. shr dx,1
  724. rcr ax,1
  725. shr cx,1
  726. rcr bx,1
  727. and cx,cx
  728. jnz UnsRem2
  729. div bx
  730. sub ax,1
  731. adc ax,0
  732. push cx
  733. push ax
  734. call far $UnsMul
  735. add ax,[bp][Low2]
  736. adc dx,[bp][High2]
  737. jc UnsRem3
  738. cmp dx,[bp][High1]
  739. jb UnsRem4
  740. ja UnsRem3
  741. cmp ax,[bp][Low1]
  742. jbe UnsRem4
  743. UnsRem3:
  744. sub ax,[bp][Low2]
  745. sbb dx,[bp][High2]
  746. UnsRem4:
  747. sub ax,[bp][Low1]
  748. sbb dx,[bp][High1]
  749. neg dx
  750. neg ax
  751. sbb dx,cx
  752. and ax,ax
  753. pop bx
  754. jmp UnsRem9
  755. UnsRem0:
  756. xor dx,dx
  757. mov al,100
  758. add al,al
  759. mov ax,dx
  760. jmp UnsRem9
  761. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  762. public @UnsMul:
  763. pop ax
  764. push cs
  765. push ax
  766. public $UnsMul: High1=12; Low1=10; High2=8; Low2=6
  767. (*Unsigned multiplication *)
  768. (*On overflow: result MAXCARD, OF set *)
  769. push bp
  770. mov bp,sp
  771. mov ax,[bp][High1]
  772. and ax,ax
  773. jnz UnsMul1
  774. add ax,[bp][High2]
  775. jnz UnsMul2
  776. mov ax,[bp][Low1]
  777. mul word [bp][Low2]
  778. UnsMul8:
  779. and ax,ax
  780. UnsMul9:
  781. pop bp
  782. ret far 8
  783. UnsMul1:
  784. cmp word [bp][High2],0
  785. jnz UnsMul0
  786. mul word [bp][Low2]
  787. jmp UnsMul3
  788. UnsMul2:
  789. mul word [bp][Low1]
  790. UnsMul3:
  791. jc UnsMul0
  792. mov dx,[bp][Low1]
  793. mov bp,[bp][Low2]
  794. xchg ax,bp
  795. mul dx
  796. add dx,bp
  797. jnc UnsMul8
  798. UnsMul0:
  799. mov al,100
  800. add al,al
  801. mov ax,0FFFFH
  802. mov dx,ax
  803. jmp UnsMul9
  804. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  805. public @SgnMul:
  806. pop ax
  807. push cs
  808. push ax
  809. public $SgnMul: High1=12; Low1=10; High2=8; Low2=6
  810. (*Signed multiplication *)
  811. (*On overflow: result MAXINT, OF set *)
  812. push bp
  813. mov bp,sp
  814. push si
  815. xor si,si
  816. mov dx,[bp][High1]
  817. and dx,dx
  818. jge SgnMul5
  819. not si
  820. neg dx
  821. neg word [bp][Low1]
  822. sbb dx,0
  823. mov [bp][High1],dx
  824. SgnMul5:
  825. mov dx,[bp][High2]
  826. and dx,dx
  827. jg SgnMul6
  828. jz SgnMul1
  829. not si
  830. neg dx
  831. neg word [bp][Low2]
  832. sbb dx,0
  833. jz SgnMul1
  834. SgnMul6:
  835. cmp word [bp][High1],0
  836. jnz SgnMul0
  837. mov ax,dx
  838. mul word [bp][Low1]
  839. jmp SgnMul2
  840. SgnMul1:
  841. mov ax,[bp][High1]
  842. and ax,ax
  843. jz SgnMul2
  844. mul word [bp][Low2]
  845. SgnMul2:
  846. jc SgnMul0
  847. mov dx,[bp][Low1]
  848. mov bp,[bp][Low2]
  849. xchg ax,bp
  850. mul dx
  851. add dx,bp
  852. jc SgnMul0
  853. js SgnMul0
  854. add ax,si
  855. adc dx,si
  856. xor ax,si
  857. xor dx,si
  858. SgnMul7:
  859. pop si
  860. pop bp
  861. ret far 8
  862. SgnMul0:
  863. mov al,100
  864. add al,al
  865. mov ax,0FFFFH
  866. mov dx,07FFFH
  867. jmp SgnMul7
  868. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  869. public @LngShl :
  870. xor ch,ch
  871. jcxz @lshl1
  872. @lshl2:
  873. shl ax,1
  874. rcl dx,1
  875. loop @lshl2
  876. @lshl1:
  877. ret 0
  878. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  879. public $LngShl :
  880. xor ch,ch
  881. jcxz $lshl1
  882. $lshl2:
  883. shl ax,1
  884. rcl dx,1
  885. loop $lshl2
  886. $lshl1:
  887. ret far 0
  888. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  889. public @LngShr :
  890. xor ch,ch
  891. jcxz @lshr1
  892. @lshr2:
  893. sar dx,1
  894. rcr ax,1
  895. loop @lshr2
  896. @lshr1:
  897. ret 0
  898. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  899. public $LngShr :
  900. xor ch,ch
  901. jcxz $lshr1
  902. $lshr2:
  903. sar dx,1
  904. rcr ax,1
  905. loop $lshr2
  906. $lshr1:
  907. ret far 0
  908. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  909. public @ULngShr :
  910. xor ch,ch
  911. jcxz @ulshr1
  912. @ulshr2:
  913. shr dx,1
  914. rcr ax,1
  915. loop @ulshr2
  916. @ulshr1:
  917. ret 0
  918. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  919. public $ULngShr :
  920. xor ch,ch
  921. jcxz $ulshr1
  922. $ulshr2: shr dx,1
  923. rcr ax,1
  924. loop $ulshr2
  925. $ulshr1: ret far 0
  926. (* Some AsmLib routines are defined here because they are required
  927. for floating point run time support, and asmlib.obj may not
  928. be included in the link *)
  929. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  930. extrn @D_DATA
  931. extrn standard@haltChain
  932. public AsmLib$Terminate : a_ptrH=12; a_ptrL=10; c_ptrH=8; c_ptrL=6
  933. push bp; mov bp,sp
  934. push ds
  935. pushf
  936. cli
  937. mov ax,[bp][a_ptrL]
  938. mov ds,cs:[@D_DATA]
  939. xchg ax,[standard@haltChain]
  940. mov dx,[bp][a_ptrH]
  941. xchg dx,[standard@haltChain][2]
  942. lds bx,[bp][c_ptrL]
  943. mov ds:[bx],ax
  944. mov ds:[bx][2],dx
  945. popf
  946. pop ds
  947. pop bp; ret far 8
  948. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  949. extrn @D_DATA
  950. extrn @Save8087
  951. public AsmLib$Disable8087ContextSave :
  952. push ds
  953. mov ds, cs:[@D_DATA]
  954. mov byte [@Save8087],0
  955. pop ds
  956. ret far 0
  957. public AsmLib$Enable8087ContextSave :
  958. push ds
  959. mov ds, cs:[@D_DATA]
  960. mov byte [@Save8087],1
  961. pop ds
  962. ret far 0
  963. (* the rest of rtl is highly system dependent *)
  964. section ; segment C_CODE(CODE,28H); group G_CODE(C_CODE); select C_CODE
  965. extrn @PrtAddrAbort; extrn msg99;
  966. public Standard$NULLPROC:
  967. public Standard@NULLPROC:
  968. push bp
  969. mov dx,msg99
  970. mov bp,sp
  971. jmp @PrtAddrAbort
  972. section ;
  973. segment D_DATA(M_DATA,28H);
  974. segment C_CODE(CODE,28H); group G_CODE(C_CODE);
  975. select D_DATA
  976. public @IntIDTable :
  977. ID0 : (* db 0,0; dw imsg0, Trap0, 0,0 *) org 10
  978. ID4 : (* db 4,0; dw 0, Int4, 0,0 *) org 10
  979. (* removed due to problems with some 286 compatibles
  980. ID5 : (* db 5,0; dw imsg5, Trap5, 0,0 *) org 10
  981. ID6 : (* db 6,0; dw imsg6, Trap6, 0,0 *) org 10
  982. ID0D: (* db 0DH,0; dw imsg0D,Trap0D, 0,0 *) org 10
  983. *)
  984. ID8 : (* db 8,0; dw 0, Trap8, 0,0 *) org 10
  985. ID1B: (* db 1BH,0; dw 0, Trap1B, 0,0 *) org 10
  986. ID23: (* db 23H,0; dw 0, Trap23, 0,0 *) org 10
  987. ID60: (* db 60H,0; dw 0, Int60, 0,0 *) org 10
  988. ID61: (* db 61H,0; dw 0, Int60, 0,0 *) org 10
  989. select C_CODE
  990. public @IntIDSrc :
  991. (* ID0 : *) db 0,0; dw imsg0, Trap0, 0,0
  992. (* ID4 : *) db 4,0; dw 0, Int4, 0,0
  993. (* removed due to problems with some 286 compatibles
  994. (* ID5 : *) db 5,0; dw imsg5, Trap5, 0,0
  995. (* ID6 : *) db 6,0; dw imsg6, Trap6, 0,0
  996. (* ID0D: *) db 0DH,0; dw imsg0D,Trap0D, 0,0
  997. *)
  998. (* ID8 : *) db 8,0; dw 0, Trap8, 0,0
  999. (* ID1B: *) db 1BH,0; dw 0, Trap1B, 0,0
  1000. (* ID23: *) db 23H,0; dw 0, Trap23, 0,0
  1001. (* ID60: *) db 60H,0; dw 0, Int60, 0,0
  1002. (* ID61: *) db 61H,0; dw 0, Int60, 0,0
  1003. public @IntIDStop :
  1004. (* Messages *)
  1005. chstr : db 'ENVREH' (* enviroment runtime error handler *)
  1006. m90 : db '] Arithmetic overflow $'
  1007. m91 : db '] Stack Overflow$'
  1008. m92 : db '] Subrange Value Out Of Range$'
  1009. m93 : db '] Enumeration Value Out Of Range$'
  1010. m94 : db '] Dereference of Nil pointer $'
  1011. m95 : db '] Index Out Of Range$'
  1012. m97 : db '] No return in function$'
  1013. imsg0 : db '] Divide by zero$'
  1014. public msg99 : db '] Attempt to call NULLPROC $'
  1015. (* removed due to problems with some 286 compatibles
  1016. imsg5 : db '] Interrupt 5 : bounds exception$'
  1017. imsg6 : db '] Interrupt 6 : invalid opcode$'
  1018. imsg0D: db '] Interrupt 13 : segment overrun$'
  1019. *)
  1020. msg8 : db '] User Break $'
  1021. IrptNo = 0
  1022. IrptLoaded = 1
  1023. IrptMsg = 2
  1024. IrptHandlerIP = 4
  1025. IrptChainIP = 6
  1026. IrptChainCS = 8
  1027. (* removed due to problems with some 286 compatibles
  1028. LongJump: db 0EAH (* jmp *)
  1029. LongJumpIP: dw 0
  1030. LongJumpCS: dw 0
  1031. *)
  1032. extrn @D_DATA
  1033. extrn @InProgramFlag
  1034. extrn @StopProgramFlag
  1035. SetIrpt :
  1036. (* IN [@D_DATA]:SI = Irpt Def *)
  1037. push ax
  1038. push bx
  1039. push dx
  1040. push ds
  1041. push es
  1042. mov ds, cs:[@D_DATA]
  1043. mov al,1
  1044. xchg al,[si][IrptLoaded]
  1045. or al,al
  1046. jne $AlreadySet
  1047. mov al,[si][IrptNo]
  1048. mov ah,35H (* get vector *)
  1049. int 21H
  1050. mov [si][IrptChainIP],bx
  1051. mov [si][IrptChainCS],es
  1052. mov al,[si][IrptNo]
  1053. mov dx,[si][IrptHandlerIP]
  1054. push cs
  1055. pop ds
  1056. mov ah,25H
  1057. int 21H
  1058. $AlreadySet:
  1059. pop es
  1060. pop ds
  1061. pop dx
  1062. pop bx
  1063. pop ax
  1064. ret near 0
  1065. ResetIrpt :
  1066. (* IN [@D_DATA]:SI = Irpt Def *)
  1067. push ax
  1068. push dx
  1069. push ds
  1070. mov ds, cs:[@D_DATA]
  1071. sub al,al
  1072. xchg al,[si][IrptLoaded]
  1073. or al,al
  1074. jz $AlreadyCleared
  1075. mov al,[si][IrptNo]
  1076. mov dx,[si][IrptChainIP]
  1077. mov ds,[si][IrptChainCS]
  1078. mov ah,25H (* set vector *)
  1079. int 21H
  1080. $AlreadyCleared:
  1081. pop ds
  1082. pop dx
  1083. pop ax
  1084. ret near 0
  1085. public @Int4Init :
  1086. push si
  1087. push di
  1088. push ds
  1089. push es
  1090. mov si,ID60
  1091. call SetIrpt
  1092. mov si,ID61
  1093. call SetIrpt
  1094. mov si,ID4
  1095. call SetIrpt
  1096. mov ds, cs:[@D_DATA]
  1097. les di,[ID4][IrptChainIP]
  1098. lea di,[di][5]
  1099. push cs
  1100. pop ds
  1101. mov si, chstr
  1102. mov cx,3
  1103. repe
  1104. cmpsw
  1105. jne ret4
  1106. (* Enviroment has set up Int 4 so remove trap *)
  1107. mov si,ID4
  1108. call ResetIrpt
  1109. mov ax, @Abort
  1110. int 4H (* Initialize error handler *)
  1111. db 9FH
  1112. ret4:
  1113. pop es
  1114. pop ds
  1115. pop di
  1116. pop si
  1117. ret near 0
  1118. extrn @ErrorCode
  1119. extrn @ChainVector
  1120. extrn standard@haltChain
  1121. public @Abort:
  1122. mov ds, cs:[@D_DATA]
  1123. mov byte [@ErrorCode], 1
  1124. public Standard$HALT:
  1125. public Standard@HALT:
  1126. mov ds, cs:[@D_DATA]
  1127. push [standard@haltChain][2]
  1128. push [standard@haltChain][0]
  1129. mov word [standard@haltChain][0],here
  1130. mov [standard@haltChain][2],cs
  1131. ret far 0 (* ie jump to termination procedures *)
  1132. here:
  1133. call @ResetBreakInterrupt
  1134. call @ResetProcessorTraps
  1135. mov si,ID4
  1136. call ResetIrpt
  1137. mov si,ID60
  1138. call ResetIrpt
  1139. mov si,ID61
  1140. call ResetIrpt
  1141. skip:
  1142. mov ds, cs:[@D_DATA]
  1143. jmp far [@ChainVector]
  1144. (*ROM
  1145. The program is exiting. There might be an error code in @ErrorCode. Since
  1146. ROM systems probably never exit, you would probably print an error message
  1147. and loop until infinity (or wait for a keystroke before jumping back to the
  1148. initialization routines (see end of this file)).
  1149. *)
  1150. public NormalExit:
  1151. mov ds, cs:[@D_DATA]
  1152. mov ah,4CH
  1153. mov al, [@ErrorCode]
  1154. int 21H
  1155. RunTimeMessages : dw m90,m91,m92,m93,m94,m95,msg99,m97
  1156. Int4 :
  1157. push bp
  1158. mov bp,sp
  1159. push ds
  1160. push es
  1161. push si
  1162. push di
  1163. push ax
  1164. push bx
  1165. push cx
  1166. push dx
  1167. call @PrtAddr
  1168. les si,[bp][2]
  1169. mov bl,es:[si] (* base at 70H *)
  1170. sub bh,bh
  1171. shl bx,1
  1172. mov dx,cs:[RunTimeMessages][bx][-90H*2]
  1173. prtms:
  1174. call @PrtDollarStr
  1175. cmp byte es:[si],91H
  1176. jnz acc
  1177. jmp @Abort
  1178. acc:
  1179. call @Accept
  1180. inc word [bp][2]
  1181. pop dx
  1182. pop cx
  1183. pop bx
  1184. pop ax
  1185. pop di
  1186. pop si
  1187. pop es
  1188. pop ds
  1189. pop bp
  1190. Int60:
  1191. iret
  1192. (* removed due to problems with some 286 compatibles
  1193. Trap5:
  1194. push si
  1195. mov si,ID5
  1196. jmp TrapEntry
  1197. Trap6:
  1198. push si
  1199. mov si,ID6
  1200. jmp TrapEntry
  1201. Trap0D:
  1202. push si
  1203. mov si,ID0D
  1204. jmp TrapEntry
  1205. *)
  1206. Trap0 :
  1207. push si
  1208. mov si,ID0
  1209. TrapEntry:
  1210. push bp
  1211. mov bp,sp
  1212. (* removed due to problems with some 286 compatibles
  1213. push es
  1214. push ds
  1215. push ax
  1216. push bx
  1217. les bx,[bp][4]
  1218. dec bx
  1219. dec bx
  1220. mov al,0CDH
  1221. mov ds, cs:[@D_DATA]
  1222. mov ah,[si][IrptNo]
  1223. cmp ax,es:[bx]
  1224. jne $HWinterrupt
  1225. (*SWinterrupt*)
  1226. mov bx,[si][IrptChainIP]
  1227. mov [LongJumpIP],bx
  1228. mov bx,[si][IrptChainCS]
  1229. mov [LongJumpCS],bx
  1230. pop bx
  1231. pop ax
  1232. pop ds
  1233. pop es
  1234. pop bp
  1235. pop si
  1236. jmp LongJump
  1237. $HWinterrupt:
  1238. *)
  1239. sti
  1240. mov ds, cs:[@D_DATA]
  1241. mov dx, [si][IrptMsg]
  1242. push cs
  1243. pop ds
  1244. push cs
  1245. pop es
  1246. add bp,2
  1247. public @PrtAddrAbort:
  1248. push dx
  1249. call @PrtAddr
  1250. pop dx
  1251. call @PrtDollarStr
  1252. jmp @Abort
  1253. SetResetProcessorTraps :
  1254. (* IN DX = Procedure to either set or reset interrupts *)
  1255. push ax
  1256. push si
  1257. (* set Irpt 0 trap *)
  1258. mov si,ID0
  1259. call dx
  1260. (* removed due to problems with some 286 compatibles
  1261. (* determine if 286 machine *)
  1262. pushf
  1263. sub ax,ax
  1264. push ax
  1265. popf
  1266. pushf
  1267. pop ax
  1268. popf
  1269. and ah,0F0H
  1270. cmp ah,0F0H
  1271. je Not286Compatible (* 8088 or 8086 *)
  1272. mov si,ID5
  1273. call dx
  1274. mov si,ID6
  1275. call dx
  1276. mov si,ID0D
  1277. call dx
  1278. Not286Compatible:
  1279. *)
  1280. pop si
  1281. pop ax
  1282. ret near 0
  1283. public @SetProcessorTraps :
  1284. push dx
  1285. mov dx,SetIrpt
  1286. SetResetTraps:
  1287. call SetResetProcessorTraps
  1288. pop dx
  1289. ret near 0
  1290. public @ResetProcessorTraps :
  1291. push dx
  1292. mov dx,ResetIrpt
  1293. jmp SetResetTraps
  1294. public @SetBreakInterrupt :
  1295. (*ROM
  1296. Install trapping of BIOS Ctrl-Break and DOS Ctrl-C handlers. There is
  1297. probably no DOS Ctrl-C interrupt, so just comment that portion out. If
  1298. there is BIOS keyboard support, then the Ctrl-Break interception can be
  1299. left in (and the application can use Lib.DisableBreak to turn it off).
  1300. Otherwise, comment it out also.
  1301. *)
  1302. push si
  1303. push es
  1304. push bx
  1305. mov si,ID1B
  1306. call SetIrpt
  1307. mov si,ID23
  1308. call SetIrpt
  1309. pop bx
  1310. pop es
  1311. pop si
  1312. ret 0
  1313. public @ResetBreakInterrupt :
  1314. (*ROM
  1315. Restore previous BIOS Ctrl-Break and DOS Ctrl-C handlers. See the above
  1316. comments.
  1317. *)
  1318. push si
  1319. mov si,ID8
  1320. call ResetIrpt
  1321. mov si,ID1B
  1322. call ResetIrpt
  1323. mov si,ID23
  1324. call ResetIrpt
  1325. pop si
  1326. ret 0
  1327. Trap1B :
  1328. (*ROM
  1329. The BIOS Ctrl-Break handler.
  1330. (*INT8*)
  1331. This routine installs an Int8 handler. The Int8 handler keeps checking to
  1332. see whether the program is currently executing program code, or whether
  1333. it is executing code outside of the program (such as in DOS). When the
  1334. program is within its own code, the program is terminated. The purpose of
  1335. this exercise is to prevent DOS re-entrancy.
  1336. *)
  1337. push ax
  1338. push ds
  1339. push es
  1340. mov es, cs:[@D_DATA]
  1341. mov byte es:[@StopProgramFlag], 1 (* Signal Break *)
  1342. sub ax, ax
  1343. mov ds, ax
  1344. mov al, 1
  1345. xchg al,es:[ID8][IrptLoaded]
  1346. cmp al, 1
  1347. je $loaded
  1348. mov ax, Trap8
  1349. xchg ax, ds:[8*4]
  1350. mov es:[ID8][IrptChainIP], ax
  1351. mov ax, cs
  1352. xchg ax, ds:[8*4+2]
  1353. mov es:[ID8][IrptChainCS], ax
  1354. $loaded:
  1355. pop es
  1356. pop ds
  1357. pop ax
  1358. iret
  1359. Trap23 : (* Dos Break interrupt *)
  1360. (*ROM
  1361. The DOS Ctrl-C handler.
  1362. *)
  1363. push bp
  1364. mov bp,sp
  1365. push ds
  1366. mov ds, cs:[@D_DATA]
  1367. mov byte [@InProgramFlag], 1
  1368. pop ds
  1369. jmp @UserBreak;
  1370. (*ROM
  1371. (*INT8*)
  1372. This is the Int8 handler installed by Trap1B.
  1373. *)
  1374. Trap8 :
  1375. push ds
  1376. push ax
  1377. mov ds, cs:[@D_DATA]
  1378. cmp byte [@InProgramFlag], 1
  1379. je OkToBreak
  1380. pushf
  1381. push cs
  1382. mov ax, BackFromPrev
  1383. push ax
  1384. jmp far [ID8][IrptChainIP]
  1385. BackFromPrev:
  1386. pop ax
  1387. pop ds
  1388. iret
  1389. OkToBreak:
  1390. pop ax
  1391. pop ds
  1392. mov al, eoivalue
  1393. out eoiport, al (* send eoi *)
  1394. push bp
  1395. mov bp,sp
  1396. public @UserBreak:
  1397. call @ResetBreakInterrupt
  1398. push ds
  1399. mov ds, cs:[@D_DATA]
  1400. mov byte [@StopProgramFlag], 0 (* Allow DOS access *)
  1401. pop ds
  1402. mov dx,msg8
  1403. jmp @PrtAddrAbort
  1404. No = 78;
  1405. Yes = 89;
  1406. public @Accept :
  1407. mov dx,msg2
  1408. call @PrtDollarStr
  1409. AcceptAgain:
  1410. (*ROM
  1411. Read a character from the keyboard. Called only by the run-time error
  1412. routines, to give the user the opportunity to ignore the error.
  1413. *)
  1414. mov ah,7
  1415. int 21H
  1416. cmp al,No
  1417. je Standard@HALTjmp
  1418. cmp al,No+32
  1419. je Standard@HALTjmp
  1420. cmp al,Yes
  1421. je Acceptret
  1422. cmp al,Yes+32
  1423. jne AcceptAgain
  1424. Acceptret:
  1425. mov dx,msg0
  1426. call @PrtDollarStr
  1427. ret 0
  1428. Standard@HALTjmp:
  1429. jmp Standard@HALT
  1430. msg0 : db 13,10,'$'
  1431. msg2 : db '. Continue (y/n) $'
  1432. @PrtChar :
  1433. (*ROM
  1434. Print a character to the screen. Called by various "abnormal termination"
  1435. routines to print messages about where/why the program died.
  1436. *)
  1437. push bx
  1438. push cx
  1439. push ax
  1440. push ds
  1441. push ss
  1442. pop ds
  1443. push dx
  1444. mov dx,sp
  1445. mov bx, 2
  1446. mov cx, 1
  1447. mov ah, 40H
  1448. int 21H
  1449. pop dx
  1450. pop ds
  1451. pop ax
  1452. pop cx
  1453. pop bx
  1454. ret 0
  1455. public @PrtDollarStr :
  1456. push bx
  1457. push dx
  1458. mov bx,dx
  1459. PrtDollarLoop:
  1460. mov dl, [bx]
  1461. cmp dl, 36 (*'$'*)
  1462. je PrtDollarExit
  1463. call @PrtChar
  1464. inc bx
  1465. jmp PrtDollarLoop
  1466. PrtDollarExit:
  1467. pop dx
  1468. pop bx
  1469. ret 0
  1470. public @PrtHex :
  1471. push si
  1472. mov cl,4
  1473. rol dx,cl
  1474. mov bx,xtab
  1475. mov si,4
  1476. HexLoop:
  1477. mov al,dl
  1478. and al,0FH
  1479. db 2EH (*cs:*); xlat
  1480. push dx
  1481. mov dl,al
  1482. call @PrtChar
  1483. pop dx
  1484. rol dx,cl
  1485. dec si
  1486. jnz HexLoop
  1487. pop si
  1488. ret 0
  1489. xtab : db '0123456789ABCDEF'
  1490. @PrtAddr :
  1491. (* entry - abort address is on stack *)
  1492. push cs
  1493. pop ds
  1494. mov dx,msg1
  1495. call @PrtDollarStr
  1496. mov dx,[bp][4]
  1497. call @PrtHex
  1498. mov ax,cs
  1499. cmp ax,[bp][4]
  1500. ja isMsdos
  1501. mov dl, 47 (*'/'*)
  1502. call @PrtChar
  1503. mov dx,[bp][4]
  1504. mov ax,cs
  1505. sub dx,ax
  1506. call @PrtHex
  1507. isMsdos:
  1508. mov dl, 58 (*':'*)
  1509. call @PrtChar
  1510. mov dx,[bp][2]
  1511. jmp @PrtHex
  1512. msg1 : db 'Run Time Error [$ '
  1513. section ;
  1514. segment C_CODE(CODE,28H);
  1515. segment D_DATA(M_DATA,28H);
  1516. group G_CODE(C_CODE)
  1517. select C_CODE
  1518. public @D_DATA : dw D_DATA
  1519. section ;
  1520. segment D_DATA(M_DATA,28H);
  1521. select D_DATA
  1522. public @InProgramFlag : org 1
  1523. public @StopProgramFlag : org 1
  1524. public @PSP : org 2
  1525. public @ErrorCode : org 1
  1526. public @ChainVector : org 4
  1527. public standard@haltChain : org 4
  1528. section ;
  1529. segment ENTERCODE(CODE,28H);
  1530. segment INITCODE(CODE,28H);
  1531. segment C_CODE(CODE,28H);
  1532. group G_CODE(INITCODE,C_CODE)
  1533. segment DataStart(Dummy,68H);
  1534. group DGROUP(DataStart);
  1535. select DataStart
  1536. @DataStart:
  1537. select INITCODE
  1538. extrn @D_DATA
  1539. extrn @Int4Init
  1540. extrn @PSP
  1541. extrn @SetBreakInterrupt
  1542. extrn @SetProcessorTraps
  1543. extrn _DoBreakInit
  1544. extrn @InProgramFlag
  1545. extrn @StopProgramFlag
  1546. extrn @PSP
  1547. extrn @ErrorCode
  1548. extrn @ChainVector
  1549. extrn standard@haltChain
  1550. extrn NormalExit
  1551. extrn Standard$HALT
  1552. extrn @IntIDTable
  1553. extrn @IntIDSrc
  1554. extrn @IntIDStop
  1555. (* A few words of explanation about how initialisation works:
  1556. The linker packs the various INITCODE segments together,
  1557. ( for this reason they must be byte aligned ), in an order
  1558. which is the reverse of the order in which the object module
  1559. sections are included by recursively resolving externals,
  1560. starting with the section with the entry point, that is this section.
  1561. Thus this bit of code finishs with a jump to 0.
  1562. *)
  1563. rtl$init:
  1564. (*ROM
  1565. The PSP probably doesn't exist. This code uses the initial value of DS to
  1566. record the PSP segment.
  1567. *)
  1568. mov bx, ds
  1569. mov ds, cs:[@D_DATA]
  1570. mov [@PSP], bx
  1571. cld (* cld is assumed everywhere *)
  1572. (* zero global variables if required *)
  1573. test word cs:[_DoBreakInit],2
  1574. jz skip
  1575. sub ax,ax
  1576. mov ds, cs:[@D_DATA]
  1577. push [@PSP]
  1578. mov bx,ss
  1579. mov dx, seg @DataStart
  1580. more:
  1581. mov es,dx
  1582. mov di, @DataStart
  1583. mov cx,8
  1584. rep
  1585. stosw
  1586. inc dx
  1587. cmp dx,bx
  1588. jb more
  1589. pop [@PSP]
  1590. skip:
  1591. (* initialize global data *)
  1592. mov ds, cs:[@D_DATA]
  1593. mov byte [@InProgramFlag], 1
  1594. mov byte [@StopProgramFlag], 0
  1595. (*
  1596. mov word [@PSP], 0 (* initialized above *)
  1597. *)
  1598. mov byte [@ErrorCode], 0
  1599. mov word [@ChainVector], NormalExit
  1600. mov word [@ChainVector][2], C_CODE
  1601. mov word [standard@haltChain], Standard$HALT
  1602. mov word [standard@haltChain][2], C_CODE
  1603. (* initialize interrupt ID table *)
  1604. push cs
  1605. pop ds
  1606. mov si, @IntIDSrc
  1607. mov es, cs:[@D_DATA]
  1608. mov di, @IntIDTable
  1609. mov cx, @IntIDStop
  1610. sub cx, @IntIDSrc
  1611. shr cx, 1
  1612. rep; movsw
  1613. (* set required break handler *)
  1614. test word cs:[_DoBreakInit],1
  1615. jz setnullbreak
  1616. call @SetBreakInterrupt
  1617. jmp skip2
  1618. setnullbreak:
  1619. (*ROM
  1620. Set DOS Ctrl-C handler. Since you probably aren't using DOS, it's probably
  1621. safe to just comment this out.
  1622. *)
  1623. mov ax,2523H (* set break vector *)
  1624. mov dx,DummyBreak
  1625. push cs
  1626. pop ds
  1627. int 21H
  1628. skip2:
  1629. call @Int4Init (* int4 is used to report run time errors *)
  1630. call @SetProcessorTraps (* traps 286 segment overruns and similar *)
  1631. sub ax,ax
  1632. push ax (* marks end when following stack frame chain *)
  1633. mov bp,sp
  1634. jmp ax (* jump to other initializations !! *)
  1635. DummyBreak :
  1636. iret
  1637. select ENTERCODE
  1638. (* The program entry point !! *)
  1639. (*ROM
  1640. This is where the program enters. You should perform any needed machine
  1641. initialization here. Specifically, be sure to initialize SS:SP.
  1642. *)
  1643. jmp far rtl$init
  1644. db 'JPI Modula2' (* pad to 16 bytes *)
  1645. end *
  1646.