TSLOCATE.LST 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. Listing:
  2. 1 (* Release 3.10 *)
  3. 2 (*-------------------------------------------------------------------------*
  4. 3 * *
  5. 4 * TSLOCATE.MOD - Embedded code locator *
  6. 5 * *
  7. 6 * COPYRIGHT (C) 1989..1992 Clarion Software Corporation. *
  8. 7 * All Rights Reserved *
  9. 8 * *
  10. 9 *--------------------------------------------------------------------------*)
  11. 10
  12. 11 (*# call(near_call=>on,
  13. 12 o_a_copy=>off) *)
  14. 13 (*# check(index=>on,
  15. 14 range=>off,
  16. 15 stack=>on,
  17. 16 overflow=>off) *)
  18. 17 (*# optimize(alias=>on) *)
  19. 18
  20. 19 MODULE tslocate;
  21. 20 IMPORT Lib,Str,FIO,IO,Storage;
  22. 21
  23. 22 (* This program is used to locate an MSDOS exe file.
  24. 23 The output is in Absolute Binary format,
  25. 24 suitable for blowing a stand-alone system into PROM.
  26. 25 The memory layout of the target system is specified in the
  27. 26 .mem file, together with the linker classes which are to be
  28. 27 put in the memory, for example:
  29. 28
  30. 29 rom F0000 FFFF0 CODE FCODE
  31. 30 ram 80000 E0000 DATA Dummy BSS M_DATA HEAP STACK
  32. 31
  33. 32 The second address is a 'stop' address, so that a warning can
  34. 33 be produced if there is not enough memory.
  35. 34
  36. 35 *)
  37. 36
  38. 37 CONST
  39. 38 cNamePos = 4; (* change to 3 if it is required to locate segments rather than classes *)
  40. 39
  41. 40 CONST
  42. 41 Delim = Str.CHARSET{' '};
  43. ***** ^ not supported yet
  44. ***** ^ not supported yet
  45. 42 ImageBufMax=4000H;
  46. 43
  47. 44 TYPE
  48. 45 StringType = ARRAY [0..31] OF CHAR;
  49. 46
  50. 47 LongStringType = ARRAY [0..511] OF CHAR;
  51. 48
  52. 49 UnitType = RECORD
  53. 50 Name:StringType;
  54. 51 Start,Stop:LONGCARD;
  55. 52 StartSeg:CARDINAL;
  56. 53 Diff:CARDINAL;
  57. 54 Located:BOOLEAN;
  58. 55 Rom:BOOLEAN;
  59. 56 MemStart:LONGCARD;
  60. 57 END;
  61. 58
  62. 59 ExeHeaderType = RECORD
  63. 60 magic : CARDINAL;
  64. 61 sizemod512 : CARDINAL;
  65. 62 sizediv512 : CARDINAL;
  66. 63 numrelocitem : CARDINAL;
  67. 64 headerparas : CARDINAL;
  68. 65 heapminparas : CARDINAL;
  69. 66 heapmaxparas : CARDINAL;
  70. 67 initialss : CARDINAL;
  71. 68 initialsp : CARDINAL;
  72. 69 checksum : CARDINAL;
  73. 70 initialip : CARDINAL;
  74. 71 initialcs : CARDINAL;
  75. 72 relocations : CARDINAL;
  76. 73 ovrlay : CARDINAL;
  77. 74 undocumented : CARDINAL;
  78. 75 (* relocation items follow *)
  79. 76 END;
  80. 77
  81. 78 ImageType = RECORD
  82. 79 index:CARDINAL;
  83. 80 pos,size:LONGCARD;
  84. 81 buf:ARRAY [0..ImageBufMax] OF SHORTCARD; (* note extra byte at start *)
  85. 82 (* this is required to deal with fixups to the last byte of the buffer *)
  86. 83 (* which are deferred until the next buffer load is read *)
  87. 84 END;
  88. 85
  89. 86 VAR
  90. 87 ExeFile,
  91. 88 MapFile,
  92. 89 MemFile,
  93. 90 Mp2File : FIO.File;
  94. 91
  95. 92 BinFile : ARRAY[1..4] OF FIO.File;
  96. 93
  97. 94 MemWidth : CARDINAL;
  98. 95
  99. 96 Image : ImageType;
  100. 97
  101. 98 ExeHeader : ExeHeaderType;
  102. 99
  103. 100 HeaderSize:LONGCARD; (* size of exeheader in bytes *)
  104. 101
  105. 102 NosUnit:CARDINAL;
  106. 103
  107. 104 Unit:ARRAY [1..300] OF UnitType;
  108. 105
  109. 106 PROCEDURE ReadHex( s:ARRAY OF BYTE; i:CARDINAL ):LONGCARD;
  110. 107 VAR
  111. 108 res:LONGCARD;
  112. 109 c:SHORTCARD;
  113. 110 BEGIN
  114. 111 res := 0;
  115. 112 LOOP
  116. 113 c := SHORTCARD(s[i]);
  117. 114 INC(i);
  118. 115 CASE CHAR(c) OF
  119. 116 | 'A'..'F': c := c - ( SHORTCARD('A') - 10 ) ;
  120. 117 | '0'..'9': c := c - SHORTCARD('0');
  121. 118 ELSE EXIT;
  122. 119 END;
  123. 120 res := res * 16 + VAL(LONGCARD, c );
  124. 121 END;
  125. 122 RETURN res;
  126. 123 END ReadHex;
  127. 124
  128. 125 PROCEDURE ReadMapFile;
  129. 126 VAR
  130. 127 cname,token:StringType;
  131. 128 line:LongStringType;
  132. 129 BEGIN
  133. 130 NosUnit := 0;
  134. 131 REPEAT
  135. 132 FIO.RdStr(MapFile,line) ;
  136. 133 UNTIL (line[0]<>CHAR(0)) AND (line[1]>='0') AND (line[1]<='9') ;
  137. 134 LOOP
  138. 135 IF Str.Length(line) < 40 THEN EXIT END;
  139. 136 Str.Item( cname, line, Delim, cNamePos );
  140. 137 IF ( NosUnit = 0 )
  141. 138 OR ( Str.Compare(cname,Unit[NosUnit].Name) <> 0 )
  142. 139 THEN
  143. 140 INC(NosUnit);
  144. 141 WITH Unit[NosUnit] DO
  145. 142 Name := cname;
  146. 143 Str.Item( token, line, Delim, 0 );
  147. 144 Start := ReadHex( token,0 );
  148. 145 StartSeg := CARDINAL(Start DIV 16);
  149. 146 Located := FALSE;
  150. 147 Rom := FALSE;
  151. 148 Diff := 0;
  152. 149 END;
  153. 150 END;
  154. 151 IF ( NosUnit <> 0 ) THEN
  155. 152 Str.Item( token, line, Delim, 1 );
  156. 153 Unit[NosUnit].Stop := ReadHex( token, 0 );
  157. 154 END;
  158. 155 FIO.RdStr(MapFile,line);
  159. 156 END;
  160. 157 IF NosUnit = 0 THEN
  161. 158 IO.WrStr('Bad .map file');
  162. 159 HALT;
  163. 160 END;
  164. 161 Unit[NosUnit+1] := Unit[NosUnit]; (* sentinel *)
  165. 162 END ReadMapFile;
  166. 163
  167. 164 PROCEDURE ClassSearch( cname:ARRAY OF CHAR ):CARDINAL;
  168. 165 VAR i:CARDINAL;
  169. 166 BEGIN
  170. 167 i := 1;
  171. 168 WHILE ( i <= NosUnit ) AND ( Str.Compare( Unit[i].Name, cname ) <> 0 ) DO
  172. 169 INC(i);
  173. 170 END;
  174. 171 RETURN i;
  175. 172 END ClassSearch;
  176. 173
  177. 174 PROCEDURE ReadMemFile;
  178. 175 VAR
  179. 176 cname,token:StringType;
  180. 177 line:LongStringType;
  181. 178 memstart,memstop:LONGCARD;
  182. 179 rom:BOOLEAN;
  183. 180 ram:BOOLEAN;
  184. 181 i,item:CARDINAL;
  185. 182 BEGIN
  186. 183 MemWidth := 1; (* default width *)
  187. 184 LOOP
  188. 185 FIO.RdStr(MemFile,line);
  189. 186 Str.Item( token, line, Delim, 0 );
  190. 187 ram := FALSE;
  191. 188 rom := FALSE;
  192. 189 IF Str.Compare(token,'') = 0 THEN
  193. 190 EXIT;
  194. 191 ELSIF Str.Compare(token,'rom') = 0 THEN
  195. 192 rom := TRUE;
  196. 193 ELSIF Str.Compare(token,'ram') = 0 THEN
  197. 194 ram := TRUE;
  198. 195 ELSIF Str.Compare(token,'width') = 0 THEN
  199. 196 Str.Item( token, line, Delim, 1 );
  200. 197 MemWidth := CARDINAL( ReadHex( token,0 ) );
  201. 198 ELSE
  202. 199 IO.WrStr('Bad .mem file');
  203. 200 HALT;
  204. 201 END;
  205. 202 IF rom OR ram THEN
  206. 203 Str.Item( token, line, Delim, 1 );
  207. 204 memstart := ReadHex( token,0 );
  208. 205 Str.Item( token, line, Delim, 2 );
  209. 206 memstop := ReadHex( token,0 );
  210. 207 item := 3;
  211. 208 LOOP
  212. 209 Str.Item( cname, line, Delim, item );
  213. 210 INC(item);
  214. 211 IF cname[0]=CHAR(0) THEN
  215. 212 EXIT;
  216. 213 END;
  217. 214 (* search table *)
  218. 215 i := ClassSearch( cname );
  219. 216 IF i > NosUnit THEN
  220. 217 IO.WrStr('Warning: ');
  221. 218 IO.WrStr(cname);
  222. 219 IO.WrStr(' not found in .map file');
  223. 220 IO.WrLn;
  224. 221 ELSE
  225. 222 INC( memstart, LONGCARD( CARDINAL(Unit[i].Start-memstart) MOD 16 ));
  226. 223 Unit[i].MemStart := memstart;
  227. 224 IF Unit[i].Located THEN
  228. 225 IO.WrStr('Warning : ');
  229. 226 IO.WrStr(cname);
  230. 227 IO.WrStr(' specified more than once in .mem file');
  231. 228 IO.WrLn;
  232. 229 END;
  233. 230 Unit[i].Located := TRUE;
  234. 231 Unit[i].Rom := rom;
  235. 232 Unit[i].Diff := CARDINAL( (Unit[i].Start-memstart) DIV 16 );
  236. 233 INC( memstart, Unit[i].Stop - Unit[i].Start );
  237. 234 IF memstart > memstop THEN
  238. 235 IO.WrStr('Warning: not enough memory for ');
  239. 236 IO.WrStr(cname);
  240. 237 IO.WrLn;
  241. 238 END;
  242. 239 END;
  243. 240 END;
  244. 241 END;
  245. 242 END;
  246. 243 END ReadMemFile;
  247. 244
  248. 245 PROCEDURE NewSeg( seg,off:CARDINAL ):CARDINAL;
  249. 246 VAR loc:LONGCARD;
  250. 247 k:CARDINAL;
  251. 248 BEGIN
  252. 249 loc := 16*VAL(LONGCARD,seg) + VAL(LONGCARD,off);
  253. 250 k := 1;
  254. 251 (* search for location segment = k *)
  255. 252 WHILE ( k <= NosUnit ) AND ( loc >= Unit[k].Start ) DO INC(k) END;
  256. 253 DEC(k);
  257. 254 RETURN seg - Unit[k].Diff;
  258. 255 END NewSeg;
  259. 256
  260. 257 PROCEDURE ChkRead( VAR buf:ARRAY OF BYTE; count:CARDINAL );
  261. 258 BEGIN
  262. 259 IF FIO.RdBin( ExeFile, buf, count ) <> count THEN
  263. 260 IO.WrStr('?? on read');
  264. 261 HALT;
  265. 262 END;
  266. 263 END ChkRead;
  267. 264
  268. 265 PROCEDURE GetByte():SHORTCARD;
  269. 266 VAR
  270. 267 pindex:CARDINAL;
  271. 268 fixlocabs:LONGCARD;
  272. 269 target:CARDINAL;
  273. 270 wp:POINTER TO CARDINAL;
  274. 271 exefix:RECORD off,seg:CARDINAL END;
  275. 272 dummy:CARDINAL;
  276. 273 i,j:CARDINAL;
  277. 274 BEGIN
  278. 275 IF Image.pos >= Image.size THEN
  279. 276 INC(Image.pos);
  280. 277 RETURN 99H;
  281. 278 END;
  282. 279 IF Image.index >= ImageBufMax THEN
  283. 280 IF Image.pos = 0 THEN
  284. 281 Image.index := 1;
  285. 282 ELSE
  286. 283 Image.buf[0] := Image.buf[ImageBufMax];
  287. 284 Image.index := 0;
  288. 285 END;
  289. 286 FIO.Seek( ExeFile, HeaderSize+Image.pos+LONGCARD(1-Image.index) );
  290. 287 dummy := FIO.RdBin( ExeFile, Image.buf[1], SIZE(Image.buf)-1 );
  291. 288
  292. 289 (* now apply segment fixups for this buffer *)
  293. 290 FIO.Seek( ExeFile, LONGCARD(ExeHeader.relocations) );
  294. 291 FOR i := 1 TO ExeHeader.numrelocitem DO
  295. 292 ChkRead( exefix, SIZE(exefix) );
  296. 293 fixlocabs := VAL(LONGCARD,exefix.off)+16*VAL(LONGCARD,exefix.seg);
  297. 294 IF fixlocabs - Image.pos <= ImageBufMax THEN
  298. 295 pindex := CARDINAL(fixlocabs-Image.pos) + Image.index;
  299. 296 IF pindex < ImageBufMax THEN
  300. 297 wp := ADR(Image.buf[pindex]);
  301. 298 target := wp^;
  302. 299 j := 0;
  303. 300 LOOP (* search for target segment = j *)
  304. 301 INC(j);
  305. 302 IF ( j > NosUnit ) OR ( target < Unit[j].StartSeg ) THEN
  306. 303 EXIT;
  307. 304 END;
  308. 305 END;
  309. 306 DEC(j);
  310. 307 wp^ := target - Unit[j].Diff;
  311. 308 END;
  312. 309 END;
  313. 310 END;
  314. 311 END;
  315. 312 INC(Image.pos);
  316. 313 INC(Image.index);
  317. 314 RETURN Image.buf[Image.index-1];
  318. 315 END GetByte;
  319. 316
  320. 317 VAR OutPos : LONGCARD;
  321. 318
  322. 319 PROCEDURE PutByte( b:SHORTCARD );
  323. 320 BEGIN
  324. 321 FIO.WrBin( BinFile[1+(CARDINAL(OutPos) MOD MemWidth)], b, 1 );
  325. 322 INC( OutPos );
  326. 323 END PutByte;
  327. 324
  328. 325 PROCEDURE PutUnit( unit:UnitType );
  329. 326 VAR
  330. 327 total:LONGCARD;
  331. 328 dummy:SHORTCARD;
  332. 329 buf:ARRAY [0..15] OF SHORTCARD;
  333. 330 i,count,seg,off:CARDINAL;
  334. 331 BEGIN
  335. 332 IF NOT unit.Located THEN
  336. 333 IO.WrStr('Warning: ');
  337. 334 IO.WrStr(unit.Name);
  338. 335 IO.WrStr(' not located ');
  339. 336 IO.WrLn;
  340. 337 END;
  341. 338 total := unit.Stop-unit.Start;
  342. 339 IF total > 0 THEN
  343. 340 IF unit.Rom THEN
  344. 341 WHILE Image.pos < unit.Start DO
  345. 342 dummy := GetByte();
  346. 343 END;
  347. 344 IF unit.Start <> Image.pos THEN
  348. 345 IO.WrStr('Overshoot error??');
  349. 346 IO.WrLngHex(unit.Start,6);
  350. 347 IO.WrLngHex(Image.pos,6);
  351. 348 HALT;
  352. 349 END;
  353. 350 IF OutPos = 0 THEN
  354. 351 OutPos := unit.MemStart;
  355. 352 ELSE
  356. 353 WHILE OutPos < unit.MemStart DO
  357. 354 PutByte(0FFH);
  358. 355 END;
  359. 356 END;
  360. 357 WHILE total > 0 DO
  361. 358 PutByte( GetByte() );
  362. 359 DEC(total);
  363. 360 END;
  364. 361 END;
  365. 362 END;
  366. 363 END PutUnit;
  367. 364
  368. 365 PROCEDURE WriteBinFile;
  369. 366 VAR
  370. 367 i:CARDINAL;
  371. 368 BEGIN
  372. 369 ChkRead( ExeHeader, SIZE(ExeHeader) );
  373. 370 HeaderSize := VAL(LONGCARD,ExeHeader.headerparas)*16;
  374. 371 Image.size := FIO.Size(ExeFile)-HeaderSize;
  375. 372 Image.pos := 0;
  376. 373 Image.index := ImageBufMax;
  377. 374 OutPos := 0;
  378. 375 FOR i := 1 TO NosUnit DO
  379. 376 PutUnit( Unit[i] );
  380. 377 END;
  381. 378 END WriteBinFile;
  382. 379
  383. 380 PROCEDURE Hex(n:CARDINAL):CHAR;
  384. 381 BEGIN
  385. 382 n := n MOD 16;
  386. 383 IF n > 9 THEN
  387. 384 RETURN CHAR( n + ORD('A') - 10 )
  388. 385 ELSE
  389. 386 RETURN CHAR( n + ORD('0') );
  390. 387 END;
  391. 388 END Hex;
  392. 389
  393. 390 PROCEDURE EditMap;
  394. 391 VAR
  395. 392 line:LongStringType;
  396. 393 i:CARDINAL;
  397. 394 seg,off:CARDINAL;
  398. 395 addr:LONGCARD;
  399. 396 k:CARDINAL;
  400. 397 cname:StringType;
  401. 398 start:RECORD
  402. 399 off,seg:CARDINAL;
  403. 400 END;
  404. 401 BEGIN
  405. 402 k := 0;
  406. 403 FIO.Seek(MapFile,0);
  407. 404 LOOP
  408. 405 FIO.RdStr(MapFile,line);
  409. 406 IF FIO.EOF THEN EXIT END;
  410. 407 IF ( line[0] = ' ' ) AND ( line[6] = 'H' ) THEN
  411. 408 Str.Item( cname, line, Delim, cNamePos );
  412. 409 k := ClassSearch(cname);
  413. 410 IF k <= NosUnit THEN
  414. 411 FOR i := 0 TO 7 BY 7 DO
  415. 412 addr := ReadHex(line,i+1);
  416. 413 seg := CARDINAL(addr DIV 16);
  417. 414 off := CARDINAL(addr) MOD 16;
  418. 415 seg := seg - Unit[k].Diff;
  419. 416 line[i+4] := Hex(seg); seg := seg DIV 16;
  420. 417 line[i+3] := Hex(seg); seg := seg DIV 16;
  421. 418 line[i+2] := Hex(seg); seg := seg DIV 16;
  422. 419 line[i+1] := Hex(seg); seg := seg DIV 16;
  423. 420 END;
  424. 421 END;
  425. 422 ELSIF ( line[0] = 'P' ) THEN
  426. 423 seg := CARDINAL(ReadHex(line,23));
  427. 424 off := CARDINAL(ReadHex(line,28));
  428. 425 seg := NewSeg(seg,off);
  429. 426 start.seg := seg;
  430. 427 start.off := off;
  431. 428 line[26] := Hex(seg); seg := seg DIV 16;
  432. 429 line[25] := Hex(seg); seg := seg DIV 16;
  433. 430 line[24] := Hex(seg); seg := seg DIV 16;
  434. 431 line[23] := Hex(seg); seg := seg DIV 16;
  435. 432 ELSE
  436. 433 FOR i := 5 TO Str.Length(line) DO
  437. 434 IF ( line[i] = ':' ) THEN
  438. 435 seg := CARDINAL(ReadHex(line,i-4));
  439. 436 off := CARDINAL(ReadHex(line,i+1));
  440. 437 seg := NewSeg( seg, off );
  441. 438 line[i-1] := Hex(seg); seg := seg DIV 16;
  442. 439 line[i-2] := Hex(seg); seg := seg DIV 16;
  443. 440 line[i-3] := Hex(seg); seg := seg DIV 16;
  444. 441 line[i-4] := Hex(seg); seg := seg DIV 16;
  445. 442 END;
  446. 443 END;
  447. 444 END;
  448. 445 IF line[0] <> CHAR(0) THEN
  449. 446 FIO.WrStr(Mp2File,line);
  450. 447 END;
  451. 448 FIO.WrLn(Mp2File);
  452. 449 END;
  453. 450 END EditMap;
  454. 451
  455. 452 PROCEDURE PrintSummary;
  456. 453 VAR i:CARDINAL;
  457. 454 BEGIN
  458. 455 FOR i := 1 TO NosUnit DO
  459. 456 WITH Unit[i] DO
  460. 457 IO.WrStr(' Start='); IO.WrLngHex(Start,6);
  461. 458 IO.WrStr(' ');
  462. 459 IO.WrStr(' Stop='); IO.WrLngHex(Stop,6);
  463. 460 IO.WrStr(' ');
  464. 461 IF Located THEN
  465. 462 IO.WrStr('MemStart=');
  466. 463 IO.WrLngHex(MemStart,6);
  467. 464 IO.WrStr(' ');
  468. 465 ELSE
  469. 466 IO.WrStr('Not located ');
  470. 467 END;
  471. 468 IO.WrStr(Name);
  472. 469 IO.WrLn;
  473. 470 END;
  474. 471 END;
  475. 472 END PrintSummary;
  476. 473
  477. 474 PROCEDURE GiveBuf( f:FIO.File );
  478. 475 TYPE buf = ARRAY [1..800H+FIO.BufferOverhead] OF SHORTCARD;
  479. 476 VAR bufp :POINTER TO buf;
  480. 477 BEGIN
  481. 478 Storage.ALLOCATE(bufp,SIZE(buf));
  482. 479 FIO.AssignBuffer(f,bufp^);
  483. 480 END GiveBuf;
  484. 481
  485. 482 PROCEDURE Create(ext:ARRAY OF CHAR):FIO.File;
  486. 483 VAR
  487. 484 filename:FIO.PathStr;
  488. 485 res:FIO.File;
  489. 486 BEGIN
  490. 487 Str.Concat( filename, Lib.CommandLine^, ext );
  491. 488 res := FIO.Create(filename);
  492. 489 GiveBuf(res);
  493. 490 RETURN res;
  494. 491 END Create;
  495. 492
  496. 493 PROCEDURE Open(ext:ARRAY OF CHAR):FIO.File;
  497. 494 VAR
  498. 495 filename:FIO.PathStr;
  499. 496 res:FIO.File;
  500. 497 BEGIN
  501. 498 Str.Concat( filename, Lib.CommandLine^, ext );
  502. 499 res := FIO.Open(filename);
  503. 500 IF Str.Compare(ext, '.exe') # 0 THEN
  504. 501 GiveBuf(res);
  505. 502 END;
  506. 503 RETURN res;
  507. 504 END Open;
  508. 505
  509. 506 BEGIN
  510. 507 IO.WrStr('TopSpeed Locator Version 1.10');
  511. 508 IO.WrLn;
  512. 509 IO.WrStr('Copyright (C) 1987-1992 Clarion Software Corporation');
  513. 510 IO.WrLn;
  514. 511
  515. 512 ExeFile := Open('.exe'); (* no buffering because random access *)
  516. 513 MemFile := Open('.mem');
  517. 514 MapFile := Open('.map');
  518. 515 Mp2File := Create('.mp2');
  519. 516 ReadMapFile;
  520. 517 ReadMemFile;
  521. 518 BinFile[1] := Create('.bn1');
  522. 519 IF MemWidth > 1 THEN
  523. 520 BinFile[2] := Create('.bn2');
  524. 521 END;
  525. 522 IF MemWidth > 2 THEN
  526. 523 BinFile[3] := Create('.bn3');
  527. 524 BinFile[4] := Create('.bn4');
  528. 525 END;
  529. 526 (*PrintSummary;*)
  530. 527 WriteBinFile;
  531. 528 EditMap;
  532. 529 FIO.Close(ExeFile);
  533. 530 FIO.Close(MemFile);
  534. 531 FIO.Close(MapFile);
  535. 532 FIO.Close(Mp2File);
  536. 533 FIO.Close(BinFile[1]);
  537. 534 IF MemWidth > 1 THEN
  538. 535 FIO.Close(BinFile[2]);
  539. 536 END;
  540. 537 IF MemWidth > 2 THEN
  541. 538 FIO.Close(BinFile[3]);
  542. 539 FIO.Close(BinFile[4]);
  543. 540 END;
  544. 541 END tslocate.
  545. 2 errors