CPM.txt 23 KB

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