ZONES.PAS 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. (* programme comment‚ et expliqu‚ dans le livre *)
  2. (* LE DESASSEMBLEUR 8086 COLIBRI, publi‚ par *)
  3. (* L'INSTITUT PASCAL: *)
  4. (* 26 Rue Lamartine, 75009 PARIS *)
  5. (* Tel: (1) 42.85.10.82 *)
  6. (*$r+*)
  7. program gestion_zones_de_desassemblage;
  8. type string2= string[2];
  9. string4= string[4];
  10. string64= string[64];
  11. string127= string[127];
  12. set_of_char= set of char;
  13. t_fiche= record
  14. debut: integer;
  15. type_zone: char;
  16. end;
  17. t_pointeur_zone= ^t_cellule_zone;
  18. t_cellule_zone= record
  19. debut: integer;
  20. type_zone: char;
  21. numero_fiche: integer;
  22. pt_inferieurs, pt_superieurs: t_pointeur_zone;
  23. end;
  24. var choix, choix1: char;
  25. nom_fichier: string64;
  26. fiche: t_fiche;
  27. fichier: file of t_fiche;
  28. resultat_entree_sortie: byte;
  29. racine_zones: t_pointeur_zone;
  30. sommet_tas: ^integer;
  31. procedure stop;
  32. var l_stop: char;
  33. begin
  34. read(kbd, l_stop);
  35. end;
  36. function f_octet_hexadecimal(p_octet: byte): string2;
  37. const kt_hexa: array[0..15] of char= '0123456789ABCDEF';
  38. begin
  39. f_octet_hexadecimal:= concat(kt_hexa[p_octet div 16],
  40. kt_hexa[p_octet mod 16]);
  41. end;
  42. function f_entier_hexadecimal(p_entier: integer): string4;
  43. begin
  44. f_entier_hexadecimal:= concat(f_octet_hexadecimal(hi(p_entier)),
  45. f_octet_hexadecimal(lo(p_entier)));
  46. end;
  47. function f_lis_commande(p_ensemble_ok: set_of_char): char;
  48. var l_touche: char;
  49. begin
  50. repeat
  51. read(kbd, l_touche);
  52. l_touche:= upcase(l_touche); write(l_touche);
  53. until l_touche in p_ensemble_ok;
  54. f_lis_commande:= l_touche;
  55. end;
  56. function f_fichier_existe(p_nom_fichier: string64): boolean;
  57. begin
  58. assign(fichier, p_nom_fichier);
  59. (*$i-*)
  60. reset(fichier);
  61. (*$i+*)
  62. f_fichier_existe:= ioresult= 0;
  63. close(fichier);
  64. end;
  65. procedure change_nom_fichier;
  66. begin
  67. write('nom <a:zones.dta> ? '); readln(nom_fichier);
  68. end;
  69. procedure cree_fichier;
  70. begin
  71. if f_fichier_existe(nom_fichier)
  72. then begin
  73. writeln;
  74. write('le fichier existe d‚j…. D‚truire, Quitter ? ');
  75. if f_lis_commande(['D', 'Q'])<> 'D'
  76. then begin
  77. writeln;
  78. exit;
  79. end;
  80. end;
  81. assign(fichier, nom_fichier);
  82. rewrite(fichier);
  83. close(fichier);
  84. end;
  85. procedure ouvre_fichier;
  86. begin
  87. assign(fichier, nom_fichier);
  88. (*$i-*)
  89. reset(fichier);
  90. (*$i+*)
  91. resultat_entree_sortie:= ioresult;
  92. if resultat_entree_sortie<> 0
  93. then writeln('le fichier ', nom_fichier, ' n''a pas ‚t‚ ouvert');
  94. end;
  95. procedure affiche_fiche(p_numero, p_debut: integer; p_type_zone: char);
  96. begin
  97. write(p_numero: 5);
  98. write(' $', f_entier_hexadecimal(p_debut));
  99. write(p_type_zone: 2);
  100. end;
  101. procedure liste_fichier;
  102. var l_numero_fiche: integer;
  103. l_dernier_numero: integer;
  104. begin
  105. ouvre_fichier;
  106. if resultat_entree_sortie<> 0
  107. then exit;
  108. repeat
  109. write('num‚ro d‚but <0> ? '); readln(l_numero_fiche);
  110. until (l_numero_fiche>= 0) and (l_numero_fiche< filesize(fichier));
  111. write('num‚ro fin <', filesize(fichier)- 1, '> ? '); readln(l_dernier_numero);
  112. seek(fichier, l_numero_fiche);
  113. while not eof(fichier) and (l_numero_fiche<= l_dernier_numero) do
  114. begin
  115. read(fichier, fiche);
  116. with fiche do
  117. affiche_fiche(l_numero_fiche, debut, type_zone);
  118. writeln;
  119. l_numero_fiche:= l_numero_fiche+ 1;
  120. end;
  121. close(fichier);
  122. end;
  123. procedure ajoute_fichier;
  124. begin
  125. ouvre_fichier;
  126. if resultat_entree_sortie<> 0
  127. then exit;
  128. seek(fichier, filesize(fichier));
  129. repeat
  130. writeln;
  131. writeln('ajoute la fiche: ', filepos(fichier));
  132. write('adresse d‚but <$1234> ? '); readln(fiche.debut);
  133. repeat
  134. write('type Code, Ascii, Hex ? ');
  135. read(kbd, fiche.type_zone); writeln(fiche.type_zone);
  136. if fiche.type_zone in ['A', 'H', 'C']
  137. then fiche.type_zone:= chr(ord(fiche.type_zone)+ 32);
  138. until fiche.type_zone in ['c', 'h', 'a'];
  139. write(fichier, fiche);
  140. write('Continuer, Quitter ? ');
  141. read(kbd, choix1); writeln(choix1);
  142. until upcase(choix1)= 'Q';
  143. close(fichier);
  144. end;
  145. procedure modifie_fichier;
  146. var l_numero_fiche: integer;
  147. begin
  148. ouvre_fichier;
  149. if resultat_entree_sortie<> 0
  150. then exit;
  151. repeat
  152. writeln;
  153. repeat
  154. write('modifie la fiche num‚ro <0..', filesize(fichier)- 1, '> ? ');
  155. readln(l_numero_fiche);
  156. until (l_numero_fiche>= 0) and (l_numero_fiche<= filesize(fichier));
  157. seek(fichier, l_numero_fiche); read(fichier, fiche);
  158. with fiche do
  159. affiche_fiche(l_numero_fiche, debut, type_zone);
  160. writeln;
  161. write('adresse d‚but <$1234> ? '); readln(fiche.debut);
  162. repeat
  163. write('type Code, Ascii, Hex ? ');
  164. read(kbd, fiche.type_zone); writeln(fiche.type_zone);
  165. if fiche.type_zone in ['A', 'H', 'C']
  166. then fiche.type_zone:= chr(ord(fiche.type_zone)+ 32);
  167. until fiche.type_zone in ['c', 'h', 'a', '?'];
  168. seek(fichier, l_numero_fiche); write(fichier, fiche);
  169. write('Continuer, Quitter ? ');
  170. read(kbd, choix1); writeln(choix1);
  171. until upcase(choix1)= 'Q';
  172. close(fichier);
  173. end;
  174. procedure supprime_fiche;
  175. var l_numero_fiche: integer;
  176. begin
  177. ouvre_fichier;
  178. if resultat_entree_sortie<> 0
  179. then exit;
  180. repeat
  181. writeln;
  182. repeat
  183. write('supprimer la fiche num‚ro <0..', filesize(fichier)- 1, '> ? ');
  184. readln(l_numero_fiche);
  185. until (l_numero_fiche>= 0) and (l_numero_fiche< filesize(fichier));
  186. seek(fichier, l_numero_fiche); read(fichier, fiche);
  187. with fiche do
  188. affiche_fiche(l_numero_fiche, debut, type_zone);
  189. write('. sUpprime ? '); read(kbd, choix1); writeln(choix1);
  190. if upcase(choix1)= 'U'
  191. then begin
  192. fiche.type_zone:= '?';
  193. seek(fichier, l_numero_fiche); write(fichier, fiche);
  194. end;
  195. write('Continuer, Quitter ? ');
  196. read(kbd, choix1); writeln(choix1);
  197. until upcase(choix1)= 'Q';
  198. close(fichier);
  199. end;
  200. procedure ajoute_depuis_fichier_text;
  201. var l_entree: text;
  202. l_nom_entree: string64;
  203. l_ligne_entree: string127;
  204. l_indice: integer;
  205. l_debut: integer;
  206. l_type: char;
  207. l_erreur_numerique: boolean;
  208. l_erreur_entree: boolean;
  209. l_fin_fichier_actuelle: integer;
  210. procedure calcule_debut;
  211. var l_caractere: char;
  212. begin
  213. l_erreur_numerique:= false;
  214. l_debut:= 0;
  215. repeat
  216. l_caractere:= upcase(l_ligne_entree[l_indice]);
  217. if l_caractere in ['0'..'9']
  218. then l_debut:= l_debut* 16+ ord(l_caractere)- 48
  219. else
  220. if l_caractere in ['A'..'F']
  221. then l_debut:= l_debut* 16+ ord(l_caractere)- 55
  222. else
  223. if l_caractere<> ' '
  224. then l_erreur_numerique:= true;
  225. l_indice:= l_indice+ 1;
  226. until l_erreur_numerique or (l_caractere= ' ');
  227. end;
  228. begin
  229. ouvre_fichier;
  230. if resultat_entree_sortie<> 0
  231. then exit;
  232. seek(fichier, filesize(fichier));
  233. l_fin_fichier_actuelle:= filesize(fichier);
  234. write('nom du fichier d''entr‚e <zones.pas> ? '); readln(l_nom_entree);
  235. assign(l_entree, l_nom_entree);
  236. (*$i-*)
  237. reset(l_entree);
  238. (*$i+*)
  239. if ioresult<> 0
  240. then begin
  241. write('erreur ouverture ', l_nom_entree);
  242. close(l_entree);
  243. close(fichier);
  244. exit;
  245. end;
  246. l_erreur_entree:= false;
  247. while not eof(l_entree) do
  248. begin
  249. writeln;
  250. readln(l_entree, l_ligne_entree);
  251. write(l_ligne_entree);
  252. if length(l_ligne_entree)> 0
  253. then
  254. if l_ligne_entree[1]= '$'
  255. then begin
  256. l_indice:= 2;
  257. calcule_debut;
  258. if l_erreur_numerique
  259. then begin
  260. writeln; write('^': l_indice);
  261. write(' erreur num‚rique');
  262. l_erreur_entree:= true;
  263. end
  264. else begin
  265. while l_ligne_entree= ' ' do
  266. l_indice:= l_indice+ 1;
  267. l_type:= l_ligne_entree[l_indice];
  268. if not (l_type in ['c', 'h', 'a'])
  269. then begin
  270. writeln; write('^': l_indice);
  271. write(' erreur de type de zone: que c a h');
  272. l_erreur_entree:= true;
  273. end
  274. else begin
  275. fiche.debut:= l_debut;
  276. fiche.type_zone:= l_type;
  277. write(fichier, fiche);
  278. write(' ok. A ajout‚');
  279. end;
  280. end;
  281. end
  282. else write('ne commence pas par $');
  283. writeln;
  284. end;
  285. if l_erreur_entree
  286. then begin
  287. writeln('Il y a eu des erreurs. Supprime toutes les entr‚es');
  288. stop;
  289. seek(fichier, l_fin_fichier_actuelle);
  290. truncate(fichier);
  291. end;
  292. close(fichier);
  293. close(l_entree);
  294. end;
  295. procedure construis_index;
  296. var l_numero_fiche: integer;
  297. l_adresse_debut, l_adresse_fin: integer;
  298. procedure ajoute(var p: t_pointeur_zone);
  299. begin
  300. if p= nil
  301. then begin
  302. new(p);
  303. p^.debut:= fiche.debut;
  304. p^.type_zone:= fiche.type_zone;
  305. p^.numero_fiche:= l_numero_fiche;
  306. p^.pt_inferieurs:= nil; p^.pt_superieurs:= nil;
  307. end
  308. else
  309. if fiche.debut- $8000< p^.debut- $8000
  310. then ajoute(p^.pt_inferieurs)
  311. else
  312. if fiche.debut- $8000> p^.debut- $8000
  313. then ajoute(p^.pt_superieurs)
  314. else begin
  315. writeln('mˆme d‚but. Ajouter ? ');
  316. read(kbd, choix1); writeln(choix1);
  317. if upcase(choix1)= 'a'
  318. then ajoute(p^.pt_superieurs);
  319. end;
  320. end;
  321. begin
  322. ouvre_fichier;
  323. if resultat_entree_sortie<> 0
  324. then exit;
  325. l_numero_fiche:= 0;
  326. write('adresse d‚but <$1234> ? '); readln(l_adresse_debut);
  327. write('adresse fin <$ABCD> ? '); readln(l_adresse_fin);
  328. release(sommet_tas);
  329. racine_zones:= nil;
  330. while not eof(fichier) do
  331. begin
  332. read(fichier, fiche);
  333. with fiche do
  334. begin
  335. if (debut- $8000>= l_adresse_debut- $8000) and (debut- $8000<= l_adresse_fin- $8000)
  336. then begin
  337. affiche_fiche(l_numero_fiche, debut, type_zone);
  338. if fiche.type_zone in ['a', 'h', 'c']
  339. then ajoute(racine_zones)
  340. else write(' -- non ajout‚');
  341. writeln;
  342. end
  343. end;
  344. l_numero_fiche:= l_numero_fiche+ 1;
  345. end;
  346. close(fichier);
  347. end;
  348. procedure liste_index;
  349. procedure affiche(p: t_pointeur_zone);
  350. begin
  351. if p<> nil
  352. then begin
  353. affiche(p^.pt_inferieurs);
  354. with p^ do
  355. affiche_fiche(numero_fiche, debut, type_zone);
  356. writeln;
  357. affiche(p^.pt_superieurs);
  358. end;
  359. end;
  360. begin
  361. affiche(racine_zones);
  362. end;
  363. procedure interroge_index;
  364. var l_adresse_debut, l_adresse_fin: integer;
  365. l_premiere_adresse: boolean;
  366. l_numero_fiche: integer;
  367. l_doit_ajouter_fin: boolean;
  368. l_type_zone: char;
  369. procedure affiche(p: t_pointeur_zone);
  370. begin
  371. if p<> nil
  372. then begin
  373. affiche(p^.pt_inferieurs);
  374. with p^ do
  375. begin
  376. if (debut- $8000>= l_adresse_debut- $8000)
  377. and (debut- 1- $8000<= l_adresse_fin- $8000)
  378. then begin
  379. if l_premiere_adresse
  380. then l_premiere_adresse:= false
  381. else begin
  382. writeln(f_entier_hexadecimal(debut- 1),
  383. l_type_zone: 2);
  384. l_doit_ajouter_fin:= false;
  385. end;
  386. if (debut- $8000<= l_adresse_fin- $8000)
  387. then begin
  388. write(numero_fiche: 4, ' $', f_entier_hexadecimal(debut), '-');
  389. l_type_zone:= type_zone;
  390. l_doit_ajouter_fin:= true;
  391. end;
  392. end;
  393. end;
  394. affiche(p^.pt_superieurs);
  395. end;
  396. end;
  397. begin
  398. write('adresse d‚but <$1234> ? '); readln(l_adresse_debut);
  399. write('adresse fin <$ABCD> ? '); readln(l_adresse_fin);
  400. l_premiere_adresse:= true;
  401. l_doit_ajouter_fin:= false;
  402. affiche(racine_zones);
  403. if l_doit_ajouter_fin
  404. then writeln(f_entier_hexadecimal(l_adresse_fin), l_type_zone: 2);
  405. end;
  406. procedure initialise;
  407. begin
  408. nom_fichier:= 'zones.dta';
  409. mark(sommet_tas);
  410. racine_zones:= nil;
  411. end;
  412. begin
  413. initialise;
  414. repeat
  415. writeln;
  416. writeln(nom_fichier);
  417. writeln('Cr‚e, Ajoute, Liste, Modifie, sUupprime, Nom');
  418. writeln('aJoute depuis text');
  419. write ('Tri, liSte index, Interroge, Quitte ? ');
  420. read(kbd, choix); writeln(choix); choix:= upcase(choix);
  421. case choix of
  422. 'A' : ajoute_fichier;
  423. 'C' : cree_fichier;
  424. 'I' : interroge_index;
  425. 'J' : ajoute_depuis_fichier_text;
  426. 'L' : liste_fichier;
  427. 'M' : modifie_fichier;
  428. 'N' : change_nom_fichier;
  429. 'R' : supprime_fiche;
  430. 'S' : liste_index;
  431. 'T' : construis_index;
  432. 'U' : supprime_fiche;
  433. end;
  434. until choix= 'Q';
  435. end.