TPSRC7 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600
  1. CMP.B cpmode,#$00 ;memory ?
  2. JNZ turfil2 ;:no
  3. MOV.B txcomp,#$FF ;set flag: compiled
  4. JMP.b turret ;'
  5. turfil2 CMP.B cpmode,#$02 ;COM / CHN ?
  6. JB turret ;:no
  7. CALL codflush ;flush code buffer
  8. turret XOR.B AL,AL
  9. JMP errexit ;"return: no error
  10. inittur MOV.B txcomp,#$00 ;Init variables: not compiled
  11. MOV.B cdinval,#$00 ;code invalid
  12. MOV BX,txend ;store ^Z at source end
  13. MOV.B [BX],#$1A
  14. MOV CL,#$04 ;(size/16)+1+DS
  15. SHR BX,CL
  16. INC BX
  17. MOV AX,DS
  18. ADD AX,BX
  19. MOV destseg,AX ;-> code dest segment
  20. MOV AX,freemem ;free memory - size
  21. SUB AX,BX
  22. MOV minstksz,AX ;-> minimum stack size
  23. MOV DI,stackpt ;stack pointer - 1024
  24. SUB DI,#$0400
  25. MOV ptcend,DI ;-> end of patch list space
  26. SUB DI,#$0400 ;- 1024
  27. MOV ptctop,DI ;-> top of patch list
  28. MOV ptcbeg,DI ;-> beg of patch list
  29. DEC DI ;destination for var table
  30. MOV SI,#stdvars ;copy std vars into symbol table
  31. MOV CX,SS ;SS -> ES
  32. MOV ES,CX
  33. PUSH DS ;save DS
  34. MOV CX,CS ;CS -> DS
  35. MOV DS,CX
  36. MOV CX,#$036A ;count
  37. STD
  38. REPZ
  39. MOVS.B
  40. POP DS ;restore DS
  41. INC DI
  42. MOV symtop,DI ;-> top of symtab
  43. MOV symtop2,DI
  44. MOV fence,DI ;-> current var fence
  45. MOV BX,#varpatch ;patch in ptrs to type defs
  46. MOV CX,#$0019
  47. itpatch CS:
  48. MOV BP,[BX] ;pointer
  49. ADD [BP_DI],DI ;+ offset
  50. INC BX
  51. INC BX ;next one
  52. LOOP itpatch ;:another one
  53. MOV AX,txbeg ;text beg
  54. MOV srcptr,AX ;-> src ptr
  55. MOV DI,#pnbuf ;line buffer
  56. MOV chptr,DI ;-> char ptr
  57. MOV.B [DI],#$00 ;clear line
  58. XOR AX,AX ;clear vars:
  59. MOV recnum,AL ;record nesting
  60. MOV reccnt,AL
  61. MOV lexnest,AL ;lexical nesting
  62. MOV srcend,AL ;not end of source
  63. MOV flgpshax,AL ;no PUSH AX
  64. MOV flgpshes,AL ;no PUSH ES
  65. MOV flgpshdi,AL ;no PUSH DI
  66. MOV usrint,AL ;user int not used
  67. MOV ovrcnt,AL ;no overlays used
  68. MOV inclflg,AL ;no include
  69. MOV cdptr,AX ;code ptr
  70. MOV cdbufpt,AX ;code pos in buffer
  71. MOV cdbegpt,AX ;beg of code buffer
  72. MOV cdfoff,AX ;current file offset
  73. MOV cdfoff1,AX
  74. MOV lincnt,AX ;line counter
  75. MOV cinpsize,AX ;std in buffer size
  76. MOV coutsize,AX ;std out buffer size
  77. MOV cmaxfil,#$0010 ;max 16 open files
  78. MOV.B scalcnt,#$0D ;counter for scalar types
  79. MOV direct,#$00ED ;set compiler directive
  80. CALL disline ;display line, test brk
  81. MOV pc,#$2D7C ;PC: start of code
  82. MOV dc,#$0240 ;DC: start of file list
  83. CMP.B cpmode,#$02 ;COM ?
  84. JZ itcom ;:yes
  85. JA itret ;CHN:ret
  86. MOV cdptr,#$2D7C ;code pos of buffer
  87. RET ;'
  88. itcom MOV cdptr,#$2C7C ;code ptr
  89. MOV cdbufpt,#$2C7C ;code pos of buffer
  90. itret RET ;"
  91. copyrt MOV AX,#start ;Test for memory overflow
  92. MOV cdptr,AX
  93. MOV CL,#$04 ;(../16)+1
  94. SHR AX,CL
  95. INC AX
  96. ADD AX,destseg ;+ dest segment
  97. MOV BX,symtop ;(symtop/16)+SS
  98. SHR BX,CL
  99. MOV CX,SS
  100. ADD BX,CX
  101. CMP AX,BX ;compare them
  102. CALL errnb ;99:compiler overflow
  103. B $63
  104. XOR SI,SI ;clear addr
  105. XOR DI,DI
  106. MOV ES,destseg ;dest seg
  107. PUSH DS ;save DS
  108. PUSH CS ;CS -> DS
  109. POP DS
  110. MOV CX,#start ;copy runtime library into code
  111. CLD
  112. REPZ
  113. MOVS.B
  114. POP DS ;restore DS
  115. RET ;"
  116. opendest MOV AH,#$3C ;Open dest file
  117. XOR CX,CX ;no attribute
  118. MOV DX,#destpn ;dest name ptr
  119. PUSH DS ;DS -> ES
  120. POP ES
  121. CALL dos ;create it
  122. CALL errb
  123. B $C9
  124. MOV dstfile,AX ;store file handle
  125. CMP.B cpmode,#$02 ;COM file ?
  126. JNZ odret ;:no
  127. MOV BX,AX ;file handle
  128. MOV AH,#$40 ;write byte block
  129. MOV CX,#$2C7C ;size of runtime code
  130. MOV DX,#$0100 ;offset
  131. PUSH DS ;save DS
  132. PUSH CS ;CS -> DS
  133. POP DS
  134. CALL dos ;write runtime library
  135. POP DS ;restore DS
  136. JB oderr ;:error
  137. CMP AX,CX ;length = expected ?
  138. JNZ oderr ;no: error
  139. odret RET ;'
  140. oderr CALL err ;C9:dest file not written
  141. B $C9 ;"
  142. cvmemdsk PUSH DS ;Change mem code to disk code
  143. PUSH DS ;save DS
  144. POP ES ;DS -> ES
  145. MOV DS,destseg ;code dest segment
  146. MOV SI,#memparm ;ptr to memory parameters
  147. MOV DI,#pnbuf ;dest: buffer
  148. MOV CX,#$0007 ;7 words
  149. CLD
  150. REPZ
  151. MOVS ;move it into buffer
  152. PUSH DS ;DS -> ES
  153. POP ES
  154. POP DS ;restore DS
  155. MOV DI,#memparm ;ptr to memory parameters
  156. ES:
  157. AND [DI],#$FFFE ;clear direct mode
  158. MOV AX,codesize ;code size > min CS size ?
  159. CMP AX,mincssz
  160. JNB cvdcs ;:ok
  161. MOV AX,mincssz ;at least min CS size
  162. cvdcs ES:
  163. MOV [DI]$06,AX ;store CS size
  164. MOV AX,datasize ;data size > min DS size ?
  165. CMP AX,mindssz
  166. JNB cvdds ;:ok
  167. MOV AX,mindssz ;at least min DS size
  168. cvdds ES:
  169. MOV [DI]$08,AX ;store DS size
  170. MOV AX,minhpsz ;min free heap
  171. ES:
  172. MOV [DI]$0A,AX ;-> heap, stack size
  173. CMP AX,maxhpsz ;> max free heap ?
  174. JNB cvdhp ;:yes
  175. MOV AX,maxhpsz ;take that size
  176. cvdhp ES:
  177. MOV [DI]$0C,AX ;store max heap,stack size
  178. MOV AH,#$40 ;Write code to disk
  179. MOV BX,dstfile ;dest file handle
  180. MOV CX,cdptr ;code end
  181. MOV DX,#start ;offset: end of run-time
  182. SUB CX,DX ;calc length
  183. PUSH DS ;save DS
  184. PUSH ES ;ES -> DS
  185. POP DS
  186. CALL dos ;write it
  187. POP DS ;restore DS
  188. PUSH AX ;save results
  189. PUSH CX
  190. PUSHF
  191. MOV SI,#pnbuf ;restore memory code
  192. MOV DI,#memparm
  193. MOV ES,destseg
  194. MOV CX,#$0007 ;7 words
  195. CLD
  196. REPZ ;do it
  197. MOVS
  198. POPF ;restore results
  199. POP CX
  200. POP AX
  201. JB cvderr ;:error
  202. CMP AX,CX ;length = expected ?
  203. JNZ cvderr ;:no
  204. RET ;'
  205. cvderr CALL err ;C9:file error
  206. B $C9 ;"
  207. compile CALL skip ;Compile program: get word
  208. CALL ctoken ;PROGRAM ?
  209. W tkprog
  210. JNZ comnoprm ;:no
  211. CALL dummysym ;read dummy symbol
  212. CALL cbrack1 ;( ?
  213. JNZ comprmen ;:no
  214. comprmlp CALL dummysym ;read dummy symbol
  215. CALL ccomma ;, ?
  216. JZ comprmlp ;yes: repeat
  217. CALL ebrack2 ;! )
  218. comprmen CALL esemi ;! ;
  219. comnoprm MOV AX,#initmem ;* CALL initmem
  220. CALL ecall ;emit CALL
  221. XOR AX,AX ;set mode flag
  222. CMP.B cpmode,#$00 ;to memory ?
  223. JNZ comcom ;:no
  224. OR AX,#$0001 ;flag: direct mode
  225. comcom TEST direct,#$0080 ;device checking ?
  226. JZ comdevck ;:no
  227. OR AX,#$0002 ;set flag
  228. comdevck TEST direct,#$0008 ;test ^C and ^S ?
  229. JZ comctcs ;:no
  230. OR AX,#$0004 ;set flag
  231. comctcs PUSH AX ;save flag
  232. PUSH cdptr ;save code ptr
  233. CALL eword ;emit mode flag
  234. MOV AX,CS ;emit Turbo CS
  235. CALL eword
  236. MOV AX,DS ;emit Turbo DS
  237. CALL eword
  238. PUSH cdptr ;save code ptr
  239. CALL eword ;emit 4 dummy words:
  240. CALL eword ;memory size is not yet known
  241. CALL eword
  242. CALL eword
  243. MOV AX,cmaxfil ;max number of open files
  244. ADD dc,AX ;add to data counter
  245. ADD dc,AX ;(file handle list)
  246. CALL eword ;emit file count
  247. MOV AX,cinpsize ;std in buf size
  248. ADD dc,AX ;add to DC
  249. CALL eword ;emit
  250. MOV AX,coutsize ;std out buf size
  251. ADD dc,AX ;add to DC
  252. CALL eword ;emit
  253. CALL ecode ;* MOV BP,SP
  254. B $02,$8B,$EC
  255. MOV varspc,#$0000 ;clear var space used
  256. CALL emcrunch ;emit overlay uncrunch
  257. CALL defpart ;declaration part
  258. CALL progpart ;program part
  259. MOV DI,chptr
  260. CMP.B [DI],#$2E
  261. CALL errnz
  262. B $0A
  263. CALL ecode ;* XOR AX,AX
  264. B $02,$33,$C0
  265. MOV AX,#progend ;* CALL progend
  266. CALL ecall
  267. CALL ptcrunch ;end overlay crunch list
  268. MOV AX,pc ;(PC+15)/16
  269. ADD AX,#$000F
  270. MOV CL,#$04
  271. SHR AX,CL
  272. MOV codesize,AX ;-> CS size
  273. MOV AX,dc ;(DC+15)/16
  274. ADD AX,#$000F
  275. MOV CL,#$04
  276. SHR AX,CL
  277. MOV datasize,AX ;-> DS size
  278. POP BX ;code ptr: memory sizes
  279. MOV AX,codesize ;CS size > min CS size ?
  280. CMP AX,mincssz
  281. JNB comcs ;:ok
  282. MOV AX,mincssz ;at least min CS size
  283. comcs CALL patch ;patch in
  284. INC BX
  285. INC BX
  286. MOV AX,datasize ;DS size > min DS size ?
  287. CMP AX,mindssz
  288. JNB comds ;:ok
  289. MOV AX,mindssz ;at least min DS size
  290. comds CALL patch ;patch in
  291. INC BX
  292. INC BX
  293. MOV AX,minhpsz ;min free heap
  294. CMP.B cpmode,#$02 ;COM / CHN ?
  295. JNB comfile ;:yes
  296. MOV AX,minstksz ;min stack size
  297. SUB AX,codesize ;- code size - data size
  298. SUB AX,datasize
  299. MOV minstksz,AX ;-> min stack size
  300. comfile PUSH AX ;save it
  301. CALL patch ;patch in
  302. POP AX ;restore
  303. INC BX
  304. INC BX
  305. CMP AX,maxhpsz ;> max free heap size ?
  306. JNB comhp ;:ok
  307. MOV AX,maxhpsz ;at least max free heap
  308. comhp CALL patch ;patch in
  309. POP BX ;code ptr mode flag
  310. POP AX ;flag
  311. CMP.B usrint,#$00 ;user interrupt used ?
  312. JZ comnobrk ;:no
  313. OR AX,#$0008 ;set flag: user interrupt
  314. comnobrk CALL patch ;patch in
  315. JMP ptcflush ;"patch code in file
  316. dummysym PUSH symtop ;read dummy symbol
  317. CALL rdsym ;read symbol
  318. POP symtop ;restore symtob: forget symbol read
  319. RET ;"
  320. chkovrfl PUSH AX ;Test for overflow
  321. PUSH BX
  322. PUSH CX ;save regs
  323. CMP.B cpmode,#$00 ;to memory ?
  324. JNZ ckvfil ;:no
  325. MOV AX,pc ;(PC/16)+1
  326. MOV CL,#$04
  327. SHR AX,CL
  328. INC AX
  329. MOV BX,dc ;+(DC/16)+64
  330. MOV CL,#$04
  331. SHR BX,CL
  332. ADD BX,AX
  333. ADD BX,#$40
  334. CMP BX,minstksz ;>= free memory ?
  335. CALL errnb ;98:memory overflow
  336. B $62
  337. JMP.b ckvmem ;'ok
  338. ckvfil MOV AX,cdptr ;code ptr
  339. SUB AX,cdbufpt ;-code pos of buffer
  340. ADD AX,cdbegpt ;+beg of code buffer
  341. MOV CL,#$04 ;convert to paragraphs
  342. SHR AX,CL
  343. INC AX
  344. ckvmem ADD AX,destseg ;+ dest segment
  345. ADD AX,#$0020 ;+ spare
  346. MOV BX,symtop ;(symtab top/16)+SS
  347. SHR BX,CL
  348. MOV CX,SS
  349. ADD BX,CX
  350. CMP AX,BX ;crash ?
  351. JB ckvok ;:no
  352. PUSH DX ;save
  353. CALL codflush ;flush code buffer
  354. CALL errb ;99:compiler overflow
  355. B $63
  356. POP DX ;restore
  357. ckvok POP CX ;restore regs
  358. POP BX
  359. POP AX
  360. RET ;"
  361. alpha CMP AL,#$41 ;valid symbol char ?
  362. JB alpharet ;:no
  363. CMP AL,#$5B ;A..Z ?
  364. CMC
  365. JNB alpharet ;:ok
  366. CMP AL,#$5F ;_ ?
  367. JZ alpharet ;yes: ok
  368. CMP AL,#$61 ;a..z ?
  369. JB alpharet ;:no
  370. CMP AL,#$7B
  371. CMC
  372. alpharet RET ;"
  373. alphanum CALL alpha ;valid alphanumeric char ?
  374. JNB alnret ;:ok
  375. number CMP AL,#$30 ;0..9 ?
  376. JB alnret ;:no
  377. CMP AL,#$3A
  378. CMC
  379. alnret RET ;"
  380. perrb MOV chptr,DI ;Error if below: store error pos
  381. errb JNB skiperr ;:no error
  382. JMP.b err ;'
  383. MOV chptr,DI ;Error if not below
  384. errnb JB skiperr ;:no error
  385. JMP.b err ;'
  386. perrz MOV chptr,DI ;Error if equal
  387. errz JNZ skiperr ;:no error
  388. JMP.b err ;'
  389. perrnz MOV chptr,DI ;Error if not equal
  390. errnz JNZ err ;:error
  391. skiperr PUSH BP ;no error: skip inline parameter
  392. MOV BP,SP
  393. INC [BP]$02
  394. POP BP
  395. RET ;'
  396. perr MOV chptr,DI ;store error position
  397. err POP BX ;Error: get return addr
  398. CS:
  399. MOV.B AL,[BX] ;get error number (inline)
  400. errexit MOV cperr,AL ;store it
  401. CALL disline ;write line number
  402. OR.B AL,AL ;test error
  403. JZ exitcom ;:no error
  404. MOV AX,chptr ;calculate error position
  405. SUB AX,#pnbuf ;pos in buffer - buffer beg
  406. CMP.B inclflg,#$00 ;include file ?
  407. JNZ errfil ;:yes
  408. SUB AX,txbeg ;- text beg
  409. ADD AX,srclnbeg ;+ beginning of source line
  410. JMP.b errmem ;'
  411. errfil ADD AX,srclnbg ;pos of line begin
  412. errmem MOV txerrpos,AX ;store relative error pos
  413. exitcom MOV AH,#$80 ;close all files
  414. CALL dos
  415. MOV SP,spsav ;restore stack pointer
  416. RET ;"return to user-interface
  417. defpart PUSH cdptr ;Definition part: save code pointer
  418. CALL ejump ;* JMP ....
  419. PUSH pc ;save PC
  420. defloop CALL ckey ;search keyword
  421. B $01 ;offset between keywords
  422. W tklabel ;keyword pointer
  423. CALL errnz ;not found ?
  424. B $0C ;12:BEGIN expected
  425. deflab CMP AL,#$01 ;LABEL ?
  426. JNZ defconst ;:no
  427. CALL label ;do label
  428. JMP defloop ;'next def
  429. defconst CMP AL,#$02 ;CONST ?
  430. JNZ deftype ;:no
  431. CALL const ;do const
  432. JMP deflab ;'next def, already searched
  433. deftype CMP AL,#$03 ;TYPE ?
  434. JNZ defvar ;:no
  435. CALL type ;do type
  436. JMP deflab ;'next def
  437. defvar CMP AL,#$04 ;VAR ?
  438. JNZ defover ;:no
  439. CALL var ;do var
  440. JMP deflab ;'next def
  441. defover CMP AL,#$07 ;OVERLAY ?
  442. JNZ defproc ;:no
  443. CALL overlay ;do overlay
  444. JMP defloop ;'next def
  445. defproc CMP AL,#$08 ;BEGIN ?
  446. JZ defend ;:yes
  447. MOV.B ovrproc,#$00 ;flag: not overlay procedure
  448. CALL procfunc ;do procedure / function def
  449. JMP defloop ;'next def
  450. defend CALL resforw ;resolve forward definitions
  451. POP CX ;restore beginning PC
  452. MOV AX,pc ;new PC
  453. SUB AX,CX ;calc offset
  454. POP BX ;code ptr of beginning
  455. INC BX ;+1: offset
  456. JMP patch ;"patch it
  457. emcrunch MOV AX,#uncrunch ;emit code for overlay uncrunch
  458. CALL ecall ;* CALL uncrunch
  459. MOV AX,cdptr ;code ptr
  460. MOV uncrlink,AX ;-> link
  461. CALL eword ;emit it (dummy)
  462. MOV AX,pc ;PC+2
  463. INC AX
  464. INC AX
  465. JMP eword ;"emit it
  466. ptcrunch MOV BX,uncrlink ;do overlay uncrunch list
  467. MOV AX,cdptr ;code ptr
  468. SUB AX,BX ;- pos old link
  469. CALL patch ;patch offset
  470. XOR AX,AX ;emit a zero:
  471. JMP eword ;"current end of the list
  472. label MOV AX,#$0100 ;label definition
  473. CALL symword ;store word in symtab
  474. MOV DI,chptr ;current pos
  475. MOV.B AL,[DI] ;get char
  476. CALL alphanum ;in alphanum ?
  477. CALL rdsym0 ;get sym - numbers allowed
  478. MOV.B AH,lexnest ;lexical nesting
  479. MOV AL,#$FF ;flag: unresolved
  480. CALL symword ;store word
  481. CALL symword ;store dummy: offset
  482. CALL symoffs ;write symtab offset
  483. CALL ccomma ;, ?
  484. JZ label ;yes: do another definition
  485. JMP esemi ;"! ;
  486. const PUSH symtop ;Constant definition
  487. XOR AX,AX ;tag: invisible
  488. CALL symword ;store in symtab
  489. CALL rdsym ;get symbol name
  490. CALL cequal ;= ?
  491. JNZ cnstruct ;no: structured constant
  492. CALL rdconst ;read constant
  493. MOV.B AL,CL ;type
  494. CALL symbyte ;store in symtab
  495. CMP.B CL,#$09 ;real ?
  496. JNZ cnstr ;:no
  497. MOV AX,creal3 ;store real number in symtab
  498. CALL symword ;6 bytes
  499. MOV AX,creal2
  500. CALL symword
  501. MOV AX,creal1
  502. CALL symword
  503. JMP.b cnput ;'do end of entry
  504. cnstr CMP.B CL,#$08 ;string ?
  505. JNZ cnint ;:no
  506. MOV BX,#wordbuf ;buffer pointer
  507. MOV.B AL,CH ;get length
  508. INC.B CH ;counter
  509. cnstlp CALL symbyte ;store byte in symtab
  510. MOV.B AL,[BX] ;get next char
  511. INC BX
  512. DEC.B CH ;another ?
  513. JNZ cnstlp ;:yes
  514. JMP.b cnput ;'do end of entry
  515. cnint XCHG AX,BX ;integer constant: result -> AX
  516. CALL symword ;store in symtab
  517. cnput CALL symoffs ;write symtab offset
  518. MOV AL,#$02 ;set tag: normal constant
  519. JMP.b cnput2 ;'do it
  520. cnstruct CALL ecolon ;! : (structured constant)
  521. PUSH symtop ;save symtab pos
  522. CALL symword ;store dummy type
  523. MOV AX,pc ;store offset in symtab
  524. CALL symword
  525. MOV AX,#$FE00 ;segment CS
  526. CALL symword
  527. CALL symoffs ;write symtab offset
  528. CALL rdtype ;get type
  529. POP BP ;restore symtab pos
  530. MOV AX,vartp ;store type ptr
  531. MOV [BP]-$02,AX
  532. CALL eequal ;! =
  533. CALL structcn ;read structured constant
  534. MOV AL,#$04 ;tag: structured constant
  535. cnput2 POP BP ;restore symtab pos
  536. MOV.B [BP]-$01,AL ;set tag byte: entry type
  537. CALL esemi ;! ;
  538. CALL ckey ;search keyword: definitions
  539. B $01
  540. W tklabel
  541. JZ cnrt ;:found, exit
  542. JMP const ;'do another const definition
  543. cnrt RET ;"
  544. structcn MOV AL,varctp ;read structured constant
  545. CMP AL,#$04 ;test component type
  546. JB scnok ;:ok
  547. CMP AL,#$08 ;file / pointer ?
  548. JNB scnok ;:no
  549. CALL err ;61:Files and pointers
  550. B $3D ;'are not allowed here
  551. scnok CMP AL,#$01 ;array ?
  552. JNZ scnrec ;:no
  553. CALL pushe1 ;save entry to stack
  554. MOV BP,upper ;index type
  555. CALL getparm ;get parameters
  556. MOV AX,upper2 ;upper bound - lower bound + 1
  557. SUB AX,lower2
  558. INC AX
  559. PUSH AX ;save count
  560. MOV BP,lower ;component type pointer
  561. CALL getvprm2 ;get parms
  562. POP CX ;restore count
  563. CMP.B varctp,#$0C ;array of char ?
  564. JNZ scnarray ;:no
  565. OR.B CH,CH ;test count
  566. JNZ scnarray ;:more than 256
  567. CALL cbrack1 ;( ?
  568. JNZ scnarrch ;no: defined by string constant
  569. JMP.b scnarrlp ;'
  570. scnarray CALL ebrack1 ;! (
  571. scnarrlp PUSH CX ;save count
  572. CALL structcn ;read structured constant (recursive !)
  573. POP CX ;restore count
  574. DEC CX ;count down
  575. JCXZ scnaend ;:done
  576. CALL ecomma ;! ,
  577. JMP scnarrlp ;'do next entry
  578. scnarrch PUSH CX ;save count
  579. CALL rdstrcn ;read constant
  580. POP DX ;restore expected length
  581. CMP.B CH,DL ;= length read ?
  582. CALL errnz ;50:String const length does not
  583. B $32 ;match type
  584. CALL estr2 ;emit string (without length byte)
  585. JMP.b scnaend2 ;'done
  586. scnaend CALL ebrack2 ;! )
  587. scnaend2 CALL pope1 ;restore entry
  588. RET ;'
  589. scnrec CMP AL,#$02 ;record ?
  590. JNZ scset ;:no
  591. CALL pushe1 ;save entry to stack
  592. CALL ebrack1 ;! (
  593. MOV.B CL,varnest ;record nesting level
  594. PUSH varsize ;save component size
  595. XOR AX,AX ;offset in record: size done
  596. scnrlp PUSH CX ;save nesting, size
  597. PUSH AX
  598. MOV CH,#$04 ;search variable
  599. CALL search
  600. CALL errnz ;41:Unknown ID or syntax error
  601. B $29
  602. CALL getvprm ;get parms
  603. POP AX ;restore size
  604. CMP AX,varofs ;= offset of record sub-var ?
  605. CALL errnz ;69:Invalid ordering of fields
  606. B $45
  607. ADD AX,varsize ;add size to offset
  608. PUSH AX ;save it
  609. CALL ecolon ;! :
  610. CALL structcn ;read structured constant
  611. CALL csemi ;, ?
  612. POP AX ;restore size, nesting level
  613. POP CX
  614. JZ scnrlp ;yes: continue
  615. PUSH AX ;save size
  616. CALL ebrack2 ;! )
  617. POP AX ;current size
  618. POP CX ;component size of record type
  619. SUB CX,AX ;compare them
  620. JZ scnrok ;:ok
  621. scnrfill XOR.B AL,AL ;emit zeroes to fill
  622. CALL ebyte
  623. LOOP scnrfill ;:another
  624. scnrok CALL pope1 ;restore entry from stack
  625. RET ;'
  626. scset CMP AL,#$03 ;set ?
  627. JNZ scstr ;:no
  628. CALL pushe1 ;save entry to stack
  629. PUSH varsize ;save component size
  630. MOV BP,lower ;type ptr
  631. CALL getvprm2 ;get type parms
  632. CALL esqr1 ;! [
  633. MOV DI,#wordbuf ;buffer ptr
  634. PUSH DS ;DS,DI: dest ptr
  635. PUSH DI
  636. CALL sldempty ;make empty set (on stack)
  637. CALL csqr2 ;] ?
  638. JZ scssto ;:yes
  639. scslp CALL rdscalar ;get scalar element
  640. PUSH AX ;save
  641. CALL ctoken
  642. W tk2dot
  643. JNZ scsincl ;:no
  644. CALL rdscalar ;get scalar element
  645. CALL setinrng ;include range in set
  646. JMP.b scsrng ;'
  647. scsincl POP AX ;restore scalar element
  648. CALL setincl ;include element in set
  649. scsrng CALL ccomma ;, ?
  650. JZ scslp ;yes: continue
  651. CALL esqr2 ;! ]
  652. scssto MOV CX,#$0020 ;32 bytes
  653. CALL setsto ;store set into buffer
  654. MOV BX,lower ;crunch set constant:
  655. MOV CL,#$03 ;(lower bound)/8
  656. SHR BX,CL
  657. ADD BX,#wordbuf ;+ buffer offset
  658. POP CX ;restore component size
  659. scsemit MOV.B AL,[BX] ;get byte
  660. CALL ebyte ;emit it
  661. INC BX ;next one
  662. LOOP scsemit ;:another
  663. CALL pope1 ;restore entry from stack
  664. RET ;'
  665. scstr CMP AL,#$08 ;string ?
  666. JNZ screal ;:no
  667. CALL rdstrcn ;read string constant
  668. MOV.B CL,varsize ;component size - 1
  669. DEC.B CL
  670. SUB.B CL,CH ;>= actual size ?
  671. JNB scstok ;:ok
  672. ADD.B CL,CH ;limit to max size
  673. MOV.B CH,CL
  674. XOR.B CL,CL ;nothing to fill up
  675. scstok CALL estring ;emit string
  676. OR.B CL,CL ;fill up ?
  677. JZ scstret ;:no
  678. scstfill XOR.B AL,AL ;emit zeroes to reserve space
  679. CALL ebyte
  680. DEC.B CL ;another ?
  681. JNZ scstfill ;:yes
  682. scstret RET ;'
  683. screal CMP AL,#$09 ;real ?
  684. JNZ scint ;:no
  685. CALL rdnumcn ;get numeric constant
  686. CMP.B CL,#$09 ;real ?
  687. JZ scrok ;:ok
  688. CMP.B CL,#$0A ;integer ?
  689. CALL errnz ;25:Integer or real const expected
  690. B $19
  691. XCHG AX,BX ;get result
  692. CALL intreal ;convert to real
  693. MOV creal1,AX ;store it in buffer
  694. MOV creal2,BX
  695. MOV creal3,DX
  696. scrok MOV AX,creal1 ;emit resulting real number
  697. CALL eword
  698. MOV AX,creal2
  699. CALL eword
  700. MOV AX,creal3
  701. JMP eword ;'done
  702. scint CALL rdscalar ;integer: get scalar element
  703. CMP varsize,#$01 ;component size = 1 ?
  704. JZ scbyte ;:yes
  705. JMP eword ;'emit word
  706. scbyte JMP ebyte ;"emit byte
  707. rdscalar CALL rdnumcn ;get scalar element
  708. CMP.B CL,varctp ;= component type ?
  709. CALL errnz ;44:Type mismatch
  710. B $2C
  711. XCHG AX,BX ;result -> AX
  712. CMP AX,lower ;< lower bound ?
  713. JL rscalerr ;:yes
  714. CMP AX,upper ;> upper bound ?
  715. JG rscalerr ;:yes
  716. RET ;'
  717. rscalerr CALL err ;45:Constant out of range
  718. B $2D ;"
  719. type PUSH symtop ;Type definition
  720. typelp PUSH symtop ;save symtab top
  721. MOV AX,#$0000 ;tag: invisible
  722. CALL symword ;store in symtab
  723. CALL rdsym ;get symbol
  724. PUSH symtop ;save symtab top
  725. CALL symword ;store dummy
  726. CALL symoffs ;write symtab offset
  727. CALL eequal ;! =
  728. CALL rdtype ;get type
  729. POP BP ;restore pos
  730. MOV AX,vartp ;store type ptr
  731. MOV [BP]-$02,AX
  732. POP BP ;pos of tag
  733. MOV.B [BP]-$01,#$03 ;set tag: type definition
  734. CALL esemi ;! ;
  735. CALL ckey ;search keyword: definitions
  736. B $01
  737. W tklabel
  738. JNZ typelp ;not found: another type def
  739. POP tyfence ;old symtab top -> type fence
  740. PUSH AX ;save next element
  741. CALL resptr ;fill in pointer types
  742. POP AX ;restore next element
  743. RET ;"
  744. var CALL vardef ;Var definition: define var
  745. CALL esemi ;! ;
  746. CALL ckey ;search keyword: definitions
  747. B $01
  748. W tklabel
  749. JNZ var ;not found: another var
  750. RET ;"
  751. overlay MOV.B cdinval,#$FF ;Overlay: always recompile
  752. MOV DI,#destpn ;get filename
  753. XOR DX,DX ;end pos
  754. ovnm1 MOV.B AL,[DI] ;get char
  755. OR.B AL,AL ;end ?
  756. JZ ovnmend ;:yes
  757. CMP AL,#$2E ;. ?
  758. JNZ ovnm2 ;:no
  759. MOV DX,DI ;remember end pos
  760. ovnm2 INC DI ;next char
  761. CMP AL,#$5C ;\ ?
  762. JNZ ovnm1 ;no: loop back
  763. MOV BX,DI ;set beg position
  764. XOR DX,DX ;clear end position
  765. JMP ovnm1 ;'loop
  766. ovnmend OR DX,DX ;end position set ?
  767. JZ ovnm3 ;:no
  768. MOV DI,DX ;set it
  769. ovnm3 CMP DI,#destpne ;too much ?
  770. CALL errnb ;92:Unable to create overlay file
  771. B $5C
  772. MOV AL,ovrcnt ;overlay counter
  773. XOR.B AH,AH ;clear high byte
  774. INC.B ovrcnt ;count up
  775. MOV [DI],#$302E
  776. MOV CL,#$0A ;get 10-digit
  777. DIV.B CL
  778. ADD AX,#$3030 ;-> ASCII
  779. MOV [DI]$02,AX ;store number
  780. MOV.B [DI]$04,#$00 ;mark end
  781. MOV AX,#rdover ;* CALL readovr
  782. CALL ecall
  783. MOV AX,#$FFFF ;invalid overlay in mem
  784. CALL eword ;emit word
  785. MOV CX,#$000D ;13 bytes
  786. ovnmem MOV.B AL,[BX] ;emit file name
  787. CALL ebyte
  788. INC BX
  789. LOOP ovnmem ;:another
  790. CALL ptcflush ;patch code in file
  791. CALL codflush ;flush code buffer
  792. MOV AL,cpmode ;save code destination
  793. PUSH AX
  794. PUSH dstfile ;save dest file handle
  795. PUSH cdptr ;save code ptr
  796. PUSH cdbufpt ;save code pos buf beg
  797. PUSH cdbegpt ;save beg of buf
  798. PUSH cdfoff ;save current offset in file
  799. PUSH cdfoff1
  800. PUSH uncrlink ;save uncrunch link
  801. PUSH ovrlen ;save max length of overlay part
  802. CMP.B cpmode,#$00 ;compile to memory ?
  803. JNZ ovfil ;:no
  804. MOV.B cpmode,#$02 ;set: to COM
  805. ovfil MOV AX,cdptr ;code ptr - code pos of buffer
  806. SUB AX,cdbufpt ;add to beg of code buffer
  807. ADD cdbegpt,AX
  808. XOR AX,AX ;length = 0
  809. MOV ovrlen,AX
  810. MOV cdfoff,AX ;no offset in file
  811. MOV cdfoff1,AX
  812. CMP.B cpmode,#$01 ;find error ?
  813. JZ ovloop
  814. MOV AH,#$3C ;create file
  815. XOR CX,CX ;no attribute
  816. MOV DX,#destpn ;name ptr
  817. PUSH DS ;DS -> ES
  818. POP ES
  819. CALL dos ;open it
  820. CALL errb ;92:Unable to create overlay file
  821. B $5C
  822. MOV dstfile,AX ;store dest file handle
  823. ovloop XOR AX,AX
  824. MOV cdptr,AX ;clear code ptr
  825. MOV cdbufpt,AX ;code pos of buffer
  826. CALL ckey ;search key word
  827. B $01 ;(procedure or function)
  828. W tkproc
  829. CALL errnz ;16:PROC or FUNC expected
  830. B $10
  831. PUSH pc ;save PC
  832. PUSH cdptr ;save code ptr
  833. PUSH AX ;save keyword
  834. CALL emcrunch ;emit overlay uncrunch code
  835. POP AX ;restore keyword
  836. MOV.B ovrproc,#$FF ;set flag: in overlay
  837. CALL procfunc ;do proc/func
  838. CALL ptcrunch ;end overlay uncrunch list
  839. CALL ptcflush ;patch code in file
  840. POP CX ;restore code ptr, PC
  841. POP DX
  842. PUSH BP ;save
  843. ovfill MOV AX,cdptr ;new - old code ptr
  844. SUB AX,CX
  845. OR.B AL,AL ;emit zeroes, until length
  846. JZ ovnofill ;a multiple of 256
  847. XOR.B AL,AL
  848. CALL ebyte
  849. JMP ovfill ;'
  850. ovnofill POP BP ;restore
  851. MOV [BP]-$0E,AX ;store code pos in proc def
  852. ADD cdfoff,AX ;add to pos in file
  853. ADC cdfoff1,#$00
  854. MOV AX,pc ;PC - old PC
  855. SUB AX,DX
  856. MOV pc,DX ;restore old PC
  857. CMP AX,ovrlen ;>= previous procedures ?
  858. JB ovshort ;:no
  859. MOV ovrlen,AX ;set as max length
  860. ovshort CALL codflush ;flush code buffer
  861. CALL ctoken ;OVERLAY ?
  862. W tkover
  863. JZ ovloop ;yes: repeat
  864. CMP.B cpmode,#$01 ;find error ?
  865. JZ ovfind ;yes: no file
  866. MOV AH,#$3E ;close file
  867. MOV BX,dstfile ;file handle
  868. CALL dos
  869. ovfind MOV DX,ovrlen ;get maximum length
  870. POP ovrlen ;restore variables
  871. POP uncrlink ;same as above
  872. POP cdfoff1
  873. POP cdfoff
  874. POP cdbegpt
  875. POP cdbufpt
  876. POP cdptr
  877. POP dstfile
  878. POP AX
  879. MOV cpmode,AL ;restore code destination
  880. ADD DX,pc ;max length + PC
  881. MOV BX,uncrlink ;uncrunch link
  882. MOV AX,cdptr ;code ptr -> uncrunch link
  883. MOV uncrlink,AX
  884. SUB AX,BX ;code pos - link
  885. CALL patch ;patch link
  886. CALL eword ;emit word
  887. MOV AX,DX ;max length + PC
  888. CALL eword ;emit word
  889. MOV pc,DX ;set new PC
  890. RET ;"
  891. procfunc MOV procfnc,AL ;define proc / func: set flag
  892. MOV.B CH,AL ;-> type
  893. XOR.B CL,CL
  894. PUSH CX ;save type
  895. CALL srchvar ;search
  896. POP AX
  897. JNZ prfnew ;not found: new definition
  898. JMP prffwd ;'complete forward definition
  899. prfnew CALL symword ;store tag word in symbol table
  900. CALL rdsym ;get symbol
  901. PUSH fence ;save current var fence
  902. MOV AX,symtop2 ;current sym top
  903. MOV fence,AX ;-> new var fence
  904. PUSH symtop ;save symtab pos
  905. SUB symtop,#$10 ;make space
  906. CALL chkovrfl ;test overflow
  907. MOV BX,#$0004 ;size of stack frame
  908. XOR CX,CX ;parameter counter
  909. CALL cbrack1 ;( ?
  910. JNZ prfnil ;no:no parms
  911. prfloop PUSH BX ;save
  912. PUSH CX
  913. PUSH symtop ;save symtab pos
  914. SUB symtop,#$04 ;make space
  915. CALL chkovrfl ;test overflow
  916. CALL ctoken ;VAR ?
  917. W tkvar
  918. MOV CX,#$0000 ;normal: 0
  919. JNZ prfcnt ;no: normal
  920. DEC.B CH ;flag: FF00
  921. prfcnt PUSH CX ;save flag
  922. CALL rdsym ;read symbol
  923. POP CX ;restore type
  924. INC.B CL ;count vars of same type
  925. CALL ccomma ;, ?
  926. JZ prfcnt ;yes: repeat
  927. PUSH CX ;save count
  928. OR.B CH,CH ;VAR-parameter ?
  929. JNZ prfnotyp ;:yes
  930. CALL ecolon ;! :
  931. JMP.b prftype ;'
  932. prfnotyp CALL ccolon ;: ?
  933. JZ prftype ;yes: ok
  934. MOV AX,ptcbeg ;bottom of symtab
  935. SUB AX,#$000E ;point to untyped var
  936. MOV vartp,AX ;-> type ptr
  937. JMP.b prfnot2 ;'
  938. prftype MOV.B flgvar,CH ;set VAR flag
  939. CALL testtp ;get type
  940. CALL tstscal ;limit component size
  941. prfnot2 POP CX ;restore type, count
  942. POP BP ;restore symtab pos
  943. MOV AX,vartp ;type ptr
  944. MOV [BP]-$02,AX ;-> type
  945. MOV [BP]-$04,CX ;store count
  946. MOV AX,varsize ;component size
  947. OR.B CH,CH ;VAR-parameter ?
  948. JZ prfnovar ;:no
  949. MOV AX,#$0004 ;size 4: pointer
  950. prfnovar XOR.B CH,CH ;clear hi
  951. MUL CX ;count * component size
  952. POP CX
  953. POP BX ;restore
  954. ADD BX,AX ;add to size of stack frame
  955. INC.B CL ;count entries
  956. CALL csemi ;semicolon ?
  957. JZ prfloop ;yes: another parm
  958. CALL ebrack2 ;! )
  959. prfnil CALL symoffs ;write symtab offset
  960. CMP.B procfnc,#$06 ;function ?
  961. JNZ prfprc1 ;:no
  962. CALL ecolon ;! :
  963. PUSH BX ;save parm count,
  964. PUSH CX ;stack frame size
  965. MOV.B flgvar,#$00 ;clear flag: normal var
  966. CALL testtp ;get type
  967. POP CX ;restore
  968. POP BX
  969. CMP.B varctp,#$08 ;legal type ?
  970. JNB prfresok ;:no
  971. CMP.B varctp,#$04 ;pointer ?
  972. CALL errnz ;48:Invalid result type
  973. B $30
  974. prfresok POP BP ;symtab ptr
  975. PUSH BP
  976. MOV AX,vartp ;get type ptr
  977. MOV [BP]-$02,AX ;store it
  978. MOV [BP]-$04,BX ;store stack frame size
  979. MOV.B AH,lexnest ;lexical nesting level
  980. INC.B AH ;+1
  981. MOV AL,#$FF
  982. MOV [BP]-$06,AX ;store segment
  983. ADD BX,varsize ;add to size of stack frame
  984. prfprc1 CALL esemi ;! ;
  985. POP BP ;restore symtab ptr
  986. POP AX ;restore var fence
  987. MOV fence,AX
  988. MOV AX,pc ;get PC
  989. CMP.B ovrproc,#$00 ;overlay procedure ?
  990. JZ prfnoovr ;:no
  991. SUB AX,#$0019 ;entry code...
  992. prfnoovr MOV [BP]-$08,AX ;store position
  993. MOV [BP]-$0A,BX ;store stack frame size
  994. XOR.B CH,CH ;store param count
  995. MOV [BP]-$10,CX
  996. MOV AX,cdprcoff ;position in overlay file
  997. MOV [BP]-$0C,AX
  998. MOV [BP]-$0E,#$0000 ;no forward
  999. CMP.B ovrproc,#$00 ;overlay procedure ?
  1000. JNZ prfovr ;:yes
  1001. CALL ctoken ;FORWARD ?
  1002. W tkforwrd
  1003. JNZ prfnofwd ;:no
  1004. MOV AX,cdptr ;remember code position
  1005. MOV [BP]-$0C,AX ;for patching
  1006. DEC.B [BP]-$0F ;set flag: forward def
  1007. CALL ejump ;emit jump
  1008. JMP esemi ;'! ;
  1009. prfnofwd CALL ctoken ;EXTERNAL ?
  1010. W tkext
  1011. JNZ prfovr ;:no
  1012. JMP rdextnal ;'do external procedure
  1013. prffwd CMP.B [BP]-$0F,#$00 ;complete forward definition
  1014. CALL errz ;test flag. Defined:
  1015. B $2B ;43:Duplicate ID or label
  1016. CMP.B ovrproc,#$00 ;overlay procedure ?
  1017. CALL errnz ;yes:
  1018. B $4C ;76:Overlays cannot be forwarded
  1019. CALL skipdi ;skip spaces
  1020. CALL esemi ;! ;
  1021. MOV.B [BP]-$0F,#$00 ;clear forward flag
  1022. MOV BX,[BP]-$0C ;get addr of forward jump
  1023. INC BX
  1024. MOV AX,pc ;PC-proc pos-3 -> offset
  1025. SUB AX,[BP]-$08
  1026. SUB AX,#$0003
  1027. CALL patch ;patch it in
  1028. prfovr PUSH varspc ;save memory usage
  1029. PUSH fence ;save fence
  1030. MOV AX,symtop ;symtab top
  1031. MOV fence,AX ;-> current fence
  1032. PUSH BP ;save pos in symtab
  1033. MOV AX,[BP]-$0A ;get stack frame size
  1034. CMP.B procfnc,#$05 ;procedure ?
  1035. JZ prfprc2 ;:yes
  1036. MOV BX,[BP]-$02 ;subtract size of result
  1037. SS:
  1038. SUB AX,[BX]-$02
  1039. prfprc2 MOV varspc,AX ;-> memory usage
  1040. INC.B lexnest ;inc nesting
  1041. MOV.B [BP]-$06,#$00
  1042. MOV.B CL,[BP]-$10 ;parameter count
  1043. MOV BX,BP ;pos
  1044. SUB BX,#$10
  1045. prfsto OR.B CL,CL ;all parms done ?
  1046. JZ prfentry ;:yes
  1047. PUSH CX ;save count
  1048. SS:
  1049. MOV BP,[BX]-$02 ;get variable pointer
  1050. PUSH BX ;save current pos
  1051. MOV vartp,BP ;set type ptr
  1052. CALL getvprm2 ;get var parms
  1053. POP BX ;restore pos
  1054. SS:
  1055. MOV CX,[BX]-$04 ;get type
  1056. MOV.B flgvar,CH
  1057. XOR.B CH,CH
  1058. PUSH CX ;save type
  1059. PUSH symtop ;save symtab top
  1060. SUB BX,#$04 ;go down
  1061. prfsto2 MOV BP,symtop ;symtab top
  1062. DEC BP
  1063. DEC BP
  1064. MOV [BP]$00,#$0400 ;store: var
  1065. DEC BX
  1066. DEC BP
  1067. SS:
  1068. MOV.B DL,[BX] ;get length
  1069. MOV.B [BP]$00,DL ;store length
  1070. prfsto3 DEC BX ;go down
  1071. DEC BP
  1072. SS:
  1073. MOV.B AL,[BX] ;get char
  1074. MOV.B [BP]$00,AL ;store it
  1075. DEC.B DL ;another ?
  1076. JNZ prfsto3 ;:yes
  1077. SUB BP,#$06 ;go down
  1078. MOV symtop,BP ;set new symtab top
  1079. CALL symoffs ;write offset
  1080. LOOP prfsto2 ;:another var
  1081. POP BP ;restore pos
  1082. POP CX ;restore count
  1083. PUSH BX
  1084. CALL rdvnrm ;store offset, segment
  1085. CALL tstscal ;scalar var: 2 bytes on stack
  1086. CALL vardef2 ;do var definitions
  1087. POP BX ;restore pos, cnt
  1088. POP CX
  1089. DEC.B CL ;another ?
  1090. JMP prfsto ;'
  1091. prfentry CALL ecode ;emit stack frame code
  1092. B $01,$55 ;* PUSH BP
  1093. CMP.B lexnest,#$01 ;lexical nesting = 1 ?
  1094. JNZ prflong ;:no
  1095. CALL ecode
  1096. B $02,$8B,$EC ;* MOV BP,SP
  1097. JMP.b prfshort ;'
  1098. prflong CALL ecode ;complicated - do display
  1099. B $02,$8B,$C4 ;* MOV AX,SP
  1100. XOR.B CH,CH
  1101. MOV.B CL,lexnest ;lexical nesting -> count
  1102. DEC.B CL
  1103. prfcopy CALL ecode ;* PUSH [BP+..]
  1104. B $02,$FF,$76
  1105. DEC.B CH ;count down two bytes
  1106. DEC.B CH
  1107. MOV.B AL,CH ;offset into display
  1108. CALL ebyte ;emit offset
  1109. DEC.B CL ;another level ?
  1110. JNZ prfcopy ;:no
  1111. CALL ecode
  1112. B $02,$8B,$E8 ;* MOV BP,AX
  1113. prfshort CALL ecode ;now push current display !
  1114. B $01,$55 ;* PUSH BP
  1115. MOV AL,lexnest ;lexical nesting * 2
  1116. XOR.B AH,AH
  1117. ADD AX,AX
  1118. NEG AX
  1119. MOV varspc,AX ;-> stack usage
  1120. PUSH AX
  1121. MOV AL,procfnc ;proc or func ?
  1122. PUSH AX ;save flag
  1123. CALL defpart ;do definition part
  1124. POP AX ;restore... (defs may be recursive)
  1125. MOV procfnc,AL
  1126. POP AX
  1127. SUB AX,varspc ;mem usage - current
  1128. CALL allotstk ;make space on stack
  1129. POP BP ;restore symtab ptr
  1130. PUSH BP
  1131. PUSH [BP]-$0A ;store memory size
  1132. MOV AX,varspc ;memory usage
  1133. NEG AX
  1134. ADD [BP]-$0A,AX ;add to mem size
  1135. CALL errb ;98:Memory overflow
  1136. B $62
  1137. CALL progpart ;do program part
  1138. POP AX ;restore memory size - 4
  1139. SUB AX,#$0004
  1140. CMP.B procfnc,#$06 ;function ?
  1141. JNZ prfret ;:no
  1142. POP BP ;restore symtab pos
  1143. PUSH BP
  1144. PUSH AX ;save mem size
  1145. CALL getvprm ;get var parms
  1146. MOV.B indflg,#$00 ;flag: not indexed
  1147. POP AX ;mem size
  1148. CMP.B varctp,#$09 ;component type = real ?
  1149. JNZ prfstr ;:no
  1150. SUB AX,#$0006 ;6 bytes on stack
  1151. JMP.b prfret ;'
  1152. prfstr CMP.B varctp,#$08 ;string ?
  1153. JNZ prfelse ;:no
  1154. SUB AX,varsize ;- component size -> pos on stack
  1155. CALL emovdxi ;* MOV DX,..
  1156. MOV AX,varsize ;component size: max length - 1
  1157. DEC AX
  1158. MOV.B AH,AL ;max string length
  1159. MOV AL,#$B1 ;* MOV CL,..
  1160. CALL eword
  1161. CALL ecode ;* MOV SP,BP
  1162. B $03,$8B,$E5,$5D ;* POP BP
  1163. MOV AX,#retstr ;* JMP retstr
  1164. CALL ejump
  1165. JMP.b prfret2 ;'
  1166. prfelse PUSH AX ;save pos
  1167. CALL eload ;load var
  1168. POP AX ;restore
  1169. CMP.B varctp,#$0B ;boolean ?
  1170. JNZ prfret ;:no
  1171. CALL ecode ;* OR AX,AX (set flags)
  1172. B $02,$0B,$C0
  1173. prfret CALL ecode ;* MOV SP,BP
  1174. B $03,$8B,$E5,$5D ;* POP BP
  1175. OR AX,AX ;stack frame ?
  1176. JNZ prfretn ;:yes
  1177. CALL ecode ;none:
  1178. B $01,$C3 ;* RET
  1179. JMP.b prfret2 ;'
  1180. prfretn CALL ecode ;remove stack frame
  1181. B $01,$C2 ;* RET ....
  1182. CALL eword ;emit stack frame size
  1183. prfret2 CALL esemi ;! ;
  1184. POP BP ;restore symtab pos
  1185. DEC.B [BP]-$06 ;clear flag
  1186. DEC.B lexnest ;restore lexical nesting
  1187. MOV AX,fence ;fence -> symtab top
  1188. MOV symtop,AX ;= remove all local vars
  1189. MOV symtop2,AX
  1190. POP fence ;restore fence
  1191. POP varspc ;restore mem usage
  1192. RET ;"
  1193. rdextnal PUSH BP ;read external proc
  1194. MOV CX,#$0500 ;tag: procedure
  1195. CALL search
  1196. JZ rdxold ;: found
  1197. MOV CX,#$0600 ;tag: function
  1198. CALL search
  1199. JNZ rdxnew ;:not found
  1200. rdxold PUSH [BP]-$08 ;get offset
  1201. CALL esqr1 ;! [
  1202. CALL rdintcn ;get integer constant
  1203. CALL esqr2 ;! ]
  1204. POP AX ;offset + number
  1205. ADD AX,BX
  1206. JMP.b rdxsto ;'-> offset of this proc
  1207. rdxnew PUSH pc ;save PC
  1208. CALL rdstrcn ;read string constant
  1209. MOV.B BL,CH ;length
  1210. XOR.B BH,BH
  1211. MOV.B [BX]wordbuf,#$00 ;store a 0 at the end
  1212. MOV BX,#wordbuf ;name ptr
  1213. MOV SI,#extcom ;extension .COM
  1214. CALL kextdef ;parse filename
  1215. MOV AX,#$3D00 ;open file
  1216. MOV DX,#scrpn ;name ptr
  1217. PUSH DS ;DS -> ES
  1218. POP ES
  1219. CALL dos ;open it
  1220. CALL errb ;90:File not found
  1221. B $5A
  1222. MOV BX,AX ;file handle
  1223. rdxloop MOV AH,#$3F ;read from file
  1224. MOV CX,#$0080 ;128 bytes
  1225. MOV DX,#wordbuf ;dest buffer
  1226. CALL dos ;do it
  1227. CALL errb ;90:File not found
  1228. B $5A
  1229. XCHG AX,CX ;length read -> CX
  1230. JCXZ rdxend ;0: end
  1231. MOV SI,#wordbuf ;source ptr
  1232. rdxcopy MOV.B AL,[SI] ;get byte from external file
  1233. CALL ebyte ;and emit it
  1234. INC SI ;next one
  1235. LOOP rdxcopy ;:again
  1236. JMP rdxloop ;'try another block
  1237. rdxend MOV AH,#$3E ;close file
  1238. CALL dos
  1239. POP AX ;restore offset
  1240. rdxsto POP BP ;restore symtab pos
  1241. MOV [BP]-$08,AX ;store offset
  1242. JMP esemi ;"! ;
  1243. tstscal CMP.B varctp,#$0A ;scalar var ?
  1244. JB tsc2 ;:no
  1245. MOV varsize,#$0002 ;on stack at least 2 bytes
  1246. tsc2 RET ;"
  1247. resforw MOV BP,symtop ;Resolve forward definitions
  1248. rfwloop CMP BP,fence ;= var fence ?
  1249. JZ rfwret ;yes: end
  1250. ADD BP,[BP]$00 ;go to next entry
  1251. CMP.B [BP]-$01,#$06 ;function ?
  1252. JZ rfwfunc ;:yes
  1253. CMP.B [BP]-$01,#$05 ;procedure ?
  1254. JNZ rfwloop ;:no, next one
  1255. rfwfunc MOV BX,BP ;entry ptr
  1256. SUB BX,#$03
  1257. SS:
  1258. MOV.B AL,[BX] ;length of name
  1259. XOR.B AH,AH
  1260. SUB BX,AX ;go down
  1261. SS:
  1262. CMP.B [BX]-$0F,#$00 ;defined ?
  1263. CALL errnz ;no:
  1264. B $49 ;73:Undefined FORWARD procedure
  1265. JMP rfwloop ;'next one
  1266. rfwret RET ;"
  1267. vardef MOV.B flgvar,#$00 ;define var: clear VAR-flag
  1268. CALL rdvarlst ;get variable list
  1269. PUSH CX ;save counter
  1270. PUSH BP ;save symtab ptr
  1271. CALL ecolon ;! :
  1272. CALL rdvartp ;get type, test absolute
  1273. POP BP ;restore
  1274. POP CX
  1275. vardef2 MOV DX,varsize ;component size
  1276. CMP.B flgvar,#$00 ;VAR-parameter ?
  1277. JZ vdvar ;:no
  1278. MOV DX,#$0004 ;yes: pointer !
  1279. vdvar MOV AX,var3ofs ;var offset
  1280. CMP.B absflg,#$00 ;absolute ?
  1281. JNZ vdstore ;:yes
  1282. CMP.B recnum,#$00 ;record nesting level ?
  1283. JNZ vdrec ;:in record
  1284. CMP.B lexnest,#$00 ;inside procedure ?
  1285. JNZ vdstk ;:yes
  1286. MOV AX,dc ;DC -> offset
  1287. ADD dc,DX ;add size to DC
  1288. CALL errb ;overflow:
  1289. B $62 ;98:Memory overflow
  1290. JMP.b vdstore ;'
  1291. vdstk SUB varspc,DX ;go down (stack !)
  1292. CALL errb ;overflow ?
  1293. B $62 ;98:Memory overflow
  1294. MOV AX,varspc ;get offset
  1295. JMP.b vdstore ;'
  1296. vdrec MOV AX,varspc ;get offset
  1297. ADD varspc,DX ;add to var space
  1298. CALL errb ;overflow ?
  1299. B $62 ;98:memory overflow
  1300. vdstore SUB BP,#$03 ;go down in var list
  1301. MOV.B BL,[BP]$00 ;get length
  1302. XOR.B BH,BH
  1303. SUB BP,BX ;go down
  1304. MOV [BP]-$04,AX ;store offset
  1305. MOV AX,var3seg ;store segment
  1306. MOV [BP]-$06,AX
  1307. MOV AX,vartp ;store type ptr
  1308. MOV [BP]-$02,AX
  1309. SUB BP,#$08 ;make space
  1310. LOOP vdvar ;another definition ?
  1311. JMP chkovrfl ;"test for overflow
  1312. rdvarlst PUSH symtop ;get variable list
  1313. XOR CX,CX ;clear counter
  1314. rdvloop PUSH CX ;save
  1315. MOV AH,#$04 ;tag: var, record nesting
  1316. MOV AL,recnum
  1317. CALL symword ;store in symtab
  1318. CALL rdsym ;store name in symtab
  1319. SUB symtop,#$06 ;reserve some space
  1320. CALL symoffs ;write symtab offset
  1321. POP CX ;restore counters
  1322. INC CX
  1323. CALL ccomma ;, ?
  1324. JZ rdvloop ;yes: next var
  1325. POP BP ;restore symtab pos
  1326. RET ;"(beginning of list)
  1327. rdvartp PUSH symtop ;get var type, test ABSOLUTE
  1328. CALL rdtype ;read type
  1329. POP tyfence ;symtab top -> type fence
  1330. CALL resptr ;fill in pointer types
  1331. CALL ctoken ;ABSOLUTE ?
  1332. W tkabs
  1333. JNZ rdvnrm ;:no
  1334. MOV.B absflg,#$FF ;set flag
  1335. CMP.B recnum,#$00 ;in record ?
  1336. CALL errnz ;yes:
  1337. B $4B ;75:Illegal use of ABSOLUTE
  1338. MOV CX,#$0400 ;search var
  1339. CALL search
  1340. JNZ rdvabs ;:not found
  1341. MOV AX,[BP]-$06 ;get offset
  1342. MOV DX,[BP]-$04 ;get segment
  1343. JMP.b rdvofs ;'store parms
  1344. rdvabs CALL rdconst ;read constant -> segment
  1345. JNZ rdvseg ;:no good
  1346. CALL testint ;test type: integer
  1347. PUSH BX ;save segment
  1348. CALL ecolon ;! :
  1349. CALL rdintcn ;get integer constant
  1350. MOV DX,pc ;get PC: pos of pointer
  1351. XCHG AX,BX
  1352. CALL eword ;emit result = offset
  1353. POP AX ;emit segment
  1354. CALL eword
  1355. MOV AX,#$FEFF ;flag: CS indirect
  1356. JMP.b rdvofs ;'
  1357. rdvseg CALL ctoken ;DSEG ?
  1358. W tkdseg
  1359. MOV AX,#$FF00 ;flag: DS
  1360. JZ rdvseg2 ;:yes
  1361. CALL ctoken ;CSEG ?
  1362. W tkcseg
  1363. MOV AX,#$FE00 ;flag: CS
  1364. JZ rdvseg2 ;:yes
  1365. JMP snerror ;'Unknown ID or syntax error
  1366. rdvseg2 PUSH AX ;save segment flag
  1367. CALL ecolon ;! :
  1368. CALL rdintcn ;get integer constant
  1369. POP AX ;restore segment
  1370. MOV DX,BX ;offset -> DX
  1371. rdvofs MOV var3ofs,DX
  1372. JMP.b rdvsto ;'
  1373. rdvnrm MOV.B absflg,#$00 ;clear absolute flag
  1374. MOV AL,flgvar ;VAR-parameter ?
  1375. MOV.B AH,lexnest ;lexical nesting
  1376. OR.B AH,AH ;inside proc ?
  1377. JNZ rdvofs ;:yes, use stack segment
  1378. MOV AH,#$FF ;data segment
  1379. rdvsto MOV var3seg,AX ;store segment
  1380. RET ;"
  1381. testtp CALL srchtype ;Test file type: search type
  1382. JZ ttpsto ;:found
  1383. CALL ctoken ;TEXT ?
  1384. W tktext
  1385. JNZ ttpnotxt ;:no
  1386. CALL textstd ;get ptr to that type
  1387. JMP.b ttpsto ;'
  1388. ttpnotxt CALL ctoken ;FILE ?
  1389. W tkfile
  1390. CALL errnz ;no:
  1391. B $24 ;36:Type ID expected
  1392. CALL filuntp ;point to typed/untyped file
  1393. ttpsto CMP.B flgvar,#$00 ;VAR-parameter ?
  1394. JNZ rdvnrm ;yes: ok
  1395. CMP.B varctp,#$05 ;typed file ?
  1396. JB rdvnrm ;:below
  1397. CMP.B varctp,#$07 ;above file ?
  1398. JA rdvnrm ;yes: ok
  1399. CALL err
  1400. B $43 ;"67:Files must be VAR parameters
  1401. resptr MOV BP,symtop ;Fill in pointer types
  1402. rptlp CMP BP,tyfence ;= type fence ?
  1403. JZ rptret ;yes: done
  1404. ADD BP,[BP]$00 ;go to next var
  1405. CMP.B [BP]-$01,#$08 ;subtype ?
  1406. JNZ rptlp ;no: next one
  1407. MOV.B [BP]-$01,#$00 ;make it invisible
  1408. CMP.B [BP]-$0A,#$04 ;pointer ?
  1409. JNZ rptlp ;no: next one
  1410. CMP.B [BP]-$09,#$00 ;filled in ?
  1411. JZ rptlp ;:yes
  1412. MOV.B [BP]-$09,#$00 ;flag: filled in
  1413. MOV BX,[BP]-$08 ;get pos of type name
  1414. SS:
  1415. MOV.B DL,[BX]-$01 ;name length
  1416. XOR.B DH,DH
  1417. INC DX ;-> count
  1418. PUSH BP ;save pos
  1419. MOV BP,symtop ;search from top
  1420. rptsrch CMP BP,ptcbeg ;bottom of symbol table ?
  1421. JZ rpterr ;yes: error
  1422. ADD BP,[BP]$00 ;go to next var
  1423. CMP.B [BP]-$01,#$03 ;type ?
  1424. JNZ rptsrch ;:no, search next
  1425. MOV SI,BP ;pointer
  1426. DEC SI
  1427. DEC SI
  1428. MOV DI,BX ;pos of searched string
  1429. MOV CX,DX ;len -> count
  1430. rptcmp DEC SI ;go back
  1431. DEC DI
  1432. SS:
  1433. MOV.B AL,[SI] ;compare chars
  1434. SS:
  1435. CMP.B AL,[DI]
  1436. JNZ rptsrch ;:not the right one
  1437. LOOP rptcmp ;:test another char
  1438. POP BP ;restore symtab pos
  1439. SS:
  1440. MOV AX,[SI]-$02 ;get type pointer
  1441. MOV [BP]-$08,AX ;store into pointer entry
  1442. JMP rptlp ;'next one
  1443. rptret RET ;'
  1444. rpterr CALL err ;42:Undefd ptr type in preceding
  1445. B $2A ;"type defs
  1446. rdtype CALL srchtype ;get type: search type ID
  1447. JZ rdtpret ;found: ret
  1448. CALL ctoken ;PACKED ?
  1449. W tkpacked ;(ignored)
  1450. CALL array ;array ?
  1451. JZ rdtpret ;:done
  1452. CALL record ;record ?
  1453. JZ rdtpret ;:done
  1454. CALL set ;set ?
  1455. JZ rdtpret ;:done
  1456. CALL pointer ;pointer ?
  1457. JZ rdtpret ;:done
  1458. CALL file ;file ?
  1459. JZ rdtpret ;:done
  1460. CALL text ;text ?
  1461. JZ rdtpret ;:done
  1462. CALL string ;string ?
  1463. JZ rdtpret ;:done
  1464. CALL scalar ;scalar list ?
  1465. JZ rdtpret ;:done
  1466. CALL subrange ;subrange ?
  1467. JZ rdtpret ;:done
  1468. CALL err ;36:Type identifier expected
  1469. B $24 ;'
  1470. rdtpret RET ;"
  1471. srchtype MOV CX,#$0300 ;search type
  1472. CALL search
  1473. JNZ srtret ;:not found - ret
  1474. MOV BP,[BP]-$02 ;type pointer
  1475. stdtype MOV vartp,BP ;store it
  1476. CALL getvprm2 ;get type parms
  1477. XOR AX,AX ;ok
  1478. srtret RET ;"
  1479. array CALL ctoken ;ARRAY ?
  1480. W tkarray
  1481. JNZ arret ;:no
  1482. CALL esqr1 ;! [
  1483. XOR CX,CX ;clear dimension count
  1484. arrlp PUSH CX ;save
  1485. CALL rdscaltp ;get scalar type
  1486. POP CX
  1487. PUSH vartp ;save type pointer: index type
  1488. MOV AX,upper ;upper bound - lower bound
  1489. SUB AX,lower
  1490. INC AX ;+ 1
  1491. CALL errz ;98:Memory overflow
  1492. B $62
  1493. PUSH AX ;save component count
  1494. INC CX ;count dimensions
  1495. CALL ccomma ;, ?
  1496. JZ arrlp ;yes: another dimension
  1497. PUSH CX ;save dim count
  1498. CALL esqr2 ;! ]
  1499. CALL expof ;! OF
  1500. CALL rdtype ;get type
  1501. POP CX ;dim count
  1502. arrlp2 MOV AX,vartp ;type ptr
  1503. MOV lower,AX ;-> type
  1504. MOV AX,varsize ;component size
  1505. POP BX ;* component count
  1506. MUL BX
  1507. CALL errb ;too much ?
  1508. B $62 ;98:Memory overflow
  1509. MOV varsize,AX ;-> component size
  1510. POP AX ;index type
  1511. MOV upper,AX ;store it
  1512. MOV.B varctp,#$01 ;tag: array
  1513. CALL stotype ;store type
  1514. LOOP arrlp2 ;:another dimension
  1515. arret RET ;"
  1516. record CALL ctoken ;RECORD ?
  1517. W tkrec
  1518. JNZ recret ;no: ret
  1519. MOV AL,vrecflg ;save variant rec nesting
  1520. PUSH AX
  1521. MOV AL,recnum ;save rec nesting
  1522. PUSH AX
  1523. INC.B reccnt ;one more level
  1524. MOV AL,reccnt ;record counter
  1525. MOV recnum,AL ;-> record number
  1526. PUSH varspc ;save space used
  1527. PUSH maxsize ;save max size of variant rec
  1528. MOV varspc,#$0000 ;clear them
  1529. MOV maxsize,#$0000
  1530. MOV.B vrecflg,#$00 ;no variant record
  1531. CALL recdef ;do record definition
  1532. MOV AX,maxsize ;max component size
  1533. MOV varsize,AX ;-> variable size
  1534. POP maxsize ;restore vars
  1535. POP varspc
  1536. MOV AL,recnum ;record number
  1537. MOV varnest,AL ;-> subtype
  1538. POP AX
  1539. MOV recnum,AL
  1540. POP AX
  1541. MOV vrecflg,AL
  1542. MOV.B varctp,#$02 ;type: record
  1543. CALL stotype ;store type
  1544. recret RET ;"
  1545. recdef CALL rectest ;do record def: test end
  1546. JZ rcdret ;yes: ret
  1547. CALL ctoken ;CASE ?
  1548. W tkcase
  1549. JZ rcdvrec ;:yes
  1550. CALL vardef ;define variables
  1551. MOV AX,varspc ;memory used
  1552. CMP AX,maxsize ;>= max size ?
  1553. JB rcdsmall ;below: forget
  1554. MOV maxsize,AX ;store as new max size
  1555. rcdsmall CALL csemi ;semicolon ?
  1556. JZ recdef ;yes: loop back
  1557. JMP.b rcde ;'end it
  1558. rcdvrec CALL srchtype ;variant record: search type
  1559. JZ rcdnotag ;:found
  1560. CALL vardef ;define var: tag field
  1561. rcdnotag CALL expof ;! OF
  1562. rcdvlp CALL rectest ;test for end
  1563. JZ rcdret ;yes: ret
  1564. PUSH varspc ;save mem used
  1565. rcdtag CALL rdnumcn ;get constant
  1566. CALL ccomma ;, ?
  1567. JZ rcdtag ;:another constant
  1568. CALL ecolon ;! :
  1569. CALL ebrack1 ;! (
  1570. MOV AL,vrecflg ;save variant rec flag
  1571. PUSH AX
  1572. MOV.B vrecflg,#$FF ;set it
  1573. CALL recdef ;do type definition list
  1574. POP AX ;restore flag
  1575. MOV vrecflg,AL
  1576. POP varspc ;restore memory used
  1577. CALL csemi ;semicolon ?
  1578. JZ rcdvlp ;yes: another
  1579. rcde CMP.B vrecflg,#$00 ;variant record ?
  1580. JZ rcde1 ;:no
  1581. JMP ebrack2 ;'! )
  1582. rcde1 CALL ctoken ;END ?
  1583. W tkend
  1584. CALL errnz ;no:
  1585. B $0E ;14:END expected
  1586. rcdret RET ;"
  1587. rectest CMP.B vrecflg,#$00 ;test end
  1588. JZ rectest2 ;:normal rec
  1589. JMP cbrack2 ;'in variant rec: ) ?
  1590. rectest2 CALL ctoken ;END ?
  1591. W tkend
  1592. RET ;"
  1593. set CALL ctoken ;SET ?
  1594. W tkset
  1595. JNZ setret ;no: ret
  1596. CALL expof ;! OF
  1597. CALL rdscaltp ;get scalar type
  1598. MOV AX,upper ;upper bound
  1599. MOV BX,lower ;lower bound
  1600. MOV.B CL,AH ;one of them > 255 ?