Robotrontechnik-Forum

Registrieren || Einloggen || Hilfe/FAQ || Suche || Mitglieder || Home || Statistik || Kalender || Admins Willkommen Gast! RSS

Robotrontechnik-Forum » Technische Diskussionen » PASCAL Quelltxt als CP/M File kompilieren » Themenansicht

Autor Thread - Seiten: -1-
000
06.12.2009, 13:11 Uhr
Ralph



Hallo,
wer kann mir eine Pascal Programm als CP / M 2.2 COM-Datei kompilieren?
Leider weiß ich nicht genau, was für ein Quelltext das ist .. deshalb hier mal ein der Code der zu übersetzen wäre.
Ich möchte gern dieses Tool auf den AC1 anpassen. Vielen Dank Euch!


Quellcode:
program IDE_Test_Programm;

(* written Q&D 920308 by Tilmann Reh *)
(* some modifications during 1992 & 1993 *)
(* translated and adapted to GIDE 950403 Tilmann Reh *)
(* variable base address added 951015 Tilmann Reh *)
(* an AC1 angepasst 05.12.2009 Ralph Haensel *)


const  signon = ^m^j'IDE Harddisk Utility V0.4  TR 951015'^m^j;

(* default geometry of connected SSD harddisk *)
(* here: default mode SSD  *)
(* enter real dimension, not greatest value! *)

const  cylinders   : integer = 984;
       heads       : integer = 16;
       sectors     : integer = 32;

(* I/O addresses and commands of the IDE interface/drive *)
(* The I/O addresses are user selectable in steps of $10 *)

       GIDEbase    : integer = $80;  (* GIDE base address *)

       cmd_readsector  = $20;
       cmd_writesector = $30;
       cmd_seek        = $70;
       cmd_diagnostics = $90;
       cmd_initialize  = $91;
       cmd_identify    = $EC;

(* variables *)

type   workstr       = string[30];
       buftype       = array[0..511] of byte;
       str           = string[80];
       IDRecord      = record
                         config       : integer;
                         NumCyls      : integer;
                         NumCyls2     : integer;
                         NumHeads     : integer;
                         BytesPerTrk  : integer;
                         BytesPerSec  : integer;
                         SecsPerTrack : integer;
                         d1,d2,d3     : integer;
                         SerNo        : array [0..19] of char;
                         CtrlType     : integer;
                         BfrSize      : integer;
                         ECCBytes     : integer;
                         CtrlRev      : array [0..7] of char;
                         CtrlModl     : array [0..39] of char;
                         SecsPerInt   : integer;
                         DblWordFlag  : Integer;
                         WrProtect    : integer;
                       end;

var    Alt_Status,IDE_Data,IDE_Error,
       IDE_SecCnt,IDE_SecNum,IDE_CylLow,
       IDE_CylHigh,IDE_SDH,IDE_CmdStat : integer;

       secbuf,bakbuf   : buftype;
       i,j,k,l,m       : integer;
       func,c          : char;
       err             : boolean;
       s               : workstr;

(* use our own console status routine, since the one implemented in *)
(* Turbo-Pascal won't detect the "keypressed" status properly.      *)

function ConStat:boolean;
begin
  ConStat:=BIOS(1)>0;
  end;

(* translate numbers into their hex representation (as string). *)

function hexbyte(x:byte):workstr;
const nib : array[0..15] of char = '0123456789ABCDEF';
begin
  hexbyte:=nib[x shr 4]+nib[x and 15];
  end;

function hexword(x:integer):workstr;
begin
  hexword:=hexbyte(hi(x))+hexbyte(lo(x));
  end;


(* Set the port addresses for the various interface registers. *)
(* The addresses are kept in variables since they can be       *)
(* changed during run-time.                                    *)

procedure SetPorts(var base:integer);
begin
  base:=base and $F0;
  Alt_Status:=base+6;
  IDE_Data:=base+8;
  IDE_Error:=base+9;
  IDE_SecCnt:=base+10;
  IDE_SecNum:=base+11;
  IDE_CylLow:=base+12;
  IDE_CylHigh:=base+13;
  IDE_SDH:=base+14;
  IDE_CmdStat:=base+15;
  writeln('Ports setup for base ',HexByte(base),'h.');
  end;


(* Translate an ARRAY OF CHAR from the drive into a Pascal-usable string. *)
(* (character pairs must be swapped for this.)                            *)

function st(s:str):str;
var s1 : str;
    i  : byte;
begin
  s1[0]:=s[0];
  for i:=0 to pred(length(s)) do s1[i+1]:=s[(i xor 1)+1];
  st:='>'+s1+'<';
end;

(* display error status *)

procedure Error(s:workstr; flag:boolean);
begin
  writeln('  ',s,'; Status: ',hexbyte(port[ide_cmdstat]),
          ' ',hexbyte(port[ide_error]));
  if flag then halt;
  end;

(* Wait until the drive is ready to accept a command.       *)
(* The timeout value may be changed according to the drive. *)
(* Remove the "i:=succ(i)" instruction to disable timeout.  *)

procedure wait_ready;
const timeout = 30000;
var i : integer;
begin
  i:=0;
  while (port[ide_cmdstat]>128) and (i<timeout) do i:=succ(i);
  if i=timeout then Error('WaitReady TimeOut',true);
  end;

(* Wait for the drive's Data Request (DRQ). *)
(* For the timeout, see above.              *)

procedure wait_drq;
const timeout = 30000;
var i : integer;
begin
  i:=0;
  while (port[ide_cmdstat] and 8=0) and (i<timeout) do i:=succ(i);
  if i=timeout then Error('WaitDRQ TimeOut',true);
  end;

(* write a command to the drive *)

procedure ide_command(cmd:byte);
begin
  wait_ready;
  port[ide_cmdstat]:=cmd;
  wait_ready;
  end;

(* Read the sector buffer from the drive. *)

function read_secbuf(var buf:buftype):boolean;
var i : integer;
begin
  wait_drq;
  for i:=0 to 511 do buf[i]:=port[ide_data];
  read_secbuf:=port[ide_cmdstat] and $89=0;
  end;

(* Write the sector buffer to the drive. *)

function write_secbuf(var buf:buftype):boolean;
var i : integer;
begin
  wait_drq;
  for i:=0 to 511 do port[ide_data]:=buf[i];
  wait_ready;
  write_secbuf:=port[ide_cmdstat] and $89=0;
  end;

(* position the drive on the desired cylinder (seek) *)

function hd_seek(cyl:integer):boolean;
begin
  wait_ready;
  port[ide_cyllow]:=lo(cyl);
  port[ide_cylhigh]:=hi(cyl);
  port[ide_sdh]:=$A0;
  ide_command(cmd_seek);
  hd_seek:=port[ide_cmdstat] and $89=0;
  end;

(* Read a single sector from the drive. Retry up to 5 times on error. *)
(* Print the number of tries if above 1, and report errors.           *)

procedure hd_readsector(cyl,head,sec:integer; var buf:buftype);
var n : byte;
    b : boolean;
begin
  n:=0;
  repeat
    wait_ready;
    port[ide_error]:=$AA;
    port[ide_seccnt]:=1;
    port[ide_secnum]:=sec;
    port[ide_cyllow]:=lo(cyl);
    port[ide_cylhigh]:=hi(cyl);
    port[ide_sdh]:=$A0+head;
    ide_command(cmd_readsector);
    b:=read_secbuf(buf);
    n:=succ(n);
  until b or (n>5);
  if not b then Error('Read Sector',false) else if n>1 then writeln(n:5);
  end;

(* Write a single sector to the drive. No need for retries yet, *)
(* until now it was just a go/nogo behaviour.                   *)

procedure hd_writesector(cyl,head,sec:integer; var buf:buftype);
begin
  wait_ready;
  port[ide_seccnt]:=1;
  port[ide_secnum]:=sec;
  port[ide_cyllow]:=lo(cyl);
  port[ide_cylhigh]:=hi(cyl);
  port[ide_sdh]:=$A0+head;
  ide_command(cmd_writesector);
  if not write_secbuf(buf) then Error('Write Sector',false);
  end;

(* initialise the harddisk drive and set the desired geometry *)

procedure hd_init(cyls,hds,secs:integer);
begin
  writeln('Initialising the drive...');
  port[alt_status]:=6;
  delay(10);            (* Drive Software Reset *)
  port[alt_status]:=2;
  wait_ready;
  writeln(port[ide_error]:4,port[ide_seccnt]:4,port[ide_secnum]:4,
          port[ide_cyllow]:4,port[ide_cylhigh]:4,port[ide_sdh]:4);
  port[ide_seccnt]:=secs;
  port[ide_cyllow]:=lo(cyls);
  port[ide_cylhigh]:=hi(cyls);
  port[ide_sdh]:=pred(hds)+$A0;
  ide_command(cmd_initialize);
  writeln('Mode : ',cyls,'x',hds,'x',secs);
  end;

(* read and show drive ID data *)

procedure hd_identify;
var buffer : IDRecord absolute secbuf;
    Words  : array[0..255] of integer absolute secbuf;
    i,j    : integer;
    secs   : real;
begin
  writeln('Reading ID information...');
  ide_command(cmd_identify);
  if not read_secbuf(secbuf) then Error('Read Identify',false);
  with buffer do begin
    writeln('ID constant            : ',config,' (',hexword(config),')');
    writeln('cylinders fixed        : ',NumCyls);
    writeln('cylinders removable    : ',NumCyls2);
    writeln('number of heads        : ',NumHeads);
    writeln('bytes per track phys.  : ',BytesPerTrk);
    writeln('bytes per sector phys. : ',BytesPerSec);
    writeln('sectors per track      : ',SecsPerTrack);
    writeln('serial number          : ',st(SerNo));
    writeln('controller revision    : ',st(CtrlRev));
    writeln('buffer size (sectors)  : ',BfrSize);
    writeln('number of ECC bytes    : ',ECCBytes);
    writeln('controller model       : ',st(CtrlModl));
    secs := int(NumCyls) * NumHeads * SecsPerTrack;
    writeln('total sector count     : ',secs:1:0);
    writeln('capacity (MByte)       : ',int(secs / 2048):1:1);
    end;
  write(^m^j'press ENTER ');
  readln;
end;

(* execute drive diagnostics (self test) *)

procedure hd_diagnostics;
begin
  writeln(^m^j'Drive Self-Test...');
  ide_command(cmd_diagnostics);
  writeln('Result Code: ',hexbyte(port[ide_error]),^m^j);
  end;

(* Random Seek Test *)

procedure hd_seekrandom;
begin
  writeln('Seek Test. Press any key to abort.');
  repeat
    i:=random(cylinders);
    write(^m,i:4);
    if not hd_seek(i) then error('Seek',false);
  until keypressed;
  read(kbd,c);
  writeln(' ** Aborted **');
  end;

(* Read the complete drive, linear access *)

procedure hd_readlinear;
begin
  writeln('Disk is being read. Press any key to abort.');
  for i:=0 to pred(cylinders) do
  for j:=0 to pred(heads) do
  for k:=1 to sectors do begin
    write(^m,i:4,j:3,k:3);
    hd_readsector(i,j,k,secbuf);
    if keypressed then begin
      read(kbd,c);
      writeln(' ** Aborted **');
      exit; end;
    end;
  end;

(* randomly read the harddisk drive *)

procedure hd_readrandom;
begin
  writeln('Disk is being read. Press any key to abort.');
  repeat
    i:=random(cylinders); j:=random(heads); k:=succ(random(sectors));
    write(^m,i:4,j:3,k:3);
    hd_readsector(i,j,k,secbuf);
  until keypressed;
  read(kbd,c);
  writeln(' ** Aborted **');
  end;

(* read and write-back the entire drive, linear *)

procedure hd_rw_linear;
begin
  writeln('Test running. Press any key to abort.');
  for i:=0 to pred(cylinders) do
  for j:=0 to pred(heads) do
  for k:=1 to sectors do begin
    write(^m,i:4,j:3,k:3);
    hd_readsector(i,j,k,secbuf);
    hd_writesector(i,j,k,secbuf);
    if keypressed then begin
      read(kbd,c);
      writeln(' ** Aborted **');
      exit; end;
    end;
  end;

(* randomly read and write-back drive data *)

procedure hd_rw_random;
begin
  writeln('Test running. Press any key to abort.');
  repeat
    i:=random(cylinders); j:=random(heads); k:=succ(random(sectors));
    write(^m,i:4,j:3,k:3);
    hd_readsector(i,j,k,secbuf);
    hd_writesector(i,j,k,secbuf);
  until keypressed;
  read(kbd,c);
  writeln(' ** Aborted **');
  end;

(* Write random data to a sector, then read back and compare. *)
(* Repeat this linearly for the complete drive. All data is   *)
(* destroyed by this test, so be careful!                     *)

procedure hd_test_linear;
begin
  write('All data will be destroyed! Continue? (Y/N) ');
  repeat read(kbd,c); c:=upcase(c) until (c='Y') or (c='N');
  writeln(c); if c='N' then exit;
  writeln('Test running. Press any key to abort.');
  for i:=0 to pred(cylinders) do
  for j:=0 to pred(heads) do
  for k:=1 to sectors do begin
    write(^m,i:4,j:3,k:3);
    for l:=0 to 511 do bakbuf[l]:=random(256);
    hd_writesector(i,j,k,bakbuf);
    hd_readsector(i,j,k,secbuf);
    err:=false;
    for l:=0 to 511 do if secbuf[l]<>bakbuf[l] then err:=true;
    if err then Error('Sector R/W Verify',false);
    if keypressed then begin
      read(kbd,c);
      writeln(' ** Aborted **');
      exit; end;
    end;
  end;

(* Write random data to a sector, then read back and compare. *)
(* Repeat this randomly for the complete drive. All data is   *)
(* destroyed by this test, so be careful!                     *)

procedure hd_test_random;
begin
  write('All data will be destroyed! Continue? (Y/N) ');
  repeat read(kbd,c); c:=upcase(c) until (c='Y') or (c='N');
  writeln(c); if c='N' then exit;
  writeln('Test running. Press any key to abort.');
  repeat
    i:=random(cylinders); j:=random(heads); k:=succ(random(sectors));
    write(^m,i:4,j:3,k:3);
    for l:=0 to 511 do bakbuf[l]:=random(256);
    hd_writesector(i,j,k,bakbuf);
    hd_readsector(i,j,k,secbuf);
    err:=false;
    for l:=0 to 511 do if secbuf[l]<>bakbuf[l] then err:=true;
    if err then Error('Sector R/W Verify',false);
  until keypressed;
  read(kbd,c);
  writeln(' ** Aborted **');
  end;

(* MAIN *)

begin
  constptr:=addr(constat);
  writeln(signon);
  SetPorts(GIDEbase);
{  hd_init(cylinders,heads,sectors); }   (* option *)
  repeat
    write(^m^j'Functions:'^m^j,
    '(0) Initialise drive             (5) Read disk randomly'^m^j,
    '(1) Read drive''s ID data         (6) Read/rewrite linear'^m^j,
    '(2) Execute drive''s selftest     (7) Read/rewrite randomly'^m^j,
    '(3) Random seek test             (8) Write/read linear (destructive)'^m^j,
    '(4) Read disk linear             (9) Write/read randomly (destructive)'^m^j,
    '(p) Set port address             (x) Exit program'^m^j,
    'Input: ');
    repeat read(kbd,func); func:=upcase(func)
    until func in ['0'..'9','P','X'];
    write(func,^m^j^m^j);
    case func of
      '0' : begin
              write('No. of Cylinders (',cylinders:4,') : '); readln(cylinders);
              write('No. of Heads     (',heads:4,') : '); readln(heads);
              write('No. of Sectors   (',sectors:4,') : '); readln(sectors);
              hd_init(cylinders,heads,sectors);
              end;
      '1' : hd_identify;
      '2' : hd_diagnostics;
      '3' : hd_seekrandom;
      '4' : hd_readlinear;
      '5' : hd_readrandom;
      '6' : hd_rw_linear;
      '7' : hd_rw_random;
      '8' : hd_test_linear;
      '9' : hd_test_random;
      'P' : begin
              write('GIDE base adress in hex (',HexByte(GIDEbase),') : ');
              readln(s);
              if length(s)>0 then begin
                val('$'+s,i,j);
                if j=0 then GIDEbase:=i;
                end;
              SetPorts(GIDEbase);
              end;
      end;
  until func='X';


--
Es geht alles erst richtig los !

Dieser Beitrag wurde am 06.12.2009 um 13:16 Uhr von Ralph editiert.
Seitenanfang Seitenende
Profil || Private Nachricht || Suche Zitatantwort || Editieren || Löschen
001
06.12.2009, 13:15 Uhr
holm

Avatar von holm

Das ist Turbopascal 3.x für CP/M 2.2

Gruß,
Holm
--
float R,y=1.5,x,r,A,P,B;int u,h=80,n=80,s;main(c,v)int c;char **v;
{s=(c>1?(h=atoi(v[1])):h)*h/2;for(R=6./h;s%h||(y-=R,x=-2),s;4<(P=B*B)+
(r=A*A)|++u==n&&putchar(*(((--s%h)?(u<n?--u%6:6):7)+"World! \n"))&&
(A=B=P=u=r=0,x+=R/2))A=B*2*A+y,B=P+x-r;}

Dieser Beitrag wurde am 06.12.2009 um 13:16 Uhr von holm editiert.
Seitenanfang Seitenende
Profil || Private Nachricht || Suche Zitatantwort || Editieren || Löschen
002
06.12.2009, 13:16 Uhr
Ralph



Hallo Holm.. Du warst aber fix.. Danke, aber das Tool ist so 1:1 von Tilman Reh
--
Es geht alles erst richtig los !
Seitenanfang Seitenende
Profil || Private Nachricht || Suche Zitatantwort || Editieren || Löschen
003
06.12.2009, 13:30 Uhr
Ralph



@Holm..und kannst Du mir das auch übersetzen? Wäre ein echtes Nikolausgeschenk :-)
--
Es geht alles erst richtig los !
Seitenanfang Seitenende
Profil || Private Nachricht || Suche Zitatantwort || Editieren || Löschen
004
06.12.2009, 18:18 Uhr
holm

Avatar von holm

Theoretisch ja, ich habe es ja schon mal gemacht. :-)
Ich habe aber zur Zeit (aus Platzgründen) keinen CP/M Rechner hier arbeitsbereit
und das wird voraussichlich auch noch ein Bisschen so bleiben, hatte gehofft das sich noch jemand Anderes meldet...

BTW: Ich hatte meinen Post korrigiert während Du geantwortet hast.
Ich habe Tillmanns Source wiedererkannt..

Gruß,

Holm
--
float R,y=1.5,x,r,A,P,B;int u,h=80,n=80,s;main(c,v)int c;char **v;
{s=(c>1?(h=atoi(v[1])):h)*h/2;for(R=6./h;s%h||(y-=R,x=-2),s;4<(P=B*B)+
(r=A*A)|++u==n&&putchar(*(((--s%h)?(u<n?--u%6:6):7)+"World! \n"))&&
(A=B=P=u=r=0,x+=R/2))A=B*2*A+y,B=P+x-r;}
Seitenanfang Seitenende
Profil || Private Nachricht || Suche Zitatantwort || Editieren || Löschen
005
06.12.2009, 18:51 Uhr
AlexHuck



Würde es denn nicht ausreichen, in einem Emulator den Quelltext zu übersetzen? MyZ80, YAZE-AG und SIMH/Altair sind recht einfach zu bedienen, bieten Import/Export mit dem Hostsystem und sind sehr schnell.
--
Jeder blamiert sich, so gut er kann.
Seitenanfang Seitenende
Profil || Private Nachricht || Suche Zitatantwort || Editieren || Löschen
006
06.12.2009, 19:42 Uhr
ambrosius



Ich habe gerade versucht, mittels "turbo.com" auf einem A5120 den Quelltext zu übersetzen, erhalte aber immer eine Fehler beim ersten Record. Dort verlangt der Compiler immer ein Semikolon.

...
IDRecord = record -------> hier wird ';' erwartet
config : integer;
...
Lt. meiner Doku entspricht das SCPX-Turbo.COM dem Turbo Pascal 3.02 und den Typ 'record' gab es auch und zwar in obiger Syntax. Ich kann aber sonst keinen Fehler finden. Kann mir jemand einen Tip geben?

mfg

Holger

-------
edit: @ralph: auf welche Startadresse soll das Programm übersetzt werden?
--
viele Grüße
Holger

Dieser Beitrag wurde am 06.12.2009 um 19:47 Uhr von ambrosius editiert.
Seitenanfang Seitenende
Profil || Private Nachricht || Suche Zitatantwort || Editieren || Löschen
007
06.12.2009, 20:28 Uhr
Ralph



@alle... erstmal Danke für Eure Bemühungen !

@ambrosius... Nun da es als CP/M Programm laufen soll, dann müsste es ab 0100H starten
--
Es geht alles erst richtig los !
Seitenanfang Seitenende
Profil || Private Nachricht || Suche Zitatantwort || Editieren || Löschen
008
06.12.2009, 22:36 Uhr
ambrosius



Hallo Ralph,

Problem gelöst, hast PN

mfg
Holger
--
viele Grüße
Holger
Seitenanfang Seitenende
Profil || Private Nachricht || Suche Zitatantwort || Editieren || Löschen
Seiten: -1-     [ Technische Diskussionen ]  



Robotrontechnik-Forum

powered by ThWboard 3 Beta 2.84-php5
© by Paul Baecher & Felix Gonschorek