1991-Club80-34 S.9-12

Textkonvertierung IBM-PC nach CP/M

Helmut Bernhardt

Wer abwechselnd unter CP/M und unter DRDOS (oder womöglich gar MSDOS) Texte schreibt, hat stets Probleme, diese Texte zwischen beiden Systemen auszutauschen. Das geringere Übel ist dabei, daß die auf dem PC eingegebenen deutschen Umlaute und Grafikzeichen unter CP/M nicht mehr zu erkennen sind; viel schlimmer ist, daß gelegentlich ab einer bestimmtem Stelle im Text unter CP/M vermeintlich nichts mehr da ist.

Woran liegt das? ---Daran:

Unter CP/M gibt es den 7Bit-ASCII-Code, mit dem 128 verschiedene Zeichen codiert werden können. Die ersten 32 Codes werden noch für Steuerzeichen für das Terminal, den Drucker oder wen auch immer belegt, so daß mit 96 Codes nicht allzuviele darstellbaren Zeichen unterschieden werden können. So hat man schon für die verschiedenen nationalen Sonderzeichen die Konvention eingeführt, daß deren Codes immer bei 5Bh-5Eh und 7Bh-7Eh liegen. Welches nationale Sonderzeichen mit einem dieser Codes erzeugt werden soll, kann z.B. beim Drucker über ein Mäuseklavier eingestellt werden oder allgemeiner über eine ESC-Sequenz vorgegeben werden.

Bei der Druckerausgabe ist es noch möglich, durch Umschalten mit entsprechenden ESC-Sequenzen abwechselnd die Sonderzeichen aller nationalen Zeichensätze innerhalb eines Textes zu benutzen. Dann müssen in dem Text-File diese Steuersequenzen enthalten sein und es handelt sich nicht mehr um einen reinen ASCII-Text, der universell übertragbar ist.

Ein Terminal kann aber immer nur eines der mit einem der Codes 5Bh-5Eh und 7Bh-7Eh gemeinten Zeichen darstellen, das dann in allen Fällen auf dem Bildschirm erscheint. Gleichzeitige Darstellung von z.B. [ und Ä ist nicht möglich.

Dieses Übel wurde beim PC durch den 8Bit-ASCII-Code beseitigt. Das 8te Bit wird dafür verwendet, weitere 128 darstellbare Zeichen zu codieren. Die Codes 5Bh-5Eh und 7Bh-7Eh sind eindeutig den Zeichen [\]^{|} zugeordnet und alle anderen nationalen Sonderzeichen haben eindeutige Codes mit gesetztem Bit 7. Daneben gibt es noch etliche weitere Sonderzeichen und auch Grafikzeichen zum Erzeugen von Linien und Rahmen in einfacher, doppelter und gemischter Linienführung.

Da unter CP/M das Bit 7 eines ASCII-Codes nicht definiert ist, benutzen einige Textprogramme und auch Terminals es zur Unterbringung eines Attribut-Bits oder ignorieren es einfach. In diesem Fall werden die PC-Zeichen mit Codes 8Ch-9Fh als Steuerzeichen 00h-1Fh erkannt (z.B. Wordstar), was im Fall von "Ü" mit dem Code 9Ah als 1Ah = ^Z erkannt und als 'End of File' interpretiert wird. Der Rest des Files hinter dem Ü ist dann nicht zugänglich.

Da mit dem unter CP/M 3.0 laufenden Programm MSDOS.COM, dessen Turbo Pascal Source in dem Artikel "CP/M 3.0 goes MSDOS' in der c't abgedruckt war, 5¼"-360K-MSDOS-Disketten gelesen und geschrieben werden können, ist ein Transfer von Texten zwischen den Systemen physikalisch möglich. Es muß nur noch eine Anpassung der ASCII-Codes vorgenommen werden, falls das Text-File von DRDOS nach CP/M übertragen werden soll. In anderer Richtung ergibt eine Code-Umwandlung wenig Sinn, weil nicht feststeht, welches nationale Sonderzeichen anstelle der eckigen und geschweiften Klammern gemeint ist, oder ob nicht hier tatsächlich mal eine solche Klammer gemeint ist.

Eine Anpassung der Zeichen des PC-Zeichensatzes No2 an den 7Bit-ASCII- Zeichensatz leistet das beiliegende kleine Pascal-Programm, das einfache 8Bit-ASCII-Files (von Quick Star, dem Editor von Turbo Pascal, EDITOR.EXE von DRDOS...) umcodiert. Texte von MS-Word, Word Perfect, Star Writer PC, Word Star... lassen sich nicht (solange sie nicht mit einem entsprechenden Utility in reine ASCII-Texte konvertiert wurden) übertragen. Das Programm läßt sich mit Turbo Pascal unter DRDOS und unter CP/M kompilieren und läuft unter beiden Betriebssystemen. Es werden nicht nur die deutschen Umlaute übersetzt sondern auch die Selbstlaute mit Akzenten in entsprechende Selbstlaute ohne Akzent übersetzt. Die Grafikzeichen werden je nach Form in die Zeichen ! - + übersetzt, wobei man unter CP/M die Linien leidlich erkennen kann, die im PC-Zeichensatz dargestellt sind. Für nicht übertragbare Zeichen wird ein Blank erzeugt. Tabelle: Zeichen des PC-Zeichensatzes No2 und die daraus für den 7Bit-ASCII-Zeichensatz erzeugten Entsprechungen.

Da diese Umcodierung über eine Tabelle erledigt wird, kann man sich dort noch weitere Stellvertreter-Zeichen für den 7Bit-Zeichnsatz einbauen, ohne an der Programmlogik herumschnitzen zu müssen.


program PC2CPM
{uses crt;	nur unter Turbo Pascal 4.0 nötig, kann sonst kein UPCASE}

const logo : string = 'PC => CP/M Textkonvertierung,   (C) 06.09.91 Be';

Umcode : array [0..127] of Byte =
($43,$7D,$65,$61, $7B,$61,$61,$63, $65,$65,$65,$69, $69,$69,$5B,$65,
 $45,$7b,$5b,$7c, $7c,$6f;$75,$75, $79,$5c,$5d,$63, $20,$59,$20,$20,
 $61,$69,$6f,$75, $6e,$4e,$61,$6f, $20,$20,$20,$20, $20,$20,$3c,$3c,
 $20,$20,$20,$21, $21,$21,$21,$2b, $2b,$21,$21,$2b, $2b,$2b,$2b,$2b,
 $2b,$2d,$2d,$21, $2d,$2b,$21,$21, $2b,$2b,$2d,$2d, $21,$2d,$2b,$2b,
 $2d,$2d,$2d,$2d, $2b,$2b,$2b,$2b, $2b,$2b,$2b,$20, $20,$20,$20,$20,
 $61,$7e,$54,$20, $20,$20,$20,$20, $20,$20,$20,$20, $20,$20,$20,$20,
 $3d,$2b,$3e,$3c, $20,$20,$20,$20, $20,$20,$20,$20, $20,$32,$20,$20;
{	Position in der Tabelle ist PC-ASCII-Code abzüglich 128.
	Wert in der Tabelle ist der entsprechende CP/M-ASCII-Code
	Für nicht übertragbare Zeichen wird ein Blank erzeugt}

var  PC, CPM		   : file of byte;
     Quelle, Ziel	   : string;
     Ptr, scan, i, Zeichen : byte;

procedure GetSource;
begin
  repeat
    write('PC-Text-File : ');	readln(Quelle);
    for scan := 1 to length (Quelle do Quelle[scan] :=
	upcase(Quelle[scan];
    assign(PC,Quelle);   {$I-}   reset(PC);   {$I+}
  until oiresult=0;
end;

begin
  if ParamCount  0 then begin
    Quelle := ParamStr(1); for scan := 1 to length(Quelle) do
      Quelle[scan] := upcase(Quelle[scan]
    assign(PC,Quelle);   {$I-}   reset(PC);   {$I+}
    if ioresult  0 then begin
      writeln('kann ',Quelle, ' nicht oeffnen!');   GetSource;
    end;
  end;
  else GetSource;

  Ziel:='';  scan:=1;
  repeat
    Zile := Ziel + Quelle[scan];   scn := scan + 1;
    if Quelle[scan] = '.' than scan := length(Quelle);
  until scan = length(Quelle);

  Ziel := Ziel + '.CPM';
  assign(CPM,Ziel);   {$I-}   rewrite(CPM);   {$I+}
  if ioresult  0 then begin
    writeln('kann ',Ziel,' nicht anlegen!');   Halt;
  end;

  writeln(logo);
  repeat
    read(PC,Zeichen);
    if (Zeichen and $80)  0 then begin
      Ptr := (Zeichen and $7F);   Zeichen := umcode[Ptr]:
    end;
    write(CPM,Zeichen);
  until eof(PC);
  close(PC);   close(CPM);
  writeln(Quelle,' in,' Ziel. konvertiert !')
end.