APPENDere in Turbo Pascal per CP/M


di Francesco Sblendorio

Prerequisiti tecnici: conoscenza della gestione dei file di testo in Turbo Pascal

Consideriamo un programma scritto in Turbo Pascal 3 che si occupi, in sequenza, di:

  • Aprire un file di testo in scrittura, e scriverci una riga
  • Aprire lo stesso file in append, quindi scrittura in coda, e aggiungere una seconda riga
  • Aprire lo stesso file in lettura e stamparne il contenuto a video

Per esempio…

PROGRAM TestAppend;
VAR f:TEXT;
s:STRING[80];
BEGIN
  ASSIGN(f,'test.txt');

  REWRITE(f);
  WRITELN(f,'First row');
  CLOSE(f);

  APPEND(f);
  WRITELN(f,'Second row');
  CLOSE(f);

  RESET(f);
  WHILE NOT EOF(f) DO BEGIN
    READLN(f,s);
    WRITELN(s)
  END;
  CLOSE(f);
END.

Se compilato in Turbo Pascal 3 per MS-DOS, fila tutto liscio. Se compilato invece in Turbo Pascal 3 ma sotto CP/M in fase di compilazione riceveremo il seguente messaggio di errore:

Error 41: Unknown identifier or syntax error. Press <ESC>

Quindi nella versione CP/M del compilatore la procedura APPEND è semplicemente (e misteriosamente) scomparsa nonostante la sua indubbia utilità. Grazie però alla segnalazione di Marco Luciano sono riuscito a trovare presso questo link sul sito di Werner Cirsovius un suo lavoro del lontano 1988 (qui il disassemblato commentato), in pratica una implementazione in Assembly Z80 della procedura APPEND, valida però solo per i file di testo (non vale per i file binari), che quindi è valida per il nostro codice di esempio sopra riportato. Riporto in questa pagina di RetroAcademy esattamente il codice di Werner Cirsovius:

procedure append(var f:text);
{ ============================================================== }
{                                                                }
{ Emulation der MS-DOS TURBO PASCAL Prozedur APPEND fuer CP/M 80 }
{                                                                }
{ Der Aufruf der Prozedur muss folgende Gestalt haben :          }
{                                                                }
{ APPEND(TEXT_Datei);                                            }
{                                                                }
{ Die Datei 'TEXT_datei' vom Typ 'TEXT' muss nicht geoeffnet     }
{ sein. Wird die Datei nicht gefunden, so erhaelt die Variable   }
{ 'IORESULT' den Wert 01 (Siehe I/O Fehlermeldungen im Handbuch) }
{ Falls die Datei leer ist, so wird 02 zurueckgegeben            }
{ Damit obliegt es dem Programmierer, die Fehlermeldung zu       }
{ verarbeiten.                                                   }
{                                                                }
{ Copyright (C) Werner Cirsovius                                 }
{ Hohe Weide 44                                                  }
{ D-2000 Hamburg 20                                              }
{ Tel.: 040-4223247                                              }
{ Version 1.0 von Juli 1988                                      }
{                                                                }
{ ============================================================== }
begin{Module APPEND}
  inline (
  {0000} $22/*+139/$11/$0c/$00/$19/$e5/$22/*+133/$11/$24/$00/$19/$22/
  {0010} *+128/$e1/$cd/*+108/$0e/$0f/$cd/*+94/$20/$54/$2a/*+114/
  {0020} $eb/$0e/$1a/$cd/$05/$00/$0e/$23/$cd/*+78/$20/$3f/$11/$21/$00/
  {0030} $2a/*+93/$19/$4e/$23/$5e/$23/$56/$79/$b2/$b3/$28/$22/$0d/$f2/
  {0040} *+3/$1b/$72/$2b/$73/$2b/$71/$0e/$21/$cd/*+44/$20/$1d/$2a/
  {0050} *+64/$0e/$00/$06/$80/$3e/$1a/$be/$ca/*+6/$23/$0c/$10/$f8/
  {0060} $2a/*+43/$36/$40/$23/$23/$71/$3e/$00/$18/$07/$3e/$02/$c3/*+4/
  {0071} $3e/$01/$32/$d0/$00/$c9/$ed/$5b/*+21/$cd/$05/$00/$b7/$c9/$11/
  {0081} $0c/$00/$19/$06/$18/$36/$00/$23/$10/$fb/$c9/$00/$00/$00/$00/$00/
  {0091} $00);
end; {APPEND}

Per cui, per rendere operativo il codice di esempio anche sotto CP/M basterà quindi semplicemente includere questo prezioso e antico segmento di codice. Il risultato così ottenuto sarà quindi perfettamente funzionante:

PROGRAM TestAppend;
VAR f:TEXT;
s:STRING[80];

PROCEDURE APPEND(VAR f:TEXT);
BEGIN
  inline (
  $22/*+139/$11/$0c/$00/$19/$e5/$22/*+133/$11/$24/$00/$19/$22/
  *+128/$e1/$cd/*+108/$0e/$0f/$cd/*+94/$20/$54/$2a/*+114/
  $eb/$0e/$1a/$cd/$05/$00/$0e/$23/$cd/*+78/$20/$3f/$11/$21/$00/
  $2a/*+93/$19/$4e/$23/$5e/$23/$56/$79/$b2/$b3/$28/$22/$0d/$f2/
  *+3/$1b/$72/$2b/$73/$2b/$71/$0e/$21/$cd/*+44/$20/$1d/$2a/
  *+64/$0e/$00/$06/$80/$3e/$1a/$be/$ca/*+6/$23/$0c/$10/$f8/
  $2a/*+43/$36/$40/$23/$23/$71/$3e/$00/$18/$07/$3e/$02/$c3/*+4/
  $3e/$01/$32/$d0/$00/$c9/$ed/$5b/*+21/$cd/$05/$00/$b7/$c9/$11/
  $0c/$00/$19/$06/$18/$36/$00/$23/$10/$fb/$c9/$00/$00/$00/$00/$00/
  $00);
END;

BEGIN
  ASSIGN(f,'test.txt');

  REWRITE(f);
  WRITELN(f,'First row');
  CLOSE(f);

  APPEND(f);
  WRITELN(f,'Second row');
  CLOSE(f);

  RESET(f);
  WHILE NOT EOF(f) DO BEGIN
    READLN(f,s);
    WRITELN(s)
  END;
  CLOSE(f);
END.

Un esempio pratico di utilizzo di questo utilissimo tip l’ho utilizzato nel gioco Open Source “Queens” per CP/M (compatibile con i terminali ADM-31C128 e KayPro), i cui sorgenti ed eseguibili binari sono liberamente scaricabili presso GitHub:

https://github.com/sblendorio/queens-cpm

Nel caso specifico di Queens, la funzione APPEND è stata utile durante la memorizzazione delle soluzioni trovate dal giocatore, e aggiunte man mano a un archivio, in seguito visionabile mediante l’apposita opzione del gioco.

Buon divertimento e buona retro-programmazione!

Link esterni:

Commenti

Post popolari in questo blog

Commodore 16: CPU 7501/8501 FPGA Replacement

Zork, CP/M, le adventure Infocom e la personalizzazione del terminale

Turbo Pascal porting: dal 7.0 (DOS) al 3.01 (CP/M) – parte 1

YAZE: un ottimo emulatore Z80 + CP/M

CP/M su Commodore 128: terminali e sequenze di escape

Un MIST-ico Amiga

CP/M su Commodore 128: non solo “DIR”

Modi di andare a capo

MIST how-to: Amiga con Kickstart 1.3 e supporto Hard Disk IDE