tables.c 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923
  1. /* ------------------------------------------------------------------------- */
  2. /* "tables" : Constructs the story file or module (the output) up to the */
  3. /* end of dynamic memory, gluing together all the required */
  4. /* tables. */
  5. /* */
  6. /* Part of Inform 6.33 */
  7. /* copyright (c) Graham Nelson 1993 - 2014 */
  8. /* */
  9. /* ------------------------------------------------------------------------- */
  10. #include "header.h"
  11. uchar *zmachine_paged_memory; /* Where we shall store the story file
  12. constructed (contains all of paged
  13. memory, i.e. all but code and the
  14. static strings: allocated only when
  15. we know how large it needs to be,
  16. at the end of the compilation pass */
  17. /* In Glulx, zmachine_paged_memory contains all of RAM -- i.e. all but
  18. the header, the code, and the static strings. */
  19. /* ------------------------------------------------------------------------- */
  20. /* Offsets of various areas in the Z-machine: these are set to nominal */
  21. /* values before the compilation pass, and to their calculated final */
  22. /* values only when construct_storyfile() happens. These are then used to */
  23. /* backpatch the incorrect values now existing in the Z-machine which */
  24. /* used these nominal values. */
  25. /* Most of the nominal values are 0x800 because this is guaranteed to */
  26. /* be assembled as a long constant if it's needed in code, since the */
  27. /* largest possible value of scale_factor is 8 and 0x800/8 = 256. */
  28. /* */
  29. /* In Glulx, I use 0x12345 instead of 0x800. This will always be a long */
  30. /* (32-bit) constant, since there's no scale_factor. */
  31. /* ------------------------------------------------------------------------- */
  32. int32 code_offset,
  33. actions_offset,
  34. preactions_offset,
  35. dictionary_offset,
  36. adjectives_offset,
  37. variables_offset,
  38. strings_offset,
  39. class_numbers_offset,
  40. individuals_offset,
  41. identifier_names_offset,
  42. array_names_offset,
  43. prop_defaults_offset,
  44. prop_values_offset,
  45. static_memory_offset,
  46. attribute_names_offset,
  47. action_names_offset,
  48. fake_action_names_offset,
  49. routine_names_offset,
  50. constant_names_offset,
  51. routines_array_offset,
  52. constants_array_offset,
  53. routine_flags_array_offset,
  54. global_names_offset,
  55. global_flags_array_offset,
  56. array_flags_array_offset;
  57. int32 arrays_offset,
  58. object_tree_offset,
  59. grammar_table_offset,
  60. abbreviations_offset; /* Glulx */
  61. int32 Out_Size, Write_Code_At, Write_Strings_At;
  62. int32 RAM_Size, Write_RAM_At; /* Glulx */
  63. /* ------------------------------------------------------------------------- */
  64. /* Story file header settings. (Written to in "directs.c" and "asm.c".) */
  65. /* ------------------------------------------------------------------------- */
  66. int release_number, /* Release number game is to have */
  67. statusline_flag, /* Either TIME_STYLE or SCORE_STYLE */
  68. serial_code_given_in_program; /* If TRUE, a Serial directive has */
  69. char serial_code_buffer[7]; /* specified this 6-digit serial code */
  70. /* (overriding the usual date-stamp) */
  71. int flags2_requirements[16]; /* An array of which bits in Flags 2 of
  72. the header will need to be set:
  73. e.g. if the save_undo / restore_undo
  74. opcodes are ever assembled, we have
  75. to set the "games want UNDO" bit.
  76. Values are 0 or 1. */
  77. /* ------------------------------------------------------------------------- */
  78. /* Construct story/module file (up to code area start). */
  79. /* */
  80. /* (To understand what follows, you really need to look at the run-time */
  81. /* system's specification, the Z-Machine Standards document.) */
  82. /* ------------------------------------------------------------------------- */
  83. extern void write_serial_number(char *buffer)
  84. {
  85. /* Note that this function may require modification for "ANSI" compilers
  86. which do not provide the standard time functions: what is needed is
  87. the ability to work out today's date */
  88. time_t tt; tt=time(0);
  89. if (serial_code_given_in_program)
  90. strcpy(buffer, serial_code_buffer);
  91. else
  92. #ifdef TIME_UNAVAILABLE
  93. sprintf(buffer,"970000");
  94. #else
  95. strftime(buffer,10,"%y%m%d",localtime(&tt));
  96. #endif
  97. }
  98. static void percentage(char *name, int32 x, int32 total)
  99. { printf(" %-20s %2d.%d%%\n",name,x*100/total,(x*1000/total)%10);
  100. }
  101. static char *version_name(int v)
  102. {
  103. if (!glulx_mode) {
  104. switch(v)
  105. { case 3: return "Standard";
  106. case 4: return "Plus";
  107. case 5: return "Advanced";
  108. case 6: return "Graphical";
  109. case 8: return "Extended";
  110. }
  111. return "experimental format";
  112. }
  113. else {
  114. return "Glulx";
  115. }
  116. }
  117. static int32 rough_size_of_paged_memory_z(void)
  118. {
  119. /* This function calculates a modest over-estimate of the amount of
  120. memory required to store the Z-machine's paged memory area
  121. (that is, everything up to the start of the code area). */
  122. int32 total, i;
  123. ASSERT_ZCODE();
  124. total = 64 /* header */
  125. + 2 + subtract_pointers(low_strings_top, low_strings)
  126. /* low strings pool */
  127. + 6*32; /* abbreviations table */
  128. total += 8; /* header extension table */
  129. if (ZCODE_HEADER_EXT_WORDS>3) total += (ZCODE_HEADER_EXT_WORDS-3)*2;
  130. if (alphabet_modified) total += 78; /* character set table */
  131. if (zscii_defn_modified) /* Unicode translation table */
  132. total += 2 + 2*zscii_high_water_mark;
  133. total += 2*((version_number==3)?31:63) /* property default values */
  134. + no_objects*((version_number==3)?9:14) /* object tree table */
  135. + properties_table_size /* property values of objects */
  136. + (no_classes+1)*(module_switch?4:2)
  137. /* class object numbers table */
  138. + no_symbols*2 /* names of numerous things */
  139. + individuals_length /* tables of prop variables */
  140. + dynamic_array_area_size; /* variables and arrays */
  141. for (i=0; i<no_Inform_verbs; i++)
  142. total += 2 + 1 + /* address of grammar table, */
  143. /* number of grammar lines */
  144. ((grammar_version_number == 1)?
  145. (8*Inform_verbs[i].lines):0); /* grammar lines */
  146. if (grammar_version_number != 1)
  147. total += grammar_lines_top; /* size of grammar lines area */
  148. total += 2 + 4*no_adjectives /* adjectives table */
  149. + 2*no_actions /* action routines */
  150. + 2*no_grammar_token_routines; /* general parsing routines */
  151. total += (subtract_pointers(dictionary_top, dictionary)) /* dictionary */
  152. + ((module_switch)?30:0); /* module map */
  153. total += scale_factor*0x100 /* maximum null bytes before code */
  154. + 1000; /* fudge factor (in case the above is wrong) */
  155. return(total);
  156. }
  157. static int32 rough_size_of_paged_memory_g(void)
  158. {
  159. /* This function calculates a modest over-estimate of the amount of
  160. memory required to store the machine's paged memory area
  161. (that is, everything up to the start of the code area). */
  162. int32 total;
  163. ASSERT_GLULX();
  164. /* No header for us! */
  165. total = 1000; /* bit of a fudge factor */
  166. total += dynamic_array_area_size; /* arrays and global variables */
  167. total += no_objects * OBJECT_BYTE_LENGTH; /* object tables */
  168. total += properties_table_size; /* property tables */
  169. total += no_properties * 4; /* property defaults table */
  170. total += 4 + no_classes * 4; /* class prototype object numbers */
  171. total += 32; /* address/length of the identifier tables */
  172. total += no_properties * 4;
  173. total += (no_individual_properties-INDIV_PROP_START) * 4;
  174. total += (NUM_ATTR_BYTES*8) * 4;
  175. total += (no_actions + no_fake_actions) * 4;
  176. total += 4 + no_arrays * 4;
  177. total += 4 + no_Inform_verbs * 4; /* index of grammar tables */
  178. total += grammar_lines_top; /* grammar tables */
  179. total += 4 + no_actions * 4; /* actions functions table */
  180. total += 4;
  181. total += subtract_pointers(dictionary_top, dictionary);
  182. while (total % GPAGESIZE)
  183. total++;
  184. return(total);
  185. }
  186. static void construct_storyfile_z(void)
  187. { uchar *p;
  188. int32 i, j, k, l, mark, objs, strings_length, code_length,
  189. limit, excess, extend_offset, headerext_length;
  190. int32 globals_at, link_table_at, dictionary_at, actions_at, preactions_at,
  191. abbrevs_at, prop_defaults_at, object_tree_at, object_props_at,
  192. map_of_module, grammar_table_at, charset_at, headerext_at,
  193. terminating_chars_at, unicode_at, id_names_length;
  194. int skip_backpatching = FALSE;
  195. char *output_called = (module_switch)?"module":"story file";
  196. ASSERT_ZCODE();
  197. individual_name_strings =
  198. my_calloc(sizeof(int32), no_individual_properties,
  199. "identifier name strings");
  200. action_name_strings =
  201. my_calloc(sizeof(int32), no_actions + no_fake_actions,
  202. "action name strings");
  203. attribute_name_strings =
  204. my_calloc(sizeof(int32), 48,
  205. "attribute name strings");
  206. array_name_strings =
  207. my_calloc(sizeof(int32),
  208. no_symbols,
  209. "array name strings");
  210. write_the_identifier_names();
  211. /* We now know how large the buffer to hold our construction has to be */
  212. zmachine_paged_memory = my_malloc(rough_size_of_paged_memory_z(),
  213. "output buffer");
  214. /* Foolish code to make this routine compile on all ANSI compilers */
  215. p = (uchar *) zmachine_paged_memory;
  216. /* In what follows, the "mark" will move upwards in memory: at various
  217. points its value will be recorded for milestones like
  218. "dictionary table start". It begins at 0x40, just after the header */
  219. mark = 0x40;
  220. /* ----------------- Low Strings and Abbreviations -------------------- */
  221. p[mark]=0x80; p[mark+1]=0; mark+=2; /* Start the low strings pool
  222. with a useful default string, " " */
  223. for (i=0; i+low_strings<low_strings_top; mark++, i++) /* Low strings pool */
  224. p[0x42+i]=low_strings[i];
  225. abbrevs_at = mark;
  226. for (i=0; i<3*32; i++) /* Initially all 96 entries */
  227. { p[mark++]=0; p[mark++]=0x20; /* are set to " " */
  228. }
  229. for (i=0; i<no_abbreviations; i++) /* Write any abbreviations */
  230. { j=abbrev_values[i]; /* into banks 2 and 3 */
  231. p[abbrevs_at+64+2*i]=j/256; /* (bank 1 is reserved for */
  232. p[abbrevs_at+65+2*i]=j%256; /* "variable strings") */
  233. }
  234. /* ------------------- Header extension table ------------------------- */
  235. headerext_at = mark;
  236. headerext_length = ZCODE_HEADER_EXT_WORDS;
  237. if (zscii_defn_modified) {
  238. /* Need at least 3 words for unicode table address */
  239. if (headerext_length < 3)
  240. headerext_length = 3;
  241. }
  242. if (ZCODE_HEADER_FLAGS_3) {
  243. /* Need at least 4 words for the flags-3 field (ZSpec 1.1) */
  244. if (headerext_length < 4)
  245. headerext_length = 4;
  246. }
  247. p[mark++] = 0; p[mark++] = headerext_length;
  248. for (i=0; i<headerext_length; i++)
  249. { p[mark++] = 0; p[mark++] = 0;
  250. }
  251. /* -------------------- Z-character set table ------------------------- */
  252. if (alphabet_modified)
  253. { charset_at = mark;
  254. for (i=0;i<3;i++) for (j=0;j<26;j++)
  255. { if (alphabet[i][j] == '~') p[mark++] = '\"';
  256. else p[mark++] = alphabet[i][j];
  257. }
  258. }
  259. /* ------------------ Unicode translation table ----------------------- */
  260. unicode_at = 0;
  261. if (zscii_defn_modified)
  262. { unicode_at = mark;
  263. p[mark++] = zscii_high_water_mark;
  264. for (i=0;i<zscii_high_water_mark;i++)
  265. { j = zscii_to_unicode(155 + i);
  266. p[mark++] = j/256; p[mark++] = j%256;
  267. }
  268. }
  269. /* -------------------- Objects and Properties ------------------------ */
  270. prop_defaults_at = mark;
  271. p[mark++]=0; p[mark++]=0;
  272. for (i=2; i< ((version_number==3)?32:64); i++)
  273. { p[mark++]=prop_default_value[i]/256;
  274. p[mark++]=prop_default_value[i]%256;
  275. }
  276. object_tree_at = mark;
  277. mark += ((version_number==3)?9:14)*no_objects;
  278. object_props_at = mark;
  279. for (i=0; i<properties_table_size; i++)
  280. p[mark+i]=properties_table[i];
  281. for (i=0, objs=object_tree_at; i<no_objects; i++)
  282. {
  283. if (version_number == 3)
  284. { p[objs]=objectsz[i].atts[0];
  285. p[objs+1]=objectsz[i].atts[1];
  286. p[objs+2]=objectsz[i].atts[2];
  287. p[objs+3]=objectsz[i].atts[3];
  288. p[objs+4]=objectsz[i].parent;
  289. p[objs+5]=objectsz[i].next;
  290. p[objs+6]=objectsz[i].child;
  291. p[objs+7]=mark/256;
  292. p[objs+8]=mark%256;
  293. objs+=9;
  294. }
  295. else
  296. { p[objs]=objectsz[i].atts[0];
  297. p[objs+1]=objectsz[i].atts[1];
  298. p[objs+2]=objectsz[i].atts[2];
  299. p[objs+3]=objectsz[i].atts[3];
  300. p[objs+4]=objectsz[i].atts[4];
  301. p[objs+5]=objectsz[i].atts[5];
  302. p[objs+6]=(objectsz[i].parent)/256;
  303. p[objs+7]=(objectsz[i].parent)%256;
  304. p[objs+8]=(objectsz[i].next)/256;
  305. p[objs+9]=(objectsz[i].next)%256;
  306. p[objs+10]=(objectsz[i].child)/256;
  307. p[objs+11]=(objectsz[i].child)%256;
  308. if (!module_switch)
  309. { p[objs+12]=mark/256;
  310. p[objs+13]=mark%256;
  311. }
  312. else
  313. { p[objs+12]=objectsz[i].propsize/256;
  314. p[objs+13]=objectsz[i].propsize%256;
  315. }
  316. objs+=14;
  317. }
  318. mark+=objectsz[i].propsize;
  319. }
  320. /* ----------- Table of Class Prototype Object Numbers ---------------- */
  321. class_numbers_offset = mark;
  322. for (i=0; i<no_classes; i++)
  323. { p[mark++] = class_object_numbers[i]/256;
  324. p[mark++] = class_object_numbers[i]%256;
  325. if (module_switch)
  326. { p[mark++] = class_begins_at[i]/256;
  327. p[mark++] = class_begins_at[i]%256;
  328. }
  329. }
  330. p[mark++] = 0;
  331. p[mark++] = 0;
  332. /* ------------------- Table of Identifier Names ---------------------- */
  333. identifier_names_offset = mark;
  334. if (!module_switch)
  335. { p[mark++] = no_individual_properties/256;
  336. p[mark++] = no_individual_properties%256;
  337. for (i=1; i<no_individual_properties; i++)
  338. { p[mark++] = individual_name_strings[i]/256;
  339. p[mark++] = individual_name_strings[i]%256;
  340. }
  341. attribute_names_offset = mark;
  342. for (i=0; i<48; i++)
  343. { p[mark++] = attribute_name_strings[i]/256;
  344. p[mark++] = attribute_name_strings[i]%256;
  345. }
  346. action_names_offset = mark;
  347. fake_action_names_offset = mark + 2*no_actions;
  348. for (i=0; i<no_actions + no_fake_actions; i++)
  349. { p[mark++] = action_name_strings[i]/256;
  350. p[mark++] = action_name_strings[i]%256;
  351. }
  352. array_names_offset = mark;
  353. global_names_offset = mark + 2*no_arrays;
  354. routine_names_offset = global_names_offset + 2*no_globals;
  355. constant_names_offset = routine_names_offset + 2*no_named_routines;
  356. for (i=0; i<no_arrays + no_globals
  357. + no_named_routines + no_named_constants; i++)
  358. { if ((i == no_arrays) && (define_INFIX_switch == FALSE)) break;
  359. p[mark++] = array_name_strings[i]/256;
  360. p[mark++] = array_name_strings[i]%256;
  361. }
  362. id_names_length = (mark - identifier_names_offset)/2;
  363. }
  364. routine_flags_array_offset = mark;
  365. if (define_INFIX_switch)
  366. { for (i=0, k=1, l=0; i<no_named_routines; i++)
  367. { if (sflags[named_routine_symbols[i]] & STAR_SFLAG) l=l+k;
  368. k=k*2;
  369. if (k==256) { p[mark++] = l; k=1; l=0; }
  370. }
  371. if (k!=1) p[mark++]=l;
  372. }
  373. /* ---------------- Table of Indiv Property Values -------------------- */
  374. individuals_offset = mark;
  375. for (i=0; i<individuals_length; i++)
  376. p[mark++] = individuals_table[i];
  377. /* ----------------- Variables and Dynamic Arrays --------------------- */
  378. globals_at = mark;
  379. for (i=0; i<dynamic_array_area_size; i++)
  380. p[mark++] = dynamic_array_area[i];
  381. for (i=0; i<240; i++)
  382. { j=global_initial_value[i];
  383. p[globals_at+i*2] = j/256; p[globals_at+i*2+1] = j%256;
  384. }
  385. /* ------------------ Terminating Characters Table -------------------- */
  386. if (version_number >= 5)
  387. { terminating_chars_at = mark;
  388. for (i=0; i<no_termcs; i++) p[mark++] = terminating_characters[i];
  389. p[mark++] = 0;
  390. }
  391. /* ------------------------ Grammar Table ----------------------------- */
  392. if (grammar_version_number > 2)
  393. { warning("This version of Inform is unable to produce the grammar \
  394. table format requested (producing number 2 format instead)");
  395. grammar_version_number = 2;
  396. }
  397. grammar_table_at = mark;
  398. mark = mark + no_Inform_verbs*2;
  399. for (i=0; i<no_Inform_verbs; i++)
  400. { p[grammar_table_at + i*2] = (mark/256);
  401. p[grammar_table_at + i*2 + 1] = (mark%256);
  402. p[mark++] = Inform_verbs[i].lines;
  403. for (j=0; j<Inform_verbs[i].lines; j++)
  404. { k = Inform_verbs[i].l[j];
  405. if (grammar_version_number == 1)
  406. { int m, n;
  407. p[mark+7] = grammar_lines[k+1];
  408. for (m=1;m<=6;m++) p[mark + m] = 0;
  409. k = k + 2; m = 1; n = 0;
  410. while ((grammar_lines[k] != 15) && (m<=6))
  411. { p[mark + m] = grammar_lines[k];
  412. if (grammar_lines[k] < 180) n++;
  413. m++; k = k + 3;
  414. }
  415. p[mark] = n;
  416. mark = mark + 8;
  417. }
  418. else
  419. { int tok;
  420. p[mark++] = grammar_lines[k++];
  421. p[mark++] = grammar_lines[k++];
  422. for (;;)
  423. { tok = grammar_lines[k++];
  424. p[mark++] = tok;
  425. if (tok == 15) break;
  426. p[mark++] = grammar_lines[k++];
  427. p[mark++] = grammar_lines[k++];
  428. }
  429. }
  430. }
  431. }
  432. /* ------------------- Actions and Preactions ------------------------- */
  433. /* (The term "preactions" is traditional: Inform uses the preactions */
  434. /* table for a different purpose than Infocom used to.) */
  435. /* The values are written later, when the Z-code offset is known. */
  436. /* -------------------------------------------------------------------- */
  437. actions_at = mark;
  438. mark += no_actions*2;
  439. preactions_at = mark;
  440. if (grammar_version_number == 1)
  441. mark += no_grammar_token_routines*2;
  442. /* ----------------------- Adjectives Table --------------------------- */
  443. if (grammar_version_number == 1)
  444. { p[mark]=0; p[mark+1]=no_adjectives; mark+=2; /* To assist "infodump" */
  445. adjectives_offset = mark;
  446. dictionary_offset = mark + 4*no_adjectives;
  447. for (i=0; i<no_adjectives; i++)
  448. { j = final_dict_order[adjectives[no_adjectives-i-1]]
  449. *((version_number==3)?7:9)
  450. + dictionary_offset + 7;
  451. p[mark++]=j/256; p[mark++]=j%256; p[mark++]=0;
  452. p[mark++]=(256-no_adjectives+i);
  453. }
  454. }
  455. else
  456. { p[mark]=0; p[mark+1]=0; mark+=2;
  457. adjectives_offset = mark;
  458. dictionary_offset = mark;
  459. }
  460. /* ------------------------- Dictionary ------------------------------- */
  461. dictionary_at=mark;
  462. dictionary[0]=3; dictionary[1]='.'; /* Non-space characters which */
  463. dictionary[2]=','; /* force words apart */
  464. dictionary[3]='"';
  465. dictionary[4]=(version_number==3)?7:9; /* Length of each entry */
  466. dictionary[5]=(dict_entries/256); /* Number of entries */
  467. dictionary[6]=(dict_entries%256);
  468. for (i=0; i<7; i++) p[mark++] = dictionary[i];
  469. for (i=0; i<dict_entries; i++)
  470. { k = 7 + i*((version_number==3)?7:9);
  471. j = mark + final_dict_order[i]*((version_number==3)?7:9);
  472. for (l = 0; l<((version_number==3)?7:9); l++)
  473. p[j++] = dictionary[k++];
  474. }
  475. mark += dict_entries * ((version_number==3)?7:9);
  476. /* ------------------------- Module Map ------------------------------- */
  477. if (module_switch)
  478. { map_of_module = mark; /* Filled in below */
  479. mark += 30;
  480. }
  481. /* ----------------- A gap before the code area ----------------------- */
  482. /* (so that it will start at an exact packed address and so that all */
  483. /* routine packed addresses are >= 256, hence long constants) */
  484. /* -------------------------------------------------------------------- */
  485. while ((mark%length_scale_factor) != 0) p[mark++]=0;
  486. while (mark < (scale_factor*0x100)) p[mark++]=0;
  487. if (oddeven_packing_switch)
  488. while ((mark%(scale_factor*2)) != 0) p[mark++]=0;
  489. if (mark > 0x0FFFE)
  490. { error("This program has overflowed the maximum readable-memory \
  491. size of the Z-machine format. See the memory map below: the start \
  492. of the area marked \"above readable memory\" must be brought down to $FFFE \
  493. or less.");
  494. memory_map_switch = TRUE;
  495. /* Backpatching the grammar tables requires us to trust some of the */
  496. /* addresses we've written into Z-machine memory, but they may have */
  497. /* been truncated to 16 bits, so we can't do it. */
  498. skip_backpatching = TRUE;
  499. }
  500. /* -------------------------- Code Area ------------------------------- */
  501. /* (From this point on we don't write any more into the "p" buffer.) */
  502. /* -------------------------------------------------------------------- */
  503. Write_Code_At = mark;
  504. if (!OMIT_UNUSED_ROUTINES) {
  505. code_length = zmachine_pc;
  506. }
  507. else {
  508. if (zmachine_pc != df_total_size_before_stripping)
  509. compiler_error("Code size does not match (zmachine_pc and df_total_size).");
  510. code_length = df_total_size_after_stripping;
  511. }
  512. mark += code_length;
  513. /* ------------------ Another synchronising gap ----------------------- */
  514. if (oddeven_packing_switch)
  515. { if (module_switch)
  516. while ((mark%(scale_factor*2)) != 0) mark++;
  517. else
  518. while ((mark%(scale_factor*2)) != scale_factor) mark++;
  519. }
  520. else
  521. while ((mark%scale_factor) != 0) mark++;
  522. /* ------------------------- Strings Area ----------------------------- */
  523. Write_Strings_At = mark;
  524. strings_length = static_strings_extent;
  525. mark += strings_length;
  526. /* --------------------- Module Linking Data -------------------------- */
  527. if (module_switch)
  528. { link_table_at = mark; mark += link_data_size;
  529. mark += zcode_backpatch_size;
  530. mark += zmachine_backpatch_size;
  531. }
  532. /* --------------------- Is the file too big? ------------------------- */
  533. Out_Size = mark;
  534. switch(version_number)
  535. { case 3: excess = Out_Size-((int32) 0x20000L); limit = 128; break;
  536. case 4:
  537. case 5: excess = Out_Size-((int32) 0x40000L); limit = 256; break;
  538. case 6:
  539. case 7:
  540. case 8: excess = Out_Size-((int32) 0x80000L); limit = 512; break;
  541. }
  542. if (module_switch)
  543. { excess = Out_Size-((int32) 0x10000L); limit=64;
  544. }
  545. if (excess > 0)
  546. { char memory_full_error[80];
  547. sprintf(memory_full_error,
  548. "The %s exceeds version-%d limit (%dK) by %d bytes",
  549. output_called, version_number, limit, excess);
  550. fatalerror(memory_full_error);
  551. }
  552. /* --------------------------- Offsets -------------------------------- */
  553. dictionary_offset = dictionary_at;
  554. variables_offset = globals_at;
  555. actions_offset = actions_at;
  556. preactions_offset = preactions_at;
  557. prop_defaults_offset = prop_defaults_at;
  558. prop_values_offset = object_props_at;
  559. static_memory_offset = grammar_table_at;
  560. grammar_table_offset = grammar_table_at;
  561. if (extend_memory_map)
  562. { extend_offset=256;
  563. if (no_objects+9 > extend_offset) extend_offset=no_objects+9;
  564. while ((extend_offset%length_scale_factor) != 0) extend_offset++;
  565. /* Not sure why above line is necessary, but oddeven_packing
  566. * will need extend_offset to be even */
  567. code_offset = extend_offset*scale_factor;
  568. if (oddeven_packing_switch)
  569. strings_offset = code_offset + scale_factor;
  570. else
  571. strings_offset = code_offset + (Write_Strings_At-Write_Code_At);
  572. /* With the extended memory model, need to specifically check that we
  573. * haven't overflowed the packed address range for routines or strings.
  574. * With the standard memory model, we only need the earlier total size
  575. * check.
  576. */
  577. excess = code_length + code_offset - (scale_factor*((int32) 0x10000L));
  578. if (excess > 0)
  579. { char code_full_error[80];
  580. sprintf(code_full_error,
  581. "The code area limit has been exceeded by %d bytes",
  582. excess);
  583. fatalerror(code_full_error);
  584. }
  585. excess = strings_length + strings_offset - (scale_factor*((int32) 0x10000L));
  586. if (excess > 0)
  587. { char strings_full_error[140];
  588. if (oddeven_packing_switch)
  589. sprintf(strings_full_error,
  590. "The strings area limit has been exceeded by %d bytes",
  591. excess);
  592. else
  593. sprintf(strings_full_error,
  594. "The code+strings area limit has been exceeded by %d bytes. \
  595. Try running Inform again with -B on the command line.",
  596. excess);
  597. fatalerror(strings_full_error);
  598. }
  599. }
  600. else
  601. { code_offset = Write_Code_At;
  602. strings_offset = Write_Strings_At;
  603. }
  604. /* --------------------------- The Header ----------------------------- */
  605. for (i=0; i<=0x3f; i++) p[i]=0; /* Begin with 64 blank bytes */
  606. p[0] = version_number; /* Version number */
  607. p[1] = statusline_flag*2; /* Bit 1 of Flags 1: statusline style */
  608. p[2] = (release_number/256);
  609. p[3] = (release_number%256); /* Release */
  610. p[4] = (Write_Code_At/256);
  611. p[5] = (Write_Code_At%256); /* End of paged memory */
  612. if (version_number==6)
  613. { j=code_offset/scale_factor; /* Packed address of "Main__" */
  614. p[6]=(j/256); p[7]=(j%256);
  615. }
  616. else
  617. { j=Write_Code_At+1; /* Initial PC value (bytes) */
  618. p[6]=(j/256); p[7]=(j%256); /* (first opcode in "Main__") */
  619. }
  620. p[8] = (dictionary_at/256); p[9]=(dictionary_at%256); /* Dictionary */
  621. p[10]=prop_defaults_at/256; p[11]=prop_defaults_at%256; /* Objects */
  622. p[12]=(globals_at/256); p[13]=(globals_at%256); /* Dynamic area */
  623. p[14]=(grammar_table_at/256);
  624. p[15]=(grammar_table_at%256); /* Grammar */
  625. for (i=0, j=0, k=1;i<16;i++, k=k*2) /* Flags 2 as needed for any */
  626. j+=k*flags2_requirements[i]; /* unusual opcodes assembled */
  627. p[16]=j/256; p[17]=j%256;
  628. write_serial_number((char *) (p+18)); /* Serial number: 6 chars of ASCII */
  629. p[24]=abbrevs_at/256;
  630. p[25]=abbrevs_at%256; /* Abbreviations table */
  631. p[26]=0; p[27]=0; /* Length of file to be filled in "files.c" */
  632. p[28]=0; p[29]=0; /* Checksum to be filled in "files.c" */
  633. if (extend_memory_map)
  634. { j=(Write_Code_At - extend_offset*scale_factor)/length_scale_factor;
  635. p[40]=j/256; p[41]=j%256; /* Routines offset */
  636. if (oddeven_packing_switch)
  637. j=(Write_Strings_At - extend_offset*scale_factor)/length_scale_factor;
  638. p[42]=j/256; p[43]=j%256; /* = Strings offset */
  639. }
  640. if (version_number >= 5)
  641. { p[46] = terminating_chars_at/256; /* Terminating characters table */
  642. p[47] = terminating_chars_at%256;
  643. }
  644. if (alphabet_modified)
  645. { j = charset_at;
  646. p[52]=j/256; p[53]=j%256; } /* Character set table address */
  647. j = headerext_at;
  648. p[54] = j/256; p[55] = j%256; /* Header extension table address */
  649. p[60] = '0' + ((RELEASE_NUMBER/100)%10);
  650. p[61] = '.';
  651. p[62] = '0' + ((RELEASE_NUMBER/10)%10);
  652. p[63] = '0' + RELEASE_NUMBER%10;
  653. /* ------------------------ Header Extension -------------------------- */
  654. /* The numbering in the spec is a little weird -- it's headerext_length
  655. words *after* the initial length word. We follow the spec numbering
  656. in this switch statement, so the count is 1-based. */
  657. for (i=1; i<=headerext_length; i++) {
  658. switch (i) {
  659. case 3:
  660. j = unicode_at; /* Unicode translation table address */
  661. break;
  662. case 4:
  663. j = ZCODE_HEADER_FLAGS_3; /* Flags 3 word */
  664. break;
  665. default:
  666. j = 0;
  667. break;
  668. }
  669. p[headerext_at+2*i+0] = j / 256;
  670. p[headerext_at+2*i+1] = j % 256;
  671. }
  672. /* ----------------- The Header: Extras for modules ------------------- */
  673. if (module_switch)
  674. { p[0]=p[0]+64;
  675. p[1]=MODULE_VERSION_NUMBER;
  676. p[6]=map_of_module/256;
  677. p[7]=map_of_module%256;
  678. mark = map_of_module; /* Module map format: */
  679. p[mark++]=object_tree_at/256; /* 0: Object tree addr */
  680. p[mark++]=object_tree_at%256;
  681. p[mark++]=object_props_at/256; /* 2: Prop values addr */
  682. p[mark++]=object_props_at%256;
  683. p[mark++]=(Write_Strings_At/scale_factor)/256; /* 4: Static strs */
  684. p[mark++]=(Write_Strings_At/scale_factor)%256;
  685. p[mark++]=class_numbers_offset/256; /* 6: Class nos addr */
  686. p[mark++]=class_numbers_offset%256;
  687. p[mark++]=individuals_offset/256; /* 8: Indiv prop values */
  688. p[mark++]=individuals_offset%256;
  689. p[mark++]=individuals_length/256; /* 10: Length of table */
  690. p[mark++]=individuals_length%256;
  691. p[mark++]=no_symbols/256; /* 12: No of symbols */
  692. p[mark++]=no_symbols%256;
  693. p[mark++]=no_individual_properties/256; /* 14: Max property no */
  694. p[mark++]=no_individual_properties%256;
  695. p[mark++]=no_objects/256; /* 16: No of objects */
  696. p[mark++]=no_objects%256;
  697. i = link_table_at;
  698. p[mark++]=i/256; /* 18: Import/exports */
  699. p[mark++]=i%256;
  700. p[mark++]=link_data_size/256; /* 20: Size of */
  701. p[mark++]=link_data_size%256;
  702. i += link_data_size;
  703. p[mark++]=i/256; /* 22: Code backpatch */
  704. p[mark++]=i%256;
  705. p[mark++]=zcode_backpatch_size/256; /* 24: Size of */
  706. p[mark++]=zcode_backpatch_size%256;
  707. i += zcode_backpatch_size;
  708. p[mark++]=i/256; /* 26: Image backpatch */
  709. p[mark++]=i%256;
  710. p[mark++]=zmachine_backpatch_size/256; /* 28: Size of */
  711. p[mark++]=zmachine_backpatch_size%256;
  712. /* Further space in this table is reserved for future use */
  713. }
  714. /* ---- Backpatch the Z-machine, now that all information is in ------- */
  715. if (!module_switch && !skip_backpatching)
  716. { backpatch_zmachine_image_z();
  717. for (i=1; i<id_names_length; i++)
  718. { int32 v = 256*p[identifier_names_offset + i*2]
  719. + p[identifier_names_offset + i*2 + 1];
  720. if (v!=0) v += strings_offset/scale_factor;
  721. p[identifier_names_offset + i*2] = v/256;
  722. p[identifier_names_offset + i*2 + 1] = v%256;
  723. }
  724. mark = actions_at;
  725. for (i=0; i<no_actions; i++)
  726. { j=action_byte_offset[i];
  727. if (OMIT_UNUSED_ROUTINES)
  728. j = df_stripped_address_for_address(j);
  729. j += code_offset/scale_factor;
  730. p[mark++]=j/256; p[mark++]=j%256;
  731. }
  732. if (grammar_version_number == 1)
  733. { mark = preactions_at;
  734. for (i=0; i<no_grammar_token_routines; i++)
  735. { j=grammar_token_routine[i];
  736. if (OMIT_UNUSED_ROUTINES)
  737. j = df_stripped_address_for_address(j);
  738. j += code_offset/scale_factor;
  739. p[mark++]=j/256; p[mark++]=j%256;
  740. }
  741. }
  742. else
  743. { for (l = 0; l<no_Inform_verbs; l++)
  744. { k = grammar_table_at + 2*l;
  745. i = p[k]*256 + p[k+1];
  746. for (j = p[i++]; j>0; j--)
  747. { int topbits; int32 value;
  748. i = i + 2;
  749. while (p[i] != 15)
  750. { topbits = (p[i]/0x40) & 3;
  751. value = p[i+1]*256 + p[i+2];
  752. switch(topbits)
  753. { case 1:
  754. value = final_dict_order[value]
  755. *((version_number==3)?7:9)
  756. + dictionary_offset + 7;
  757. break;
  758. case 2:
  759. if (OMIT_UNUSED_ROUTINES)
  760. value = df_stripped_address_for_address(value);
  761. value += code_offset/scale_factor;
  762. break;
  763. }
  764. p[i+1] = value/256; p[i+2] = value%256;
  765. i = i + 3;
  766. }
  767. i++;
  768. }
  769. }
  770. }
  771. }
  772. /* ---- From here on, it's all reportage: construction is finished ---- */
  773. if (statistics_switch)
  774. { int32 k_long, rate; char *k_str="";
  775. k_long=(Out_Size/1024);
  776. if ((Out_Size-1024*k_long) >= 512) { k_long++; k_str=""; }
  777. else if ((Out_Size-1024*k_long) > 0) { k_str=".5"; }
  778. if (total_bytes_trans == 0) rate = 0;
  779. else rate=total_bytes_trans*1000/total_chars_trans;
  780. { printf("In:\
  781. %3d source code files %6d syntactic lines\n\
  782. %6d textual lines %8ld characters ",
  783. input_file, no_syntax_lines,
  784. total_source_line_count, (long int) total_chars_read);
  785. if (character_set_unicode) printf("(UTF-8)\n");
  786. else if (character_set_setting == 0) printf("(plain ASCII)\n");
  787. else
  788. { printf("(ISO 8859-%d %s)\n", character_set_setting,
  789. name_of_iso_set(character_set_setting));
  790. }
  791. printf("Allocated:\n\
  792. %6d symbols (maximum %4d) %8ld bytes of memory\n\
  793. Out: Version %d \"%s\" %s %d.%c%c%c%c%c%c (%ld%sK long):\n",
  794. no_symbols, MAX_SYMBOLS,
  795. (long int) malloced_bytes,
  796. version_number,
  797. version_name(version_number),
  798. output_called,
  799. release_number, p[18], p[19], p[20], p[21], p[22], p[23],
  800. (long int) k_long, k_str);
  801. printf("\
  802. %6d classes (maximum %3d) %6d objects (maximum %3d)\n\
  803. %6d global vars (maximum 233) %6d variable/array space (maximum %d)\n",
  804. no_classes, MAX_CLASSES,
  805. no_objects, ((version_number==3)?255:(MAX_OBJECTS-1)),
  806. no_globals,
  807. dynamic_array_area_size, MAX_STATIC_DATA);
  808. printf(
  809. "%6d verbs (maximum %3d) %6d dictionary entries (maximum %d)\n\
  810. %6d grammar lines (version %d) %6d grammar tokens (unlimited)\n\
  811. %6d actions (maximum %3d) %6d attributes (maximum %2d)\n\
  812. %6d common props (maximum %2d) %6d individual props (unlimited)\n",
  813. no_Inform_verbs, MAX_VERBS,
  814. dict_entries, MAX_DICT_ENTRIES,
  815. no_grammar_lines, grammar_version_number,
  816. no_grammar_tokens,
  817. no_actions, MAX_ACTIONS,
  818. no_attributes, ((version_number==3)?32:48),
  819. no_properties-2, ((version_number==3)?30:62),
  820. no_individual_properties - 64);
  821. if (track_unused_routines)
  822. {
  823. uint32 diff = df_total_size_before_stripping - df_total_size_after_stripping;
  824. printf(
  825. "%6ld bytes of Z-code %6ld unused bytes %s (%.1f%%)\n",
  826. (long int) df_total_size_before_stripping, (long int) diff,
  827. (OMIT_UNUSED_ROUTINES ? "stripped out" : "detected"),
  828. 100 * (float)diff / (float)df_total_size_before_stripping);
  829. }
  830. printf(
  831. "%6ld characters used in text %6ld bytes compressed (rate %d.%3ld)\n\
  832. %6d abbreviations (maximum %d) %6d routines (unlimited)\n\
  833. %6ld instructions of Z-code %6d sequence points\n\
  834. %6ld bytes readable memory used (maximum 65536)\n\
  835. %6ld bytes used in Z-machine %6ld bytes free in Z-machine\n",
  836. (long int) total_chars_trans,
  837. (long int) total_bytes_trans,
  838. (total_chars_trans>total_bytes_trans)?0:1,
  839. (long int) rate,
  840. no_abbreviations, MAX_ABBREVS,
  841. no_routines,
  842. (long int) no_instructions, no_sequence_points,
  843. (long int) Write_Code_At,
  844. (long int) Out_Size,
  845. (long int)
  846. (((long int) (limit*1024L)) - ((long int) Out_Size)));
  847. }
  848. }
  849. if (offsets_switch)
  850. {
  851. { printf(
  852. "\nOffsets in %s:\n\
  853. %05lx Synonyms %05lx Defaults %05lx Objects %05lx Properties\n\
  854. %05lx Variables %05lx Parse table %05lx Actions %05lx Preactions\n\
  855. %05lx Adjectives %05lx Dictionary %05lx Code %05lx Strings\n",
  856. output_called,
  857. (long int) abbrevs_at,
  858. (long int) prop_defaults_at,
  859. (long int) object_tree_at,
  860. (long int) object_props_at,
  861. (long int) globals_at,
  862. (long int) grammar_table_at,
  863. (long int) actions_at,
  864. (long int) preactions_at,
  865. (long int) adjectives_offset,
  866. (long int) dictionary_at,
  867. (long int) Write_Code_At,
  868. (long int) Write_Strings_At);
  869. if (module_switch)
  870. printf("%05lx Linking data\n",(long int) link_table_at);
  871. }
  872. }
  873. if (debugfile_switch)
  874. { begin_writing_debug_sections();
  875. write_debug_section("abbreviations", 64);
  876. write_debug_section("abbreviations table", abbrevs_at);
  877. write_debug_section("header extension", headerext_at);
  878. if (alphabet_modified)
  879. { write_debug_section("alphabets table", charset_at);
  880. }
  881. if (zscii_defn_modified)
  882. { write_debug_section("Unicode table", unicode_at);
  883. }
  884. write_debug_section("property defaults", prop_defaults_at);
  885. write_debug_section("object tree", object_tree_at);
  886. write_debug_section("common properties", object_props_at);
  887. write_debug_section("class numbers", class_numbers_offset);
  888. write_debug_section("identifier names", identifier_names_offset);
  889. write_debug_section("individual properties", individuals_offset);
  890. write_debug_section("global variables", globals_at);
  891. write_debug_section("array space", globals_at+480);
  892. write_debug_section("grammar table", grammar_table_at);
  893. write_debug_section("actions table", actions_at);
  894. write_debug_section("parsing routines", preactions_at);
  895. write_debug_section("adjectives table", adjectives_offset);
  896. write_debug_section("dictionary", dictionary_at);
  897. write_debug_section("code area", Write_Code_At);
  898. write_debug_section("strings area", Write_Strings_At);
  899. end_writing_debug_sections(Out_Size);
  900. }
  901. if (memory_map_switch)
  902. {
  903. {
  904. printf("Dynamic +---------------------+ 00000\n");
  905. printf("memory | header |\n");
  906. printf(" +---------------------+ 00040\n");
  907. printf(" | abbreviations |\n");
  908. printf(" + - - - - - - - - - - + %05lx\n", (long int) abbrevs_at);
  909. printf(" | abbreviations table |\n");
  910. printf(" +---------------------+ %05lx\n", (long int) headerext_at);
  911. printf(" | header extension |\n");
  912. if (alphabet_modified)
  913. {
  914. printf(" + - - - - - - - - - - + %05lx\n", (long int) charset_at);
  915. printf(" | alphabets table |\n");
  916. }
  917. if (zscii_defn_modified)
  918. {
  919. printf(" + - - - - - - - - - - + %05lx\n", (long int) unicode_at);
  920. printf(" | Unicode table |\n");
  921. }
  922. printf(" +---------------------+ %05lx\n",
  923. (long int) prop_defaults_at);
  924. printf(" | property defaults |\n");
  925. printf(" + - - - - - - - - - - + %05lx\n", (long int) object_tree_at);
  926. printf(" | objects |\n");
  927. printf(" + - - - - - - - - - - + %05lx\n",
  928. (long int) object_props_at);
  929. printf(" | object short names, |\n");
  930. printf(" | common prop values |\n");
  931. printf(" + - - - - - - - - - - + %05lx\n",
  932. (long int) class_numbers_offset);
  933. printf(" | class numbers table |\n");
  934. printf(" + - - - - - - - - - - + %05lx\n",
  935. (long int) identifier_names_offset);
  936. printf(" | symbol names table |\n");
  937. printf(" + - - - - - - - - - - + %05lx\n",
  938. (long int) individuals_offset);
  939. printf(" | indiv prop values |\n");
  940. printf(" +---------------------+ %05lx\n", (long int) globals_at);
  941. printf(" | global variables |\n");
  942. printf(" + - - - - - - - - - - + %05lx\n",
  943. ((long int) globals_at)+480L);
  944. printf(" | arrays |\n");
  945. printf(" +=====================+ %05lx\n",
  946. (long int) grammar_table_at);
  947. printf("Readable| grammar table |\n");
  948. printf("memory + - - - - - - - - - - + %05lx\n", (long int) actions_at);
  949. printf(" | actions |\n");
  950. printf(" + - - - - - - - - - - + %05lx\n", (long int) preactions_at);
  951. printf(" | parsing routines |\n");
  952. printf(" + - - - - - - - - - - + %05lx\n",
  953. (long int) adjectives_offset);
  954. printf(" | adjectives |\n");
  955. printf(" +---------------------+ %05lx\n", (long int) dictionary_at);
  956. printf(" | dictionary |\n");
  957. if (module_switch)
  958. {
  959. printf(" + - - - - - - - - - - + %05lx\n",
  960. (long int) map_of_module);
  961. printf(" | map of module addrs |\n");
  962. }
  963. printf(" +=====================+ %05lx\n", (long int) Write_Code_At);
  964. printf("Above | Z-code |\n");
  965. printf("readable+---------------------+ %05lx\n",
  966. (long int) Write_Strings_At);
  967. printf("memory | strings |\n");
  968. if (module_switch)
  969. {
  970. printf(" +=====================+ %05lx\n", (long int) link_table_at);
  971. printf(" | module linking data |\n");
  972. }
  973. printf(" +---------------------+ %05lx\n", (long int) Out_Size);
  974. }
  975. }
  976. if (percentages_switch)
  977. { printf("Approximate percentage breakdown of %s:\n",
  978. output_called);
  979. percentage("Z-code", code_length,Out_Size);
  980. if (module_switch)
  981. percentage("Linking data", link_data_size,Out_Size);
  982. percentage("Static strings", strings_length,Out_Size);
  983. percentage("Dictionary", Write_Code_At-dictionary_at,Out_Size);
  984. percentage("Objects", globals_at-prop_defaults_at,Out_Size);
  985. percentage("Globals", grammar_table_at-globals_at,Out_Size);
  986. percentage("Parsing tables", dictionary_at-grammar_table_at,Out_Size);
  987. percentage("Header and synonyms", prop_defaults_at,Out_Size);
  988. percentage("Total of save area", grammar_table_at,Out_Size);
  989. percentage("Total of text", total_bytes_trans,Out_Size);
  990. }
  991. if (frequencies_switch)
  992. {
  993. { printf("How frequently abbreviations were used, and roughly\n");
  994. printf("how many bytes they saved: ('_' denotes spaces)\n");
  995. for (i=0; i<no_abbreviations; i++)
  996. { char abbrev_string[64];
  997. strcpy(abbrev_string,
  998. (char *)abbreviations_at+i*MAX_ABBREV_LENGTH);
  999. for (j=0; abbrev_string[j]!=0; j++)
  1000. if (abbrev_string[j]==' ') abbrev_string[j]='_';
  1001. printf("%10s %5d/%5d ",abbrev_string,abbrev_freqs[i],
  1002. 2*((abbrev_freqs[i]-1)*abbrev_quality[i])/3);
  1003. if ((i%3)==2) printf("\n");
  1004. }
  1005. if ((i%3)!=0) printf("\n");
  1006. if (no_abbreviations==0) printf("None were declared.\n");
  1007. }
  1008. }
  1009. }
  1010. static void construct_storyfile_g(void)
  1011. { uchar *p;
  1012. int32 i, j, k, l, mark, strings_length, limit;
  1013. int32 globals_at, dictionary_at, actions_at, preactions_at,
  1014. abbrevs_at, prop_defaults_at, object_tree_at, object_props_at,
  1015. grammar_table_at, charset_at, headerext_at,
  1016. unicode_at, arrays_at;
  1017. int32 threespaces, code_length;
  1018. char *output_called = (module_switch)?"module":"story file";
  1019. ASSERT_GLULX();
  1020. individual_name_strings =
  1021. my_calloc(sizeof(int32), no_individual_properties,
  1022. "identifier name strings");
  1023. action_name_strings =
  1024. my_calloc(sizeof(int32), no_actions + no_fake_actions,
  1025. "action name strings");
  1026. attribute_name_strings =
  1027. my_calloc(sizeof(int32), NUM_ATTR_BYTES*8,
  1028. "attribute name strings");
  1029. array_name_strings =
  1030. my_calloc(sizeof(int32),
  1031. no_symbols,
  1032. "array name strings");
  1033. write_the_identifier_names();
  1034. threespaces = compile_string(" ", FALSE, FALSE);
  1035. compress_game_text();
  1036. /* We now know how large the buffer to hold our construction has to be */
  1037. zmachine_paged_memory = my_malloc(rough_size_of_paged_memory_g(),
  1038. "output buffer");
  1039. /* Foolish code to make this routine compile on all ANSI compilers */
  1040. p = (uchar *) zmachine_paged_memory;
  1041. /* In what follows, the "mark" will move upwards in memory: at various
  1042. points its value will be recorded for milestones like
  1043. "dictionary table start". It begins at 0x40, just after the header */
  1044. /* Ok, our policy here will be to set the *_at values all relative
  1045. to RAM. That's so we can write into zmachine_paged_memory[mark]
  1046. and actually hit what we're aiming at.
  1047. All the *_offset values will be set to true Glulx machine
  1048. addresses. */
  1049. /* To get our bearings, figure out where the strings and code are. */
  1050. /* We start with two words, which conventionally identify the
  1051. memory layout. This is why the code starts eight bytes after
  1052. the header. */
  1053. Write_Code_At = GLULX_HEADER_SIZE + GLULX_STATIC_ROM_SIZE;
  1054. if (!OMIT_UNUSED_ROUTINES) {
  1055. code_length = zmachine_pc;
  1056. }
  1057. else {
  1058. if (zmachine_pc != df_total_size_before_stripping)
  1059. compiler_error("Code size does not match (zmachine_pc and df_total_size).");
  1060. code_length = df_total_size_after_stripping;
  1061. }
  1062. Write_Strings_At = Write_Code_At + code_length;
  1063. strings_length = compression_table_size + compression_string_size;
  1064. /* Now figure out where RAM starts. */
  1065. Write_RAM_At = Write_Strings_At + strings_length;
  1066. /* The Write_RAM_At boundary must be a multiple of GPAGESIZE. */
  1067. while (Write_RAM_At % GPAGESIZE)
  1068. Write_RAM_At++;
  1069. /* Now work out all those RAM positions. */
  1070. mark = 0;
  1071. /* ----------------- Variables and Dynamic Arrays --------------------- */
  1072. globals_at = mark;
  1073. for (i=0; i<no_globals; i++) {
  1074. j = global_initial_value[i];
  1075. WriteInt32(p+mark, j);
  1076. mark += 4;
  1077. }
  1078. arrays_at = mark;
  1079. for (i=MAX_GLOBAL_VARIABLES*4; i<dynamic_array_area_size; i++)
  1080. p[mark++] = dynamic_array_area[i];
  1081. /* -------------------------- Dynamic Strings -------------------------- */
  1082. abbrevs_at = mark;
  1083. WriteInt32(p+mark, no_dynamic_strings);
  1084. mark += 4;
  1085. for (i=0; i<no_dynamic_strings; i++) {
  1086. j = Write_Strings_At + compressed_offsets[threespaces-1];
  1087. WriteInt32(p+mark, j);
  1088. mark += 4;
  1089. }
  1090. /* ---------------- Various Things I'm Not Sure About ------------------ */
  1091. /* Actually, none of these are relevant to Glulx. */
  1092. headerext_at = mark;
  1093. if (alphabet_modified)
  1094. charset_at = mark;
  1095. unicode_at = 0;
  1096. if (zscii_defn_modified)
  1097. unicode_at = mark;
  1098. /* -------------------- Objects and Properties ------------------------ */
  1099. object_tree_at = mark;
  1100. object_props_at = mark + no_objects*OBJECT_BYTE_LENGTH;
  1101. for (i=0; i<no_objects; i++) {
  1102. int32 objmark = mark;
  1103. p[mark++] = 0x70; /* type byte -- object */
  1104. for (j=0; j<NUM_ATTR_BYTES; j++) {
  1105. p[mark++] = objectatts[i*NUM_ATTR_BYTES+j];
  1106. }
  1107. for (j=0; j<6; j++) {
  1108. int32 val;
  1109. switch (j) {
  1110. case 0: /* next object in the linked list. */
  1111. if (i == no_objects-1)
  1112. val = 0;
  1113. else
  1114. val = Write_RAM_At + objmark + OBJECT_BYTE_LENGTH;
  1115. break;
  1116. case 1: /* hardware name address */
  1117. val = Write_Strings_At + compressed_offsets[objectsg[i].shortname-1];
  1118. break;
  1119. case 2: /* property table address */
  1120. val = Write_RAM_At + object_props_at + objectsg[i].propaddr;
  1121. break;
  1122. case 3: /* parent */
  1123. if (objectsg[i].parent == 0)
  1124. val = 0;
  1125. else
  1126. val = Write_RAM_At + object_tree_at +
  1127. (OBJECT_BYTE_LENGTH*(objectsg[i].parent-1));
  1128. break;
  1129. case 4: /* sibling */
  1130. if (objectsg[i].next == 0)
  1131. val = 0;
  1132. else
  1133. val = Write_RAM_At + object_tree_at +
  1134. (OBJECT_BYTE_LENGTH*(objectsg[i].next-1));
  1135. break;
  1136. case 5: /* child */
  1137. if (objectsg[i].child == 0)
  1138. val = 0;
  1139. else
  1140. val = Write_RAM_At + object_tree_at +
  1141. (OBJECT_BYTE_LENGTH*(objectsg[i].child-1));
  1142. break;
  1143. }
  1144. p[mark++] = (val >> 24) & 0xFF;
  1145. p[mark++] = (val >> 16) & 0xFF;
  1146. p[mark++] = (val >> 8) & 0xFF;
  1147. p[mark++] = (val) & 0xFF;
  1148. }
  1149. for (j=0; j<GLULX_OBJECT_EXT_BYTES; j++) {
  1150. p[mark++] = 0;
  1151. }
  1152. }
  1153. if (object_props_at != mark)
  1154. error("*** Object table was impossible length ***");
  1155. for (i=0; i<properties_table_size; i++)
  1156. p[mark+i]=properties_table[i];
  1157. for (i=0; i<no_objects; i++) {
  1158. int32 tableaddr = object_props_at + objectsg[i].propaddr;
  1159. int32 tablelen = ReadInt32(p+tableaddr);
  1160. tableaddr += 4;
  1161. for (j=0; j<tablelen; j++) {
  1162. k = ReadInt32(p+tableaddr+4);
  1163. k += (Write_RAM_At + object_props_at);
  1164. WriteInt32(p+tableaddr+4, k);
  1165. tableaddr += 10;
  1166. }
  1167. }
  1168. mark += properties_table_size;
  1169. prop_defaults_at = mark;
  1170. for (i=0; i<no_properties; i++) {
  1171. k = prop_default_value[i];
  1172. WriteInt32(p+mark, k);
  1173. mark += 4;
  1174. }
  1175. /* ----------- Table of Class Prototype Object Numbers ---------------- */
  1176. class_numbers_offset = mark;
  1177. for (i=0; i<no_classes; i++) {
  1178. j = Write_RAM_At + object_tree_at +
  1179. (OBJECT_BYTE_LENGTH*(class_object_numbers[i]-1));
  1180. WriteInt32(p+mark, j);
  1181. mark += 4;
  1182. }
  1183. WriteInt32(p+mark, 0);
  1184. mark += 4;
  1185. /* -------------------- Table of Property Names ------------------------ */
  1186. /* We try to format this bit with some regularity...
  1187. address of common properties
  1188. number of common properties
  1189. address of indiv properties
  1190. number of indiv properties (counted from INDIV_PROP_START)
  1191. address of attributes
  1192. number of attributes (always NUM_ATTR_BYTES*8)
  1193. address of actions
  1194. number of actions
  1195. */
  1196. identifier_names_offset = mark;
  1197. mark += 32; /* eight pairs of values, to be filled in. */
  1198. WriteInt32(p+identifier_names_offset+0, Write_RAM_At + mark);
  1199. WriteInt32(p+identifier_names_offset+4, no_properties);
  1200. for (i=0; i<no_properties; i++) {
  1201. j = individual_name_strings[i];
  1202. if (j)
  1203. j = Write_Strings_At + compressed_offsets[j-1];
  1204. WriteInt32(p+mark, j);
  1205. mark += 4;
  1206. }
  1207. WriteInt32(p+identifier_names_offset+8, Write_RAM_At + mark);
  1208. WriteInt32(p+identifier_names_offset+12,
  1209. no_individual_properties-INDIV_PROP_START);
  1210. for (i=INDIV_PROP_START; i<no_individual_properties; i++) {
  1211. j = individual_name_strings[i];
  1212. if (j)
  1213. j = Write_Strings_At + compressed_offsets[j-1];
  1214. WriteInt32(p+mark, j);
  1215. mark += 4;
  1216. }
  1217. WriteInt32(p+identifier_names_offset+16, Write_RAM_At + mark);
  1218. WriteInt32(p+identifier_names_offset+20, NUM_ATTR_BYTES*8);
  1219. for (i=0; i<NUM_ATTR_BYTES*8; i++) {
  1220. j = attribute_name_strings[i];
  1221. if (j)
  1222. j = Write_Strings_At + compressed_offsets[j-1];
  1223. WriteInt32(p+mark, j);
  1224. mark += 4;
  1225. }
  1226. WriteInt32(p+identifier_names_offset+24, Write_RAM_At + mark);
  1227. WriteInt32(p+identifier_names_offset+28, no_actions + no_fake_actions);
  1228. action_names_offset = mark;
  1229. fake_action_names_offset = mark + 4*no_actions;
  1230. for (i=0; i<no_actions + no_fake_actions; i++) {
  1231. j = action_name_strings[i];
  1232. if (j)
  1233. j = Write_Strings_At + compressed_offsets[j-1];
  1234. WriteInt32(p+mark, j);
  1235. mark += 4;
  1236. }
  1237. array_names_offset = mark;
  1238. WriteInt32(p+mark, no_arrays);
  1239. mark += 4;
  1240. for (i=0; i<no_arrays; i++) {
  1241. j = array_name_strings[i];
  1242. if (j)
  1243. j = Write_Strings_At + compressed_offsets[j-1];
  1244. WriteInt32(p+mark, j);
  1245. mark += 4;
  1246. }
  1247. individuals_offset = mark;
  1248. /* ------------------------ Grammar Table ----------------------------- */
  1249. if (grammar_version_number != 2)
  1250. { warning("This version of Inform is unable to produce the grammar \
  1251. table format requested (producing number 2 format instead)");
  1252. grammar_version_number = 2;
  1253. }
  1254. grammar_table_at = mark;
  1255. WriteInt32(p+mark, no_Inform_verbs);
  1256. mark += 4;
  1257. mark += no_Inform_verbs*4;
  1258. for (i=0; i<no_Inform_verbs; i++) {
  1259. j = mark + Write_RAM_At;
  1260. WriteInt32(p+(grammar_table_at+4+i*4), j);
  1261. p[mark++] = Inform_verbs[i].lines;
  1262. for (j=0; j<Inform_verbs[i].lines; j++) {
  1263. int tok;
  1264. k = Inform_verbs[i].l[j];
  1265. p[mark++] = grammar_lines[k++];
  1266. p[mark++] = grammar_lines[k++];
  1267. p[mark++] = grammar_lines[k++];
  1268. for (;;) {
  1269. tok = grammar_lines[k++];
  1270. p[mark++] = tok;
  1271. if (tok == 15) break;
  1272. p[mark++] = grammar_lines[k++];
  1273. p[mark++] = grammar_lines[k++];
  1274. p[mark++] = grammar_lines[k++];
  1275. p[mark++] = grammar_lines[k++];
  1276. }
  1277. }
  1278. }
  1279. /* ------------------- Actions and Preactions ------------------------- */
  1280. actions_at = mark;
  1281. WriteInt32(p+mark, no_actions);
  1282. mark += 4;
  1283. mark += no_actions*4;
  1284. /* Values to be written in later. */
  1285. if (DICT_CHAR_SIZE != 1) {
  1286. /* If the dictionary is Unicode, we'd like it to be word-aligned. */
  1287. while (mark % 4)
  1288. p[mark++]=0;
  1289. }
  1290. preactions_at = mark;
  1291. adjectives_offset = mark;
  1292. dictionary_offset = mark;
  1293. /* ------------------------- Dictionary ------------------------------- */
  1294. dictionary_at = mark;
  1295. WriteInt32(dictionary+0, dict_entries);
  1296. for (i=0; i<4; i++)
  1297. p[mark+i] = dictionary[i];
  1298. for (i=0; i<dict_entries; i++) {
  1299. k = 4 + i*DICT_ENTRY_BYTE_LENGTH;
  1300. j = mark + 4 + final_dict_order[i]*DICT_ENTRY_BYTE_LENGTH;
  1301. for (l=0; l<DICT_ENTRY_BYTE_LENGTH; l++)
  1302. p[j++] = dictionary[k++];
  1303. }
  1304. mark += 4 + dict_entries * DICT_ENTRY_BYTE_LENGTH;
  1305. /* -------------------------- All Data -------------------------------- */
  1306. /* The end-of-RAM boundary must be a multiple of GPAGESIZE. */
  1307. while (mark % GPAGESIZE)
  1308. p[mark++]=0;
  1309. RAM_Size = mark;
  1310. Out_Size = Write_RAM_At + RAM_Size;
  1311. limit=1024*1024;
  1312. /* --------------------------- Offsets -------------------------------- */
  1313. dictionary_offset = Write_RAM_At + dictionary_at;
  1314. variables_offset = Write_RAM_At + globals_at;
  1315. arrays_offset = Write_RAM_At + arrays_at;
  1316. actions_offset = Write_RAM_At + actions_at;
  1317. preactions_offset = Write_RAM_At + preactions_at;
  1318. prop_defaults_offset = Write_RAM_At + prop_defaults_at;
  1319. object_tree_offset = Write_RAM_At + object_tree_at;
  1320. prop_values_offset = Write_RAM_At + object_props_at;
  1321. static_memory_offset = Write_RAM_At + grammar_table_at;
  1322. grammar_table_offset = Write_RAM_At + grammar_table_at;
  1323. abbreviations_offset = Write_RAM_At + abbrevs_at;
  1324. code_offset = Write_Code_At;
  1325. strings_offset = Write_Strings_At;
  1326. /* --------------------------- The Header ----------------------------- */
  1327. /* ------ Backpatch the machine, now that all information is in ------- */
  1328. if (!module_switch)
  1329. { backpatch_zmachine_image_g();
  1330. mark = actions_at + 4;
  1331. for (i=0; i<no_actions; i++) {
  1332. j = action_byte_offset[i];
  1333. if (OMIT_UNUSED_ROUTINES)
  1334. j = df_stripped_address_for_address(j);
  1335. j += code_offset;
  1336. WriteInt32(p+mark, j);
  1337. mark += 4;
  1338. }
  1339. for (l = 0; l<no_Inform_verbs; l++) {
  1340. k = grammar_table_at + 4 + 4*l;
  1341. i = ((p[k] << 24) | (p[k+1] << 16) | (p[k+2] << 8) | (p[k+3]));
  1342. i -= Write_RAM_At;
  1343. for (j = p[i++]; j>0; j--) {
  1344. int topbits;
  1345. int32 value;
  1346. i = i + 3;
  1347. while (p[i] != 15) {
  1348. topbits = (p[i]/0x40) & 3;
  1349. value = ((p[i+1] << 24) | (p[i+2] << 16)
  1350. | (p[i+3] << 8) | (p[i+4]));
  1351. switch(topbits) {
  1352. case 1:
  1353. value = dictionary_offset + 4
  1354. + final_dict_order[value]*DICT_ENTRY_BYTE_LENGTH;
  1355. break;
  1356. case 2:
  1357. if (OMIT_UNUSED_ROUTINES)
  1358. value = df_stripped_address_for_address(value);
  1359. value += code_offset;
  1360. break;
  1361. }
  1362. WriteInt32(p+(i+1), value);
  1363. i = i + 5;
  1364. }
  1365. i++;
  1366. }
  1367. }
  1368. }
  1369. /* ---- From here on, it's all reportage: construction is finished ---- */
  1370. if (statistics_switch)
  1371. { int32 k_long, rate; char *k_str="";
  1372. k_long=(Out_Size/1024);
  1373. if ((Out_Size-1024*k_long) >= 512) { k_long++; k_str=""; }
  1374. else if ((Out_Size-1024*k_long) > 0) { k_str=".5"; }
  1375. if (strings_length == 0) rate = 0;
  1376. else rate=strings_length*1000/total_chars_trans;
  1377. { printf("In:\
  1378. %3d source code files %6d syntactic lines\n\
  1379. %6d textual lines %8ld characters ",
  1380. input_file, no_syntax_lines,
  1381. total_source_line_count, (long int) total_chars_read);
  1382. if (character_set_unicode) printf("(UTF-8)\n");
  1383. else if (character_set_setting == 0) printf("(plain ASCII)\n");
  1384. else
  1385. { printf("(ISO 8859-%d %s)\n", character_set_setting,
  1386. name_of_iso_set(character_set_setting));
  1387. }
  1388. {char serialnum[8];
  1389. write_serial_number(serialnum);
  1390. printf("Allocated:\n\
  1391. %6d symbols (maximum %4d) %8ld bytes of memory\n\
  1392. Out: %s %s %d.%c%c%c%c%c%c (%ld%sK long):\n",
  1393. no_symbols, MAX_SYMBOLS,
  1394. (long int) malloced_bytes,
  1395. version_name(version_number),
  1396. output_called,
  1397. release_number,
  1398. serialnum[0], serialnum[1], serialnum[2],
  1399. serialnum[3], serialnum[4], serialnum[5],
  1400. (long int) k_long, k_str);
  1401. }
  1402. printf("\
  1403. %6d classes (maximum %3d) %6d objects (maximum %3d)\n\
  1404. %6d global vars (maximum %3d) %6d variable/array space (maximum %d)\n",
  1405. no_classes, MAX_CLASSES,
  1406. no_objects, MAX_OBJECTS,
  1407. no_globals, MAX_GLOBAL_VARIABLES,
  1408. dynamic_array_area_size, MAX_STATIC_DATA);
  1409. printf(
  1410. "%6d verbs (maximum %3d) %6d dictionary entries (maximum %d)\n\
  1411. %6d grammar lines (version %d) %6d grammar tokens (unlimited)\n\
  1412. %6d actions (maximum %3d) %6d attributes (maximum %2d)\n\
  1413. %6d common props (maximum %3d) %6d individual props (unlimited)\n",
  1414. no_Inform_verbs, MAX_VERBS,
  1415. dict_entries, MAX_DICT_ENTRIES,
  1416. no_grammar_lines, grammar_version_number,
  1417. no_grammar_tokens,
  1418. no_actions, MAX_ACTIONS,
  1419. no_attributes, NUM_ATTR_BYTES*8,
  1420. no_properties, INDIV_PROP_START,
  1421. no_individual_properties - INDIV_PROP_START);
  1422. if (track_unused_routines)
  1423. {
  1424. uint32 diff = df_total_size_before_stripping - df_total_size_after_stripping;
  1425. printf(
  1426. "%6ld bytes of code %6ld unused bytes %s (%.1f%%)\n",
  1427. (long int) df_total_size_before_stripping, (long int) diff,
  1428. (OMIT_UNUSED_ROUTINES ? "stripped out" : "detected"),
  1429. 100 * (float)diff / (float)df_total_size_before_stripping);
  1430. }
  1431. printf(
  1432. "%6ld characters used in text %6ld bytes compressed (rate %d.%3ld)\n\
  1433. %6d abbreviations (maximum %d) %6d routines (unlimited)\n\
  1434. %6ld instructions of code %6d sequence points\n\
  1435. %6ld bytes writable memory used %6ld bytes read-only memory used\n\
  1436. %6ld bytes used in machine %10ld bytes free in machine\n",
  1437. (long int) total_chars_trans,
  1438. (long int) strings_length,
  1439. (total_chars_trans>strings_length)?0:1,
  1440. (long int) rate,
  1441. no_abbreviations, MAX_ABBREVS,
  1442. no_routines,
  1443. (long int) no_instructions, no_sequence_points,
  1444. (long int) (Out_Size - Write_RAM_At),
  1445. (long int) Write_RAM_At,
  1446. (long int) Out_Size,
  1447. (long int)
  1448. (((long int) (limit*1024L)) - ((long int) Out_Size)));
  1449. }
  1450. }
  1451. if (offsets_switch)
  1452. {
  1453. { printf(
  1454. "\nOffsets in %s:\n\
  1455. %05lx Synonyms %05lx Defaults %05lx Objects %05lx Properties\n\
  1456. %05lx Variables %05lx Parse table %05lx Actions %05lx Preactions\n\
  1457. %05lx Adjectives %05lx Dictionary %05lx Code %05lx Strings\n",
  1458. output_called,
  1459. (long int) abbrevs_at,
  1460. (long int) prop_defaults_at,
  1461. (long int) object_tree_at,
  1462. (long int) object_props_at,
  1463. (long int) globals_at,
  1464. (long int) grammar_table_at,
  1465. (long int) actions_at,
  1466. (long int) preactions_at,
  1467. (long int) adjectives_offset,
  1468. (long int) dictionary_at,
  1469. (long int) Write_Code_At,
  1470. (long int) Write_Strings_At);
  1471. }
  1472. }
  1473. if (debugfile_switch)
  1474. { begin_writing_debug_sections();
  1475. write_debug_section("memory layout id", GLULX_HEADER_SIZE);
  1476. write_debug_section("code area", Write_Code_At);
  1477. write_debug_section("string decoding table", Write_Strings_At);
  1478. write_debug_section("strings area",
  1479. Write_Strings_At + compression_table_size);
  1480. if (Write_Strings_At + strings_length < Write_RAM_At)
  1481. { write_debug_section
  1482. ("zero padding", Write_Strings_At + strings_length);
  1483. }
  1484. if (globals_at)
  1485. { compiler_error("Failed assumption that globals are at start of "
  1486. "Glulx RAM");
  1487. }
  1488. write_debug_section("global variables", Write_RAM_At + globals_at);
  1489. write_debug_section("array space", Write_RAM_At + arrays_at);
  1490. write_debug_section("abbreviations table", Write_RAM_At + abbrevs_at);
  1491. write_debug_section("object tree", Write_RAM_At + object_tree_at);
  1492. write_debug_section("common properties",
  1493. Write_RAM_At + object_props_at);
  1494. write_debug_section("property defaults",
  1495. Write_RAM_At + prop_defaults_at);
  1496. write_debug_section("class numbers",
  1497. Write_RAM_At + class_numbers_offset);
  1498. write_debug_section("identifier names",
  1499. Write_RAM_At + identifier_names_offset);
  1500. write_debug_section("grammar table", Write_RAM_At + grammar_table_at);
  1501. write_debug_section("actions table", Write_RAM_At + actions_at);
  1502. write_debug_section("dictionary", Write_RAM_At + dictionary_at);
  1503. if (MEMORY_MAP_EXTENSION)
  1504. { write_debug_section("zero padding", Out_Size);
  1505. }
  1506. end_writing_debug_sections(Out_Size + MEMORY_MAP_EXTENSION);
  1507. }
  1508. if (memory_map_switch)
  1509. {
  1510. {
  1511. printf(" +---------------------+ 000000\n");
  1512. printf("Read- | header |\n");
  1513. printf(" only +=====================+ %06lx\n", (long int) GLULX_HEADER_SIZE);
  1514. printf("memory | memory layout id |\n");
  1515. printf(" +---------------------+ %06lx\n", (long int) Write_Code_At);
  1516. printf(" | code |\n");
  1517. printf(" +---------------------+ %06lx\n",
  1518. (long int) Write_Strings_At);
  1519. printf(" | string decode table |\n");
  1520. printf(" + - - - - - - - - - - + %06lx\n",
  1521. (long int) Write_Strings_At + compression_table_size);
  1522. printf(" | strings |\n");
  1523. printf(" +=====================+ %06lx\n",
  1524. (long int) (Write_RAM_At+globals_at));
  1525. printf("Dynamic | global variables |\n");
  1526. printf("memory + - - - - - - - - - - + %06lx\n",
  1527. (long int) (Write_RAM_At+arrays_at));
  1528. printf(" | arrays |\n");
  1529. printf(" +---------------------+ %06lx\n",
  1530. (long int) (Write_RAM_At+abbrevs_at));
  1531. printf(" | printing variables |\n");
  1532. if (alphabet_modified)
  1533. {
  1534. printf(" + - - - - - - - - - - + %06lx\n",
  1535. (long int) (Write_RAM_At+charset_at));
  1536. printf(" | alphabets table |\n");
  1537. }
  1538. if (zscii_defn_modified)
  1539. {
  1540. printf(" + - - - - - - - - - - + %06lx\n",
  1541. (long int) (Write_RAM_At+unicode_at));
  1542. printf(" | Unicode table |\n");
  1543. }
  1544. printf(" +---------------------+ %06lx\n",
  1545. (long int) (Write_RAM_At+object_tree_at));
  1546. printf(" | objects |\n");
  1547. printf(" + - - - - - - - - - - + %06lx\n",
  1548. (long int) (Write_RAM_At+object_props_at));
  1549. printf(" | property values |\n");
  1550. printf(" + - - - - - - - - - - + %06lx\n",
  1551. (long int) (Write_RAM_At+prop_defaults_at));
  1552. printf(" | property defaults |\n");
  1553. printf(" + - - - - - - - - - - + %06lx\n",
  1554. (long int) (Write_RAM_At+class_numbers_offset));
  1555. printf(" | class numbers table |\n");
  1556. printf(" + - - - - - - - - - - + %06lx\n",
  1557. (long int) (Write_RAM_At+identifier_names_offset));
  1558. printf(" | id names table |\n");
  1559. printf(" +---------------------+ %06lx\n",
  1560. (long int) (Write_RAM_At+grammar_table_at));
  1561. printf(" | grammar table |\n");
  1562. printf(" + - - - - - - - - - - + %06lx\n",
  1563. (long int) (Write_RAM_At+actions_at));
  1564. printf(" | actions |\n");
  1565. printf(" +---------------------+ %06lx\n",
  1566. (long int) dictionary_offset);
  1567. printf(" | dictionary |\n");
  1568. if (MEMORY_MAP_EXTENSION == 0)
  1569. {
  1570. printf(" +---------------------+ %06lx\n", (long int) Out_Size);
  1571. }
  1572. else
  1573. {
  1574. printf(" +=====================+ %06lx\n", (long int) Out_Size);
  1575. printf("Runtime | (empty) |\n");
  1576. printf(" extn +---------------------+ %06lx\n", (long int) Out_Size+MEMORY_MAP_EXTENSION);
  1577. }
  1578. }
  1579. }
  1580. if (percentages_switch)
  1581. { printf("Approximate percentage breakdown of %s:\n",
  1582. output_called);
  1583. percentage("Code", code_length,Out_Size);
  1584. if (module_switch)
  1585. percentage("Linking data", link_data_size,Out_Size);
  1586. percentage("Static strings", strings_length,Out_Size);
  1587. percentage("Dictionary", Write_Code_At-dictionary_at,Out_Size);
  1588. percentage("Objects", globals_at-prop_defaults_at,Out_Size);
  1589. percentage("Globals", grammar_table_at-globals_at,Out_Size);
  1590. percentage("Parsing tables", dictionary_at-grammar_table_at,Out_Size);
  1591. percentage("Header and synonyms", prop_defaults_at,Out_Size);
  1592. percentage("Total of save area", grammar_table_at,Out_Size);
  1593. percentage("Total of text", strings_length,Out_Size);
  1594. }
  1595. if (frequencies_switch)
  1596. {
  1597. { printf("How frequently abbreviations were used, and roughly\n");
  1598. printf("how many bytes they saved: ('_' denotes spaces)\n");
  1599. for (i=0; i<no_abbreviations; i++)
  1600. { char abbrev_string[64];
  1601. strcpy(abbrev_string,
  1602. (char *)abbreviations_at+i*MAX_ABBREV_LENGTH);
  1603. for (j=0; abbrev_string[j]!=0; j++)
  1604. if (abbrev_string[j]==' ') abbrev_string[j]='_';
  1605. printf("%10s %5d/%5d ",abbrev_string,abbrev_freqs[i],
  1606. 2*((abbrev_freqs[i]-1)*abbrev_quality[i])/3);
  1607. if ((i%3)==2) printf("\n");
  1608. }
  1609. if ((i%3)!=0) printf("\n");
  1610. if (no_abbreviations==0) printf("None were declared.\n");
  1611. }
  1612. }
  1613. }
  1614. extern void construct_storyfile(void)
  1615. {
  1616. if (!glulx_mode)
  1617. construct_storyfile_z();
  1618. else
  1619. construct_storyfile_g();
  1620. }
  1621. /* ========================================================================= */
  1622. /* Data structure management routines */
  1623. /* ------------------------------------------------------------------------- */
  1624. extern void init_tables_vars(void)
  1625. {
  1626. serial_code_given_in_program = FALSE;
  1627. release_number = 1;
  1628. statusline_flag = SCORE_STYLE;
  1629. zmachine_paged_memory = NULL;
  1630. if (!glulx_mode) {
  1631. code_offset = 0x800;
  1632. actions_offset = 0x800;
  1633. preactions_offset = 0x800;
  1634. dictionary_offset = 0x800;
  1635. adjectives_offset = 0x800;
  1636. variables_offset = 0;
  1637. strings_offset = 0xc00;
  1638. individuals_offset=0x800;
  1639. identifier_names_offset=0x800;
  1640. class_numbers_offset = 0x800;
  1641. arrays_offset = 0x0800; /* only used in Glulx, but might as well set */
  1642. }
  1643. else {
  1644. code_offset = 0x12345;
  1645. actions_offset = 0x12345;
  1646. preactions_offset = 0x12345;
  1647. dictionary_offset = 0x12345;
  1648. adjectives_offset = 0x12345;
  1649. variables_offset = 0x12345;
  1650. arrays_offset = 0x12345;
  1651. strings_offset = 0x12345;
  1652. individuals_offset=0x12345;
  1653. identifier_names_offset=0x12345;
  1654. class_numbers_offset = 0x12345;
  1655. }
  1656. }
  1657. extern void tables_begin_pass(void)
  1658. {
  1659. }
  1660. extern void tables_allocate_arrays(void)
  1661. {
  1662. }
  1663. extern void tables_free_arrays(void)
  1664. {
  1665. /* Allocation for this array happens in construct_storyfile() above */
  1666. my_free(&zmachine_paged_memory,"output buffer");
  1667. }
  1668. /* ========================================================================= */