dec2

W 1989 roku powstał mój pierwszy profesjonalny program - wspomagał tworzenie dziurkowanej taśmy na obrabiarkę sterowaną numerycznie. Pierwsza wersja powstała w archaicznym języku BASIC, a potem w nowoczesnym PASCALu. Program działał w trybie tekstowym (o myszce i okienkach jeszcze wtedy komputerom się nie śniło) i składał się prawie z 2000 wierszy kodu i 35000 znaków, kilkunastostronicowej instrukcji obsługi i miał zaimplementowane ponad 30 różnych funkcji związanych z wierceniem dziur.

Kod źródłowy programu DECKEL

dec1Rok 1989 – świeżo upieczony magister inżynier, wydziału Metali Nieżelaznych Akademii Górniczo-Hutniczej w Krakowie znalazł pracę w Tarnowskich Zakładach Mechanicznych. Mógł pracować w zawodzie, którego przez kilka lat pilnie się uczył i być może dokonał by wielu ważnych odkryć, wolał jednak zostać informatykiem - programistą. Szczęśliwym zbiegiem okoliczności w zakładzie brakowało również i informatyków, i dlatego zostałem zatrudniony w dziale głównego technologa na stanowisku programista obrabiarek sterowanych numerycznie, z pensją mniejszą niż gaża sprzątaczki. Na szczęście nie programowałem obrabiarek, ale pisałem programy, które wspomagały inżynierów tam zatrudnionych, w pisaniu tych programów na obrabiarki. Same obrabiarki widziałem tylko i na szczęście z daleka.

Na pierwszy ogień poszła obrabiarka, która tylko wierciła, ale programowało się ją ręcznie i, jak należy się domyślać, było to żmudne, pracochłonne i długotrwałe. Pierwsza wersja programu powstała, została przetestowana i wdrożona w ciągu miesiąca. Trzeba tu koniecznie dodać, że napisana została w archaicznym dzisiaj języku BASIC, ale za to na super (wtedy) sprzęcie firmy Olivetti z twardym dyskiem (20 MB) i kolorowym monitorem (16 kolorów) o rozdzielczości 640x480 pikseli. Cały zestaw uzupełniała drukarka igłowa i dziurkarka, która wytwarzała specjalne taśmy z programem na obrabiarki. Trzeba tu dodać, że na taki sprzęt obowiązywało jeszcze embargo, które nie pozwalało polskim firmom i osobom prywatnym na kupowanie i wwożenie do Polski komputerów. Na szczęście wojskowe Zakłady Mechaniczne były pod tym względem wyjątkiem.

Przez kilka kolejnych miesięcy program był udoskonalany i pewnie by pozostał w takiej wersji, ale na szczęście zostałem powołany do odbycia półrocznej służby wojskowej. Przez te pół roku wynudziłem się straszliwie i żeby nie popaść w totalny marazm rozpocząłem naukę nowego języka programowania. Był to Pascal, który w tym czasie świecił na świecie swoją szybkością, a w Polsce był szczególnie lubiany ze względu na mnogość pirackich kopii.

Jak wyglądała ta nauka? Kupiłem jakąś książkę. Poczytałem co nieco, wykonałem mnóstwo notatek, zacząłem pisać w notesie jakieś mini programy i… nie było w jednostce ani jednego komputera, do przetestowania świeżo zdobytej wiedzy. Po miesiącu takiej męki stwierdziłem, że mam na tyle opanowaną teorię i że wiem jak działa komputer…  więc zacząłem pisać program na tarnowskiego DECKLA w zeszycie i uruchamiać go w „głowie”, wyobrażając sobie, jak to będzie działało na prawdziwym komputerze. W ten sposób napisałem cały program! Po powrocie z wojska wpisałem go do komputera, coś tam wypoprawiałem i o dziwo - program działał!

Program DECKEL, wraz z dodatkowymi modułami (zabezpieczenie i obsługa animowanych okienek) liczy około 2000 wierszy kodu. Program działa w trybie tekstowym – oznacza to, że na ekran podzielony jest na 80 kolumn i 25 wierszy, a w każdym z 2000 pól można wyświetlić literę lub cyfrę. O windowsowych okienek nikt rozsądny jeszcze wtedy nie instalował. Dodatkowo napisałem kilkunastostronicową instrukcję obsługi z opisem wszystkich funkcji i możliwości programu.

Program był zabezpieczony przed nielegalnym kopiowaniem. Co prawda nie podejrzewam by ktoś chciał program ukraść, ale wprawiałem się wtedy w wymyślaniu zabezpieczeń. W największym skrócie: program sprawdzał, czy w odpowidnim miejscu na dysku znajduje się specjalnie spreparowany plik.

Co program potrafi dodatkowego?

  • Program jest zabezpieczony przed nielegalnym kopiowaniem
  • Program próbuje wyłapywać wszelakie błędy popełniane przez użytkownika.
  • Wprowadzono autozapis.
  • Mamy możliwość zdefiniowania w pliku tekstowym podstawowej konfiguracji i ustawień.
  • Zaimplementowano około 30 funkcji uruchamianych z menu lub skrótami klawiszowymi
  • Użytkownik ma możliwość definiowania tzw. „cykli” – takie dzisiejsze makropolecenie
  • Wytworzony dla obrabiarki zestaw instrukcji może być wydrukowany na podłączonej do komputera dziurkarce, zwykłej drukarce.
  • Programy dla obrabiarki mogą być zapisywane i odczytywane z dysku
  • Można dokonać konwersi programów dla obrabiarki pomiędzy pierwszą a drugą wersją programu.

 Fragment kodu źródłowego

 

function lancuch(dlug:byte):string;   {odczytanie z klawiatury ciagu znakow}
var znak:char; x,y,poz:byte;
    bufor:array[1..80] of char;

  procedure wprawo;
            begin if poz1 then poz:=poz-1 end;

begin
  poz:=1;for x:=1 to dlug do bufor[x]:=#32;
  x:=wherex;y:=wherey;
  repeat
    while keypressed do znak:=readkey;
       gotoxy(x+poz,y);{write('_');}
       znak:=readkey;
       case znak of
          #27:lancuch:=#32;
    #32..#255:begin
                znak:=upcase(znak);
                bufor[poz]:=znak;
                gotoxy(x+poz,y);write(znak);
                wprawo
              end;
          #13:lancuch:=copy(bufor,1,poz-1);
           #8:begin
                wlewo;
                bufor[poz]:=#32;
                gotoxy(x+poz,y);write(' ')
              end
       end;
  until (znak=#13) or (znak=#27)
end;
procedure wysw_linie (nwn,jak:byte);
  var i,nw1:byte;d:string[8];
        nb1:0..999;
begin
  l:=f;nw1:=tryb-ile_wierszy+nwn;nb1:=nb-nw+nwn;
  gotoxy(1,nw1);for i:= 1 to 16 do l[i]:=tabb[nb1,i];
  if (tabb[nb1,16]='1') and (tabb[nb1,13]<>'9') then l[19]:='R';
  if jak=1 then
    begin
      cala_linia(nb1);
      gotoxy(wherex,63);
      str((tabl[nb1,t]-tabl[(nb1-1),t]):8:2,d);
      for i:=1 to 8 do l[i+63]:=d[i];
      kolor(podr,pods)
    end
  else
    begin
      case fl of
        9:cala_linia (nb1);
      1,3:begin
            case kl of
              1,2:do_linii (x,nb1);
              3,4:do_linii (y,nb1);
              5,6:do_linii (z,nb1);
              7,8:do_linii (c,nb1)
            end;
            do_linii (t,nb1)
          end;
      7,8:do_linii(t,nb1)
      end;
      kolor(ekrt,ekrl)
    end;
    write(l)
  end;

procedure na_segmenty;
  var w:array[5..16] of byte; i:byte; j:integer;
begin
  for i:=5 to 16 do
    if tabb[nb,i] in [#48..#57] then val(tabb[nb,i],w[i],j);
  kl:=w[5];kb:=tabb[nb,5];
  wl:=w[7]*100+w[8]*10+w[9]+w[10]*0.1+w[11]*0.01;
  if (kl=7) or (kl=8) then wl:=wl/10;
  wb:=tabb[nb,7]+tabb[nb,8]+tabb[nb,9]+tabb[nb,10]+tabb[nb,11];
  pl:=w[13]*10+w[14];
  fl:=w[16];fb:=tabb[nb,16];
  if (kl=2) or (kl=4) or (kl=6) or (kl=8) then wl:=-wl
end;

function czas:real;
  var cz:real;
begin
  na_segmenty;
  if ((pl=99) or (pl=0)) then cz:=500 else cz:=czasy[pl];
  if ((fl=1) or (fl=3))
    then
      if wl<>0 then cz:= (wl/cz)*60
               else cz:= tkorekcji;
  case fl of
    7:cz:=tobrotow;
    8:cz:=tpomiaru;
    9:cz:=tzmianynarz
  end;
  czas:=abs(cz/60)
end;

procedure w_gore; forward;

procedure nowe_wsp;
  var w:wartosci;
  begin
    case fl of
      9:begin
          if tabl[nb,n]=0 then begin zmiana_narzedzia; w_gore end;
          tabl[nb,gl]:=(tabl[nb-1,gl]+tabl[nb-1,n])-tabl[nb,n];
          tabl[nb,x]:=tabl[nb-1,x];
          if gl=y then  tabl[nb,z]:=tabl[nb-1,z]
                  else  tabl[nb,y]:=tabl[nb-1,y];
          tabl[nb,c]:=tabl[nb-1,c];
        end;
2,5,7,8:for w:=x to n do tabl[nb,w]:=tabl[nb-1,w];
    1,3:begin
          for w:=x to n do tabl[nb,w]:=tabl[nb-1,w];
          case kl of
            1,2: tabl[nb,x]:=tabl[nb-1,x]+wl;
            3,4: tabl[nb,y]:=tabl[nb-1,y]+wl;
            5,6: tabl[nb,z]:=tabl[nb-1,z]+wl;
            7,8: begin
                   tabl[nb,c]:=tabl[nb-1,c]+wl;
                   if abs(tabl[nb,c])=360 then tabl[nb,c]:=0
                 end
          end
        end;
    end;
    tabl[nb,t]:=tabl[nb-1,t]+czas
  end;

procedure w_prawo;
  begin if pwb5 then pwb:=pwb-1 else pwb:=16 end;

procedure w_gore;
  var nw1:byte;
  begin na_segmenty;
       if nw>1 then begin wysw_linie(nw,0); nw:=nw-1;nb:=nb-1 end
               else if nb>1 then
                 begin wysw_linie(1,0);
                       nb:=nb-1;nw1:=tryb-ile_wierszy+1;
                       gotoxy(1,nw1-1);insline;
                       gotoxy(1,tryb+1);clreol;
                 end;
                 wysw_linie(nw,1)
  end;

procedure w_dol;
  var nw1:byte;
  begin
   if nbnb_max then nb_max:=nb;
               if nb>nb_max1 then nb_max1:=nb;
               if nb_max1>=poziom then
           begin zapis_kontrolny:=true;save;zapis_kontrolny:=false;
                 poziom:=poziom+poziom_zapisu
           end;
             end
  end;