CPM.txt 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. MODULE LindevCPM;
  2. (* THIS IS TEXT COPY OF CPM.odc *)
  3. (* DO NOT EDIT *)
  4. IMPORT SYSTEM, Kernel, Files (* , Stores, Models, Views, TextModels, TextMappers, StdLog, DevMarkers *);
  5. CONST
  6. ProcSize* = 4; (* PROCEDURE type *)
  7. PointerSize* = 4; (* POINTER type *)
  8. DArrSizeA* = 8; (* dyn array descriptor *)
  9. DArrSizeB* = 4; (* size = A + B * typ.n *)
  10. MaxSet* = 31;
  11. MaxIndex* = 7FFFFFFFH; (* maximal index value for array declaration *)
  12. MinReal32Pat = 0FF7FFFFFH; (* most positive, 32-bit pattern *)
  13. MinReal64PatL = 0FFFFFFFFH; (* most negative, lower 32-bit pattern *)
  14. MinReal64PatH = 0FFEFFFFFH; (* most negative, higher 32-bit pattern *)
  15. MaxReal32Pat = 07F7FFFFFH; (* most positive, 32-bit pattern *)
  16. MaxReal64PatL = 0FFFFFFFFH; (* most positive, lower 32-bit pattern *)
  17. MaxReal64PatH = 07FEFFFFFH; (* most positive, higher 32-bit pattern *)
  18. InfRealPat = 07F800000H; (* real infinity pattern *)
  19. (* inclusive range of parameter of standard procedure HALT *)
  20. MinHaltNr* = 0;
  21. MaxHaltNr* = 128;
  22. (* inclusive range of register number of procedures SYSTEM.GETREG and SYSTEM.PUTREG *)
  23. MinRegNr* = 0;
  24. MaxRegNr* = 31;
  25. (* maximal value of flag used to mark interface structures *)
  26. MaxSysFlag* = 127; (* shortint *)
  27. CProcFlag* = 1; (* code procedures *)
  28. (* maximal condition value of parameter of SYSTEM.CC *)
  29. MaxCC* = 15;
  30. (* initialization of constant address, must be different from any valid constant address *)
  31. ConstNotAlloc* = -1;
  32. (* whether hidden pointer fields have to be nevertheless exported *)
  33. ExpHdPtrFld* = TRUE;
  34. HdPtrName* = "@ptr";
  35. (* whether hidden untagged pointer fields have to be nevertheless exported *)
  36. ExpHdUtPtrFld* = TRUE;
  37. HdUtPtrName* = "@utptr";
  38. (* whether hidden procedure fields have to be nevertheless exported (may be used for System.Free) *)
  39. ExpHdProcFld* = TRUE;
  40. HdProcName* = "@proc";
  41. (* whether hidden bound procedures have to be nevertheless exported *)
  42. ExpHdTProc* = FALSE;
  43. HdTProcName* = "@tproc";
  44. (* maximal number of exported stuctures: *)
  45. MaxStruct* = 16000; (* must be < MAX(INTEGER) DIV 2 in object model *)
  46. (* maximal number of record extensions: *)
  47. MaxExts* = 15; (* defined by type descriptor layout *)
  48. (* whether field leaf of pointer variable p has to be set to FALSE, when NEW(p) or SYSTEM.NEW(p, n) is used *)
  49. NEWusingAdr* = FALSE;
  50. (* special character (< " ") returned by procedure Get, if end of text reached *)
  51. Eot* = 0X;
  52. (* warnings *)
  53. longreal* = 0; largeint* = 1; realConst* = 2; copy* = 3; lchr* = 4; lentier* = 5; invar* = 6; outvar* = 7;
  54. (* language options *)
  55. interface* = 1;
  56. com* = 2; comAware* = 3;
  57. som* = 4; somAware* = 5;
  58. oberon* = 6;
  59. java* = 7; javaAware* = 8;
  60. noCode* = 9;
  61. allSysVal* = 14;
  62. sysImp* = 15;
  63. trap* = 31;
  64. sys386 = 10; sys68k = 20; (* processor type in options if system imported *)
  65. CONST
  66. SFdir = "Sym";
  67. OFdir = "Code";
  68. SYSdir = "System";
  69. SFtag = 6F4F5346H; (* symbol file tag *)
  70. OFtag = 6F4F4346H; (* object file tag *)
  71. maxErrors = 64;
  72. TYPE
  73. File = POINTER TO RECORD next: File; f: Files.File END;
  74. VAR
  75. LEHost*: BOOLEAN; (* little or big endian host *)
  76. MinReal32*, MaxReal32*, InfReal*,
  77. MinReal64*, MaxReal64*: REAL;
  78. noerr*: BOOLEAN; (* no error found until now *)
  79. curpos*, startpos*, errpos*: INTEGER; (* character, start, and error position in source file *)
  80. searchpos*: INTEGER; (* search position in source file *)
  81. errors*: INTEGER;
  82. breakpc*: INTEGER; (* set by OPV.Init *)
  83. options*: SET; (* language options *)
  84. file*: Files.File; (* used for sym file import *)
  85. codeDir*: ARRAY 16 OF CHAR;
  86. symDir*: ARRAY 16 OF CHAR;
  87. checksum*: INTEGER; (* symbol file checksum *)
  88. errorMes*: ARRAY 4096 OF CHAR;
  89. lastpos: INTEGER;
  90. realpat: INTEGER;
  91. lrealpat: RECORD H, L: INTEGER END;
  92. fpi, fpj: SHORTINT; fp: ARRAY 4 OF SHORTCHAR;
  93. ObjFName: Files.Name;
  94. in: Files.Reader;
  95. oldSymFile, symFile, objFile: Files.File;
  96. inSym: Files.Reader;
  97. outSym, outObj: Files.Writer;
  98. errNo-, errPos-: ARRAY maxErrors OF INTEGER;
  99. lineReader: Files.Reader;
  100. lineNum: INTEGER;
  101. crc32tab: ARRAY 256 OF INTEGER;
  102. PROCEDURE^ err* (n: INTEGER);
  103. PROCEDURE Init* (source: Files.Reader);
  104. BEGIN
  105. in := source;
  106. noerr := TRUE; options := {};
  107. curpos := in.Pos(); errpos := curpos; lastpos := curpos - 11; errors := 0;
  108. codeDir := OFdir; symDir := SFdir;
  109. errorMes := ""
  110. END Init;
  111. PROCEDURE Close*;
  112. BEGIN
  113. oldSymFile := NIL; inSym := NIL;
  114. symFile := NIL; outSym := NIL;
  115. objFile := NIL; outObj := NIL;
  116. in := NIL; lineReader := NIL
  117. END Close;
  118. PROCEDURE Get* (VAR ch: SHORTCHAR);
  119. VAR
  120. ch1: BYTE;
  121. BEGIN
  122. REPEAT
  123. in.ReadByte(ch1);
  124. ch := SYSTEM.VAL(SHORTCHAR, ch1);
  125. INC(curpos)
  126. UNTIL (ch < 100X)
  127. END Get;
  128. PROCEDURE GetL* (VAR ch: CHAR);
  129. VAR
  130. sCh: SHORTCHAR;
  131. BEGIN
  132. Get(sCh);
  133. ch := sCh
  134. END GetL;
  135. (*
  136. PROCEDURE LineOf* (pos: INTEGER): INTEGER;
  137. VAR ch: CHAR;
  138. BEGIN
  139. IF lineReader = NIL THEN lineReader := in.Base().NewReader(NIL); lineReader.SetPos(0); lineNum := 0 END;
  140. IF lineReader.Pos() > pos THEN lineReader.SetPos(0); lineNum := 0 END;
  141. WHILE lineReader.Pos() < pos DO
  142. lineReader.ReadChar(ch);
  143. IF ch = 0DX THEN INC(lineNum) END
  144. END;
  145. RETURN lineNum
  146. END LineOf;
  147. *)
  148. PROCEDURE LoWord (r: REAL): INTEGER;
  149. VAR x: INTEGER;
  150. BEGIN
  151. x := SYSTEM.ADR(r);
  152. IF ~LEHost THEN INC(x, 4) END;
  153. SYSTEM.GET(x, x);
  154. RETURN x
  155. END LoWord;
  156. PROCEDURE HiWord (r: REAL): INTEGER;
  157. VAR x: INTEGER;
  158. BEGIN
  159. x := SYSTEM.ADR(r);
  160. IF LEHost THEN INC(x, 4) END;
  161. SYSTEM.GET(x, x);
  162. RETURN x
  163. END HiWord;
  164. PROCEDURE Compound (lo, hi: INTEGER): REAL;
  165. VAR r: REAL;
  166. BEGIN
  167. IF LEHost THEN
  168. SYSTEM.PUT(SYSTEM.ADR(r), lo); SYSTEM.PUT(SYSTEM.ADR(r) + 4, hi)
  169. ELSE
  170. SYSTEM.PUT(SYSTEM.ADR(r) + 4, lo); SYSTEM.PUT(SYSTEM.ADR(r), hi)
  171. END;
  172. RETURN r
  173. END Compound;
  174. (* sysflag control *)
  175. PROCEDURE ValidGuid* (VAR str: ARRAY OF SHORTCHAR): BOOLEAN;
  176. VAR i: SHORTINT; ch: SHORTCHAR;
  177. BEGIN
  178. IF (LEN(str$) # 38) OR (str[0] # "{") & (str[37] # "}") THEN RETURN FALSE END;
  179. i := 1;
  180. WHILE i < 37 DO
  181. ch := str[i];
  182. IF (i = 9) OR (i = 14) OR (i = 19) OR (i = 24) THEN
  183. IF ch # "-" THEN RETURN FALSE END
  184. ELSE
  185. IF (ch < "0") OR (ch > "9") & (CAP(ch) < "A") OR (CAP(ch) > "Z") THEN RETURN FALSE END
  186. END;
  187. INC(i)
  188. END;
  189. RETURN TRUE
  190. END ValidGuid;
  191. PROCEDURE GetProcSysFlag* (id: ARRAY OF SHORTCHAR; num: SHORTINT; VAR flag: SHORTINT);
  192. BEGIN
  193. IF id # "" THEN
  194. IF id = "code" THEN num := 1
  195. ELSIF id = "callback" THEN num := 2
  196. ELSIF id = "nostkchk" THEN num := 4
  197. ELSIF id = "ccall" THEN num := -10
  198. ELSIF id = "guarded" THEN num := 8
  199. ELSIF id = "noframe" THEN num := 16
  200. ELSIF id = "native" THEN num := -33
  201. ELSIF id = "bytecode" THEN num := -35
  202. END
  203. END;
  204. IF (options * {sysImp, sys386, sys68k} # {}) & ((num = 1) OR (num = 2)) THEN INC(flag, num)
  205. ELSIF (sys68k IN options) & (num = 4) THEN INC(flag, num)
  206. ELSIF (options * {sys386, interface} # {}) & (num = -10) & (flag = 0) THEN flag := -10
  207. ELSIF (options * {sys386, com} # {}) & (num = 8) & (flag = 0) THEN flag := 8
  208. ELSIF (options * {sysImp, sys386} # {}) & (num = 16) & (flag = 0) THEN flag := 16
  209. ELSIF ({sysImp, java} - options = {}) & ((num= -33) OR (num = -35)) & (flag = 0) THEN flag := num
  210. ELSE err(225); flag := 0
  211. END
  212. END GetProcSysFlag;
  213. PROCEDURE GetVarParSysFlag* (id: ARRAY OF SHORTCHAR; num: SHORTINT; VAR flag: SHORTINT);
  214. VAR old: SHORTINT;
  215. BEGIN
  216. old := flag; flag := 0;
  217. IF (options * {sys386, sys68k, interface, com} # {}) THEN
  218. IF (num = 1) OR (id = "nil") THEN
  219. IF ~ODD(old) THEN flag := SHORT(old + 1) END
  220. ELSIF ((num = 2) OR (id = "in")) & (oberon IN options) THEN
  221. IF old <= 1 THEN flag := SHORT(old + 2) END
  222. ELSIF ((num = 4) OR (id = "out")) & (oberon IN options) THEN
  223. IF old <= 1 THEN flag := SHORT(old + 4) END
  224. ELSIF ((num = 8) OR (id = "new")) & (options * {com, interface} # {}) THEN
  225. IF old <= 1 THEN flag := SHORT(old + 8) END
  226. ELSIF ((num = 16) OR (id = "iid")) & (com IN options) THEN
  227. IF old <= 1 THEN flag := SHORT(old + 16) END
  228. END
  229. END;
  230. IF flag = 0 THEN err(225) END
  231. END GetVarParSysFlag;
  232. PROCEDURE GetRecordSysFlag* (id: ARRAY OF SHORTCHAR; num: SHORTINT; VAR flag: SHORTINT);
  233. VAR old: SHORTINT;
  234. BEGIN
  235. old := flag; flag := 0;
  236. IF (num = 1) OR (id = "untagged") THEN
  237. IF (options * {sysImp, sys386, sys68k, interface, com, som} # {}) & (old = 0) THEN flag := 1 END
  238. ELSIF (num = 3) OR (id = "noalign") THEN
  239. IF (options * {sys386, sys68k, interface, com, som} # {}) & (old = 0) THEN flag := 3 END
  240. ELSIF (num = 4) OR (id = "align2") THEN
  241. IF (options * {sys386, interface, com} # {}) & (old = 0) THEN flag := 4 END
  242. ELSIF (num = 5) OR (id = "align4") THEN
  243. IF (options * {sys386, interface, com} # {}) & (old = 0) THEN flag := 5 END
  244. ELSIF (num = 6) OR (id = "align8") THEN
  245. IF (options * {sys386, interface, com} # {}) & (old = 0) THEN flag := 6 END
  246. ELSIF (num = 7) OR (id = "union") THEN
  247. IF (options * {sys386, sys68k, interface, com} # {}) & (old = 0) THEN flag := 7 END
  248. ELSIF (num = 10) OR (id = "interface") OR ValidGuid(id) THEN
  249. IF (com IN options) & (old = 0) THEN flag := 10 END
  250. ELSIF (num = -11) OR (id = "jint") THEN
  251. IF (java IN options) & (old = 0) THEN flag := -11 END
  252. ELSIF (num = -13) OR (id = "jstr") THEN
  253. IF (java IN options) & (old = 0) THEN flag := -13 END
  254. ELSIF (num = 20) OR (id = "som") THEN
  255. IF (som IN options) & (old = 0) THEN flag := 20 END
  256. END;
  257. IF flag = 0 THEN err(225) END
  258. END GetRecordSysFlag;
  259. PROCEDURE GetArraySysFlag* (id: ARRAY OF SHORTCHAR; num: SHORTINT; VAR flag: SHORTINT);
  260. VAR old: SHORTINT;
  261. BEGIN
  262. old := flag; flag := 0;
  263. IF (num = 1) OR (id = "untagged") THEN
  264. IF (options * {sysImp, sys386, sys68k, interface, com, som} # {}) & (old = 0) THEN flag := 1 END
  265. ELSIF (num = -12) OR (id = "jarr") THEN
  266. IF (java IN options) & (old = 0) THEN flag := -12 END
  267. ELSIF (num = -13) OR (id = "jstr") THEN
  268. IF (java IN options) & (old = 0) THEN flag := -13 END
  269. END;
  270. IF flag = 0 THEN err(225) END
  271. END GetArraySysFlag;
  272. PROCEDURE GetPointerSysFlag* (id: ARRAY OF SHORTCHAR; num: SHORTINT; VAR flag: SHORTINT);
  273. VAR old: SHORTINT;
  274. BEGIN
  275. old := flag; flag := 0;
  276. IF (num = 1) OR (id = "untagged") THEN
  277. IF (options * {sys386, sys68k, interface, com, som} # {}) & (old = 0) THEN flag := 1 END
  278. ELSIF (num = 2) OR (id = "handle") THEN
  279. IF (sys68k IN options) & (old = 0) THEN flag := 2 END
  280. ELSIF (num = 10) OR (id = "interface") THEN
  281. IF (com IN options) & (old = 0) THEN flag := 10 END
  282. ELSIF (num = 20) OR (id = "som") THEN
  283. IF (som IN options) & (old = 0) THEN flag := 20 END
  284. END;
  285. IF flag = 0 THEN err(225) END
  286. END GetPointerSysFlag;
  287. PROCEDURE GetProcTypSysFlag* (id: ARRAY OF SHORTCHAR; num: SHORTINT; VAR flag: SHORTINT);
  288. BEGIN
  289. IF ((num = -10) OR (id = "ccall")) & (options * {sys386, interface} # {}) THEN flag := -10
  290. ELSE err(225); flag := 0
  291. END
  292. END GetProcTypSysFlag;
  293. PROCEDURE PropagateRecordSysFlag* (baseFlag: SHORTINT; VAR flag: SHORTINT);
  294. BEGIN
  295. IF (baseFlag = 1) OR (baseFlag >= 3) & (baseFlag <= 7) THEN (* propagate untagged .. union *)
  296. IF flag = 0 THEN flag := baseFlag
  297. ELSIF (flag = 6) & (baseFlag < 6) THEN (* OK *) (* special case for 8 byte aligned records *)
  298. ELSIF flag # baseFlag THEN err(225); flag := 0
  299. END
  300. ELSIF (baseFlag # 10) & (flag = 10) THEN err(225)
  301. END
  302. END PropagateRecordSysFlag;
  303. PROCEDURE PropagateRecPtrSysFlag* (baseFlag: SHORTINT; VAR flag: SHORTINT);
  304. BEGIN
  305. IF (baseFlag = 1) OR (baseFlag >= 3) & (baseFlag <= 7) THEN (* pointer to untagged .. union is untagged *)
  306. IF flag = 0 THEN flag := 1
  307. ELSIF (flag # 1) & (flag # 2) THEN err(225); flag := 0
  308. END
  309. ELSIF baseFlag = 10 THEN (* pointer to interface is interface *)
  310. IF flag = 0 THEN flag := 10
  311. ELSIF flag # 10 THEN err(225); flag := 0
  312. END
  313. ELSIF baseFlag = -11 THEN (* pointer to java interface is java interface *)
  314. IF flag # 0 THEN err(225) END;
  315. flag := -11
  316. ELSIF baseFlag = -13 THEN (* pointer to java string is java string *)
  317. IF flag # 0 THEN err(225) END;
  318. flag := -13
  319. END
  320. END PropagateRecPtrSysFlag;
  321. PROCEDURE PropagateArrPtrSysFlag* (baseFlag: SHORTINT; VAR flag: SHORTINT);
  322. BEGIN
  323. IF baseFlag = 1 THEN (* pointer to untagged or guid is untagged *)
  324. IF flag = 0 THEN flag := 1
  325. ELSIF (flag # 1) & (flag # 2) THEN err(225); flag := 0
  326. END
  327. ELSIF baseFlag = -12 THEN (* pointer to java array is java array *)
  328. IF flag # 0 THEN err(225) END;
  329. flag := -12
  330. ELSIF baseFlag = -13 THEN (* pointer to java string is java string *)
  331. IF flag # 0 THEN err(225) END;
  332. flag := -13
  333. END
  334. END PropagateArrPtrSysFlag;
  335. (* utf8 strings *)
  336. PROCEDURE PutUtf8* (VAR str: ARRAY OF SHORTCHAR; val: INTEGER; VAR idx: INTEGER);
  337. BEGIN
  338. ASSERT((val >= 0) & (val < 65536));
  339. IF val < 128 THEN
  340. str[idx] := SHORT(CHR(val)); INC(idx)
  341. ELSIF val < 2048 THEN
  342. str[idx] := SHORT(CHR(val DIV 64 + 192)); INC(idx);
  343. str[idx] := SHORT(CHR(val MOD 64 + 128)); INC(idx)
  344. ELSE
  345. str[idx] := SHORT(CHR(val DIV 4096 + 224)); INC(idx);
  346. str[idx] := SHORT(CHR(val DIV 64 MOD 64 + 128)); INC(idx);
  347. str[idx] := SHORT(CHR(val MOD 64 + 128)); INC(idx)
  348. END
  349. END PutUtf8;
  350. PROCEDURE GetUtf8* (VAR str: ARRAY OF SHORTCHAR; VAR val, idx: INTEGER);
  351. VAR ch: SHORTCHAR;
  352. BEGIN
  353. ch := str[idx]; INC(idx);
  354. IF ch < 80X THEN
  355. val := ORD(ch)
  356. ELSIF ch < 0E0X THEN
  357. val := ORD(ch) - 192;
  358. ch := str[idx]; INC(idx); val := val * 64 + ORD(ch) - 128
  359. ELSE
  360. val := ORD(ch) - 224;
  361. ch := str[idx]; INC(idx); val := val * 64 + ORD(ch) - 128;
  362. ch := str[idx]; INC(idx); val := val * 64 + ORD(ch) - 128
  363. END
  364. END GetUtf8;
  365. PROCEDURE Mark* (n, pos: INTEGER);
  366. BEGIN
  367. IF (n >= 0) & ~((oberon IN options) & (n >= 181) & (n <= 190)) THEN
  368. noerr := FALSE;
  369. IF pos < 0 THEN pos := 0 END;
  370. IF (pos < lastpos) OR (lastpos + 9 < pos) THEN
  371. lastpos := pos;
  372. IF errors < maxErrors THEN
  373. errNo[errors] := n; errPos[errors] := pos
  374. END;
  375. INC(errors)
  376. END;
  377. IF trap IN options THEN HALT(100) END;
  378. ELSIF (n <= -700) & (errors < maxErrors) THEN
  379. errNo[errors] := -n; errPos[errors] := pos; INC(errors)
  380. END
  381. END Mark;
  382. PROCEDURE err* (n: INTEGER);
  383. BEGIN
  384. Mark(n, errpos)
  385. END err;
  386. (* fingerprinting *)
  387. PROCEDURE InitCrcTab;
  388. (* CRC32, high bit first, pre & post inverted *)
  389. CONST poly = {0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26}; (* CRC32 polynom *)
  390. VAR x, c, i: INTEGER;
  391. BEGIN
  392. x := 0;
  393. WHILE x < 256 DO
  394. c := x * 1000000H; i := 0;
  395. WHILE i < 8 DO
  396. IF c < 0 THEN c := ORD(BITS(c * 2) / poly)
  397. ELSE c := c * 2
  398. END;
  399. INC(i)
  400. END;
  401. crc32tab[ORD(BITS(x) / BITS(255))] := ORD(BITS(c) / BITS(255));
  402. INC(x)
  403. END
  404. END InitCrcTab;
  405. PROCEDURE FPrint* (VAR fp: INTEGER; val: INTEGER);
  406. VAR c: INTEGER;
  407. BEGIN
  408. (*
  409. fp := SYSTEM.ROT(ORD(BITS(fp) / BITS(val)), 1) (* bad collision detection *)
  410. *)
  411. (* CRC32, high bit first, pre & post inverted *)
  412. c := ORD(BITS(fp * 256) / BITS(crc32tab[ORD(BITS(fp DIV 1000000H) / BITS(val DIV 1000000H)) MOD 256]));
  413. c := ORD(BITS(c * 256) / BITS(crc32tab[ORD(BITS(c DIV 1000000H) / BITS(val DIV 10000H)) MOD 256]));
  414. c := ORD(BITS(c * 256) / BITS(crc32tab[ORD(BITS(c DIV 1000000H) / BITS(val DIV 100H)) MOD 256]));
  415. fp := ORD(BITS(c * 256) / BITS(crc32tab[ORD(BITS(c DIV 1000000H) / BITS(val)) MOD 256]));
  416. END FPrint;
  417. PROCEDURE FPrintSet* (VAR fp: INTEGER; set: SET);
  418. BEGIN FPrint(fp, ORD(set))
  419. END FPrintSet;
  420. PROCEDURE FPrintReal* (VAR fp: INTEGER; real: SHORTREAL);
  421. BEGIN FPrint(fp, SYSTEM.VAL(INTEGER, real))
  422. END FPrintReal;
  423. PROCEDURE FPrintLReal* (VAR fp: INTEGER; lr: REAL);
  424. VAR l, h: INTEGER;
  425. BEGIN
  426. FPrint(fp, LoWord(lr)); FPrint(fp, HiWord(lr))
  427. END FPrintLReal;
  428. PROCEDURE ChkSum (VAR fp: INTEGER; val: INTEGER); (* symbolfile checksum *)
  429. BEGIN
  430. (* same as FPrint, 8 bit only *)
  431. fp := ORD(BITS(fp * 256) / BITS(crc32tab[ORD(BITS(fp DIV 1000000H) / BITS(val)) MOD 256]))
  432. END ChkSum;
  433. (* compact format *)
  434. PROCEDURE WriteLInt (w: Files.Writer; i: INTEGER);
  435. BEGIN
  436. ChkSum(checksum, i);
  437. w.WriteByte(SHORT(SHORT(i MOD 256))); i := i DIV 256;
  438. ChkSum(checksum, i);
  439. w.WriteByte(SHORT(SHORT(i MOD 256))); i := i DIV 256;
  440. ChkSum(checksum, i);
  441. w.WriteByte(SHORT(SHORT(i MOD 256))); i := i DIV 256;
  442. ChkSum(checksum, i);
  443. w.WriteByte(SHORT(SHORT(i MOD 256)))
  444. END WriteLInt;
  445. PROCEDURE ReadLInt (r: Files.Reader; VAR i: INTEGER);
  446. VAR b: BYTE; x: INTEGER;
  447. BEGIN
  448. r.ReadByte(b); x := b MOD 256;
  449. ChkSum(checksum, b);
  450. r.ReadByte(b); x := x + 100H * (b MOD 256);
  451. ChkSum(checksum, b);
  452. r.ReadByte(b); x := x + 10000H * (b MOD 256);
  453. ChkSum(checksum, b);
  454. r.ReadByte(b); i := x + 1000000H * b;
  455. ChkSum(checksum, b)
  456. END ReadLInt;
  457. PROCEDURE WriteNum (w: Files.Writer; i: INTEGER);
  458. BEGIN (* old format of Oberon *)
  459. WHILE (i < -64) OR (i > 63) DO ChkSum(checksum, i MOD 128 - 128); w.WriteByte(SHORT(SHORT(i MOD 128 - 128))); i := i DIV 128 END;
  460. ChkSum(checksum, i MOD 128);
  461. w.WriteByte(SHORT(SHORT(i MOD 128)))
  462. END WriteNum;
  463. PROCEDURE ReadNum (r: Files.Reader; VAR i: INTEGER);
  464. VAR b: BYTE; s, y: INTEGER;
  465. BEGIN
  466. s := 0; y := 0; r.ReadByte(b);
  467. IF ~r.eof THEN ChkSum(checksum, b) END;
  468. WHILE b < 0 DO INC(y, ASH(b + 128, s)); INC(s, 7); r.ReadByte(b); ChkSum(checksum, b) END;
  469. i := ASH((b + 64) MOD 128 - 64, s) + y;
  470. END ReadNum;
  471. PROCEDURE WriteNumSet (w: Files.Writer; x: SET);
  472. BEGIN
  473. WriteNum(w, ORD(x))
  474. END WriteNumSet;
  475. PROCEDURE ReadNumSet (r: Files.Reader; VAR x: SET);
  476. VAR i: INTEGER;
  477. BEGIN
  478. ReadNum(r, i); x := BITS(i)
  479. END ReadNumSet;
  480. PROCEDURE WriteReal (w: Files.Writer; x: SHORTREAL);
  481. BEGIN
  482. WriteLInt(w, SYSTEM.VAL(INTEGER, x))
  483. END WriteReal;
  484. PROCEDURE ReadReal (r: Files.Reader; VAR x: SHORTREAL);
  485. VAR i: INTEGER;
  486. BEGIN
  487. ReadLInt(r, i); x := SYSTEM.VAL(SHORTREAL, i)
  488. END ReadReal;
  489. PROCEDURE WriteLReal (w: Files.Writer; x: REAL);
  490. BEGIN
  491. WriteLInt(w, LoWord(x)); WriteLInt(w, HiWord(x))
  492. END WriteLReal;
  493. PROCEDURE ReadLReal (r: Files.Reader; VAR x: REAL);
  494. VAR h, l: INTEGER;
  495. BEGIN
  496. ReadLInt(r, l); ReadLInt(r, h); x := Compound(l, h)
  497. END ReadLReal;
  498. (* read symbol file *)
  499. PROCEDURE SymRCh* (VAR ch: SHORTCHAR);
  500. VAR b: BYTE;
  501. BEGIN
  502. inSym.ReadByte(b); ch := SHORT(CHR(b));
  503. ChkSum(checksum, b)
  504. END SymRCh;
  505. PROCEDURE SymRInt* (): INTEGER;
  506. VAR k: INTEGER;
  507. BEGIN
  508. ReadNum(inSym, k); RETURN k
  509. END SymRInt;
  510. PROCEDURE SymRSet* (VAR s: SET);
  511. BEGIN
  512. ReadNumSet(inSym, s)
  513. END SymRSet;
  514. PROCEDURE SymRReal* (VAR r: SHORTREAL);
  515. BEGIN
  516. ReadReal(inSym, r)
  517. END SymRReal;
  518. PROCEDURE SymRLReal* (VAR lr: REAL);
  519. BEGIN
  520. ReadLReal(inSym, lr)
  521. END SymRLReal;
  522. PROCEDURE eofSF* (): BOOLEAN;
  523. BEGIN
  524. RETURN inSym.eof
  525. END eofSF;
  526. PROCEDURE OldSym* (VAR modName: ARRAY OF SHORTCHAR; VAR done: BOOLEAN);
  527. VAR tag: INTEGER; loc: Files.Locator; dir, name: Files.Name;
  528. BEGIN
  529. done := FALSE;
  530. IF modName = "@file" THEN
  531. oldSymFile := file
  532. ELSE
  533. name := modName$; Kernel.SplitName(name, dir, name);
  534. Kernel.MakeFileName(name, Kernel.symType);
  535. loc := Files.dir.This(dir); loc := loc.This(symDir);
  536. oldSymFile := Files.dir.Old(loc, name, Files.shared);
  537. IF (oldSymFile = NIL) & (dir = "") THEN
  538. loc := Files.dir.This(SYSdir); loc := loc.This(symDir);
  539. oldSymFile := Files.dir.Old(loc, name, Files.shared)
  540. END
  541. END;
  542. IF oldSymFile # NIL THEN
  543. inSym := oldSymFile.NewReader(inSym);
  544. IF inSym # NIL THEN
  545. ReadLInt(inSym, tag);
  546. IF tag = SFtag THEN done := TRUE ELSE err(151) END
  547. END
  548. END
  549. END OldSym;
  550. PROCEDURE CloseOldSym*;
  551. BEGIN
  552. IF oldSymFile # NIL THEN oldSymFile.Close; oldSymFile := NIL END
  553. END CloseOldSym;
  554. (* write symbol file *)
  555. PROCEDURE SymWCh* (ch: SHORTCHAR);
  556. BEGIN
  557. ChkSum(checksum, ORD(ch));
  558. outSym.WriteByte(SHORT(ORD(ch)))
  559. END SymWCh;
  560. PROCEDURE SymWInt* (i: INTEGER);
  561. BEGIN
  562. WriteNum(outSym, i)
  563. END SymWInt;
  564. PROCEDURE SymWSet* (s: SET);
  565. BEGIN
  566. WriteNumSet(outSym, s)
  567. END SymWSet;
  568. PROCEDURE SymWReal* (VAR r: SHORTREAL);
  569. BEGIN
  570. WriteReal(outSym, r)
  571. END SymWReal;
  572. PROCEDURE SymWLReal* (VAR r: REAL);
  573. BEGIN
  574. WriteLReal(outSym, r)
  575. END SymWLReal;
  576. PROCEDURE SymReset*;
  577. BEGIN
  578. outSym.SetPos(4)
  579. END SymReset;
  580. PROCEDURE NewSym* (VAR modName: ARRAY OF SHORTCHAR);
  581. VAR loc: Files.Locator; dir: Files.Name;
  582. BEGIN
  583. ObjFName := modName$; Kernel.SplitName(ObjFName, dir, ObjFName);
  584. loc := Files.dir.This(dir); loc := loc.This(symDir);
  585. symFile := Files.dir.New(loc, Files.ask);
  586. IF symFile # NIL THEN
  587. outSym := symFile.NewWriter(NIL);
  588. WriteLInt(outSym, SFtag)
  589. ELSE
  590. err(153)
  591. END
  592. END NewSym;
  593. PROCEDURE RegisterNewSym*;
  594. VAR res: INTEGER; name: Files.Name;
  595. BEGIN
  596. IF symFile # NIL THEN
  597. name := ObjFName$;
  598. Kernel.MakeFileName(name, Kernel.symType);
  599. symFile.Register(name, Kernel.symType, Files.ask, res);
  600. symFile := NIL
  601. END
  602. END RegisterNewSym;
  603. PROCEDURE DeleteNewSym*;
  604. BEGIN
  605. IF symFile # NIL THEN symFile.Close; symFile := NIL END
  606. END DeleteNewSym;
  607. (* write object file *)
  608. PROCEDURE ObjW* (ch: SHORTCHAR);
  609. BEGIN
  610. outObj.WriteByte(SHORT(ORD(ch)))
  611. END ObjW;
  612. PROCEDURE ObjWNum* (i: INTEGER);
  613. BEGIN
  614. WriteNum(outObj, i)
  615. END ObjWNum;
  616. PROCEDURE ObjWInt (i: SHORTINT);
  617. BEGIN
  618. outObj.WriteByte(SHORT(SHORT(i MOD 256)));
  619. outObj.WriteByte(SHORT(SHORT(i DIV 256)))
  620. END ObjWInt;
  621. PROCEDURE ObjWLInt* (i: INTEGER);
  622. BEGIN
  623. ObjWInt(SHORT(i MOD 65536));
  624. ObjWInt(SHORT(i DIV 65536))
  625. END ObjWLInt;
  626. PROCEDURE ObjWBytes* (VAR bytes: ARRAY OF SHORTCHAR; n: INTEGER);
  627. TYPE P = POINTER TO ARRAY [untagged] 100000H OF BYTE;
  628. VAR p: P;
  629. BEGIN
  630. p := SYSTEM.VAL(P, SYSTEM.ADR(bytes));
  631. outObj.WriteBytes(p^, 0, n)
  632. END ObjWBytes;
  633. PROCEDURE ObjLen* (): INTEGER;
  634. BEGIN
  635. RETURN outObj.Pos()
  636. END ObjLen;
  637. PROCEDURE ObjSet* (pos: INTEGER);
  638. BEGIN
  639. outObj.SetPos(pos)
  640. END ObjSet;
  641. PROCEDURE NewObj* (VAR modName: ARRAY OF SHORTCHAR);
  642. VAR loc: Files.Locator; dir: Files.Name;
  643. BEGIN
  644. errpos := 0;
  645. ObjFName := modName$; Kernel.SplitName(ObjFName, dir, ObjFName);
  646. loc := Files.dir.This(dir); loc := loc.This(codeDir);
  647. objFile := Files.dir.New(loc, Files.ask);
  648. IF objFile # NIL THEN
  649. outObj := objFile.NewWriter(NIL);
  650. WriteLInt(outObj, OFtag)
  651. ELSE
  652. err(153)
  653. END
  654. END NewObj;
  655. PROCEDURE RegisterObj*;
  656. VAR res: INTEGER; name: Files.Name;
  657. BEGIN
  658. IF objFile # NIL THEN
  659. name := ObjFName$;
  660. Kernel.MakeFileName(name, Kernel.objType);
  661. objFile.Register(name, Kernel.objType, Files.ask, res);
  662. objFile := NIL; outObj := NIL
  663. END
  664. END RegisterObj;
  665. PROCEDURE DeleteObj*;
  666. BEGIN
  667. IF objFile # NIL THEN objFile.Close; objFile := NIL END
  668. END DeleteObj;
  669. PROCEDURE InitHost;
  670. VAR test: SHORTINT; lo: SHORTCHAR;
  671. BEGIN
  672. test := 1; SYSTEM.GET(SYSTEM.ADR(test), lo); LEHost := lo = 1X;
  673. InfReal := SYSTEM.VAL(SHORTREAL, InfRealPat);
  674. MinReal32 := SYSTEM.VAL(SHORTREAL, MinReal32Pat);
  675. MaxReal32 := SYSTEM.VAL(SHORTREAL, MaxReal32Pat);
  676. MinReal64 := Compound(MinReal64PatL, MinReal64PatH);
  677. MaxReal64 := Compound(MaxReal64PatL, MaxReal64PatH)
  678. END InitHost;
  679. BEGIN
  680. InitCrcTab;
  681. InitHost
  682. END LindevCPM.