MAD-PASCAL 1.5.7

Tebe/Madteam (2018.07.16)

`WPROWADZENIE Wstęp Kompilacja SPOSÓB UŻYCIA Przełączniki kompilatora Kody wyjścia BIBLIOTEKI LIB BLIBS SKŁADNIA Komentarze Zarezerwowane słowa Wyrażenia Liczby Operatory Dyrektywy kompilatora RESOURCE {$R filename} HISTORIA` | `CONSTANTS Ordinary constants TYPES Ordinal types Boolean types Enumeration types Real types Character types Pointers Arrays Record types Object types File types Instrukcje warunkowe Instrukcje iteracyjne Procedury i funkcje Modyfikatory procedur i funkcji Units`

`

WPROWADZENIE

`

## Wstęp

`

`Mad-Pascal (MP)` jest 32-bitowym kompilatorem Turbo Pascala dla Atari XE/XL. W założeniu jest kompatybilny z Free Pascal Compilatorem (FPC) (przełącznik -MDelphi powinien być aktywny), co oznacza możliwość otrzymanie kodu uruchomieniowego dla XE/XL, PC i każdej innej platformy dla której istnieje FPC. MP nie jest portem FPC, został napisany na podstawie kompilatorów SUB-Pascal (2009), XD-Pascal (2010), których autorem jest Vasiliy Tereshkov (vtereshkov@mail.ru).

Program który zadziała na Atari może mieć problem na PC jeśli np. nie zaincjowaliśmy wskaźników adresem zmiennej, będziemy próbowali zapisywać coś pod adresem $0000 (błąd ochrony pamięci). Mocną stroną MP jest szybka i wygodna możliwość dołączania wstawek assemblerowych. Program z wstawkami ASM nie będzie działał na innej platformie niż XE/XL. MP wykorzystuje 64KB pamięci podstawowej, korzystanie z pamięci rozszerzonej udostępnia TMemoryStream.

Alokacja zmiennych jest statyczna, nie ma dynamicznego zarządzania pamięcią. Parametry przekazywane do funkcji i procedur są przez wartość, zmienną lub stałą.

Dostępne są:

- If, Case, For, While, Repeat statements.
- Compound statements.
- Label, Goto statements.
- Arithmetic and boolean operators.
- Procedures and functions with up to 8 parameters. Returned value of a function is assigned to a predefined RESULT variable.
- Static local variables.
- Primitive data types (all types except the ShortReal/Real type are compatible. Pointers are dereferenced as pointers to Word):
  - Cardinal, Word, Char, Byte, Boolean
  - Integer, SmallInt, ShortInt
  - Pointer, File
  - ShortReal, Real (fixed-point)
  - Single (IEEE-754)
- One-dimensional and Two-dimensional arrays (with zero lower bound) of any primitive type. Arrays are treated as pointers to their origins (like in C) and can be passed to subroutines as parameters.
- Predefined type string [N] which is equivalent to array [0..N] of Char.
- Type aliases.
- Records.
- Objects.
- Separate program modules.
- Recursion.

- Free Pascal Reference Guide
- MadPascal AtariArea forum (PL)
- MadPascal AtariAge forum (ENG)
- MadPascal examples
- Atari XE/XL Pascal Compilers

  `

  ## Kompilacja

  `

  Aby skompilować źródło `Mad-Pascala`, można użyć kompilatora z `Delphi`, jeśli ktoś ma akurat zainstalowane środowisko `Delphi 7.0` lub nowsze.

  Innym sposobem, bardziej multi platformowym jest użycie kompilatora z pakietu `Free Pascal Compiler (FPC)`, który można pobrać ze strony http://www.freepascal.org/

  Uruchamiamy instalator, wybieramy katalog w którym zostanie zainstalowany `FP`. Ważne jest aby nie używać w nazwie katalogu znaku wykrzyknika `'!'` czy innych nie standardowych znaków. Jeśli nie uda nam się skompilować żadnego pliku, najpewniej winna jest nie standardowa nazwa ścieżki. Linia komend uruchamiająca kompilację może wyglądać następująco (wielkość liter w nazwach parametrów ma znaczenie):

      fpc -Mdelphi -v -O3 mp.dpr

- -Mdelphi pozwala kompilować plik w formacie `Delphi`
- -v wyświetla wszystkie komunikaty błędów i ostrzeżeń
- -O3 dokonuje optymalizacji kodu

  SPOSÓB UŻYCIA

  `

  ## Przełączniki kompilatora

  `

      Syntax: mp source [switches]

      -d:address      tryb diagnostyczny
      -code:$address  adres uruchomienia programu
      -data:$address  adres pamięci dla zmiennych, tablic
      -stack:$address adres pamięci dla stosu programowego (64 bajty)
      -zpage:$address adres na stronie zerowej dla zmiennych (24 bajty)

  -d
  Użycie przełącznika `-d` powoduje wygenerowanie dodatkowego pliku z informacją o wszystkich użytych zmiennych, procedurach, funkcjach.

  Domyślnym rozszerzeniem pliku wynikowego jest *.A65, plik taki assemblujemy z użyciem Mad-Assemblera (dodatkowo ustawiamy ścieżkę poszukiwań na -i:base), np.:

       mads source.a65 -x -i:base

  Przełącznik -x (Exclude unreferenced procedures) pozwoli wygenerować najkrótszy kod wynikowy dla 6502.

  `

  ## Kody wyjścia

  `

      3 = bad parameters, compiling not started
      2 = error occured
      0 = no errors

  Komunikaty ostrzeżenia nie powodują zmiany wartości kodu wyjścia.

  SKŁADNIA

  `

  ## Komentarze

  ` Comments

  W MP do oznaczenia komentarza jednoliniowego służą znaki `'//'`, dla wieloliniowego klamry `{ }`, lub `(* *)`.

       // to jest komentarz
       inc(a); // to jest komentarz

       (* komentarz *)

       (*

        komentarz

       *)

       { to
         jest
         komentarz
       }

  `

  ## Zarezerwowane słowa

  ` Zarezerwowane rozkazy:

      absolute
      and
      array
      asm
      begin
      case
      const
      div
      do
      downto
      else
      end
      file
      for
      function
      if
      implementation
      interface
      main
      mod
      not
      of
      or
      procedure
      program
      record
      repeat
      shl
      shr
      stack
      string
      then
      to
      type
      unit
      until
      uses
      var
      while
      xor

  Zarezerwowane stałe:

      pi
      true
      false

  WYRAŻENIA

  Expression `

  ## Liczby

  ` Numbers

- zapis decymalny:

       -100
       -2437325
       1743

- zapis hexadecymalny:

       $100
       $e430
       $000001

- zapis binarny:

       %0001001010
       %000000001
       %001000

- zapis kodami ATASCII:

       'a'
       'fds'
       'W'
       #65#32#65
       #$9b

  `

  ## Operatory

  ` Arithmetic operators

      +   Addition
      -   Subtraction
      *   Multiplication
      /   Division
      DIV Integer division
      MOD Remainder

  Logical operators

      NOT Bitwise negation (unary)
      AND Bitwise and
      OR  Bitwise or
      XOR Bitwise xor
      SHL Bitwise shift to the left
      SHR Bitwise shift to the right

  Boolean operators

      NOT logical negation (unary)
      AND logical and
      OR  logical or
      XOR logical xor

  Relational operators

      =   Equal
      <>  Not equal
      <   Less than
      >   Greater than
      <=  Less than or equal
      >=  Greater than or equal

  DYREKTYWY KOMPILATORA

  Compiler directives

  Zapis dyrektyw kompilatora ma postać:

  - {$dyrektywa parametry}
  - {$lista_dyrektyw_przełącznikowych}
  Dyrektywa stanowi komentarz, w którym pierwszy znak $ odróżnia zwykły komentarz, od dyrektywy kompilatora. `

  ## CONDITIONAL {$IFDEF label}, {$IFNDEF label}, {$ELSE}, {$ENDIF}, {$DEFINE label}, {$UNDEF label}

  ` Conditional compilation

      {$define test}

      const
      	{$ifdef test}
      	a=1;
      	{$else}
      	a=2;
      	{$endif}

  `

  ## FASTMUL {$F page}

  ` Seriously fast multiplication (8-bit and 16-bit)

      {$f $70}  // fastmul at $7000

  Alternatywne procedury szybkiego mnożenia dla typu BYTE, SHORTINT, WORD, SMALLINT, SHORTREAL. Procedury zajmują 2KB i są umieszczane od adresu PAGE*256.

  `

  ## IOCHECK {$I+} {$I-}

  ` Input/Output checking

      {i+}  IOCHECK ON  default
      {i-}  IOCHECK OFF

  Dla {$i+} w przypadku wystąpienia błędów transmisji I/O (RESET, REWRITE, BLOCKREAD, BLOCKWRITE, CLOSE) wykonywany program zostaje zatrzymany, generowany jest komunikat błędu 'ERROR xxx'. Wyłączenie IOCHECK {$i-} przydaje się gdy chcemy sprawdzić istnienie pliku na dysku, np.:

      function FileExists(name: TString): Boolean;
      var f: file;
      begin

        {$I-}     // io check off
        Assign (f, name);
        Reset (f);
        Result:=(IoResult<128) and (length(name)>0);
        Close (f);
        {$I+}     // io check

      end;

  W blokach PROCEDURE, FUNCTION dyrektywa IOCHECK jest zasięgu lokalnego, po zakończeniu kompilacji takiego bloku przywracana jest wartość IOCHECK która została określona poza takim blokiem.

  `

  ## INCLUDE {$I filename}

  ` Include file

  Dyrektywa dołączenia tekstu zawartego w pliku.

  `

  ## LIBRARY PATH {$LIBRARYPATH path1;path2;...}

  ` Specify library path

  Dyrektywa pozwalająca wskazać dodatkowe ścieżki poszukiwań dla bibliotek (unit).

  `

  ## RESOURCE {$R filename}

  ` Include resource

  ## RCLABEL RCTYPE RCFILE [PAR0 PAR1 PAR2 PAR3 PAR4 PAR5 PAR6 PAR7]

  Dyrektywa dołączenia pliku z zasobami. Plik zasobów jest plikiem tekstowym, każdy jego kolejny wiersz powinien składać się z trzech pól rozdzielonych "białym znakiem": etykieta RCLABEL (jej deklaracja musi znaleźć się także w programie), typ zasobów RCTYPE, lokalizacja pliku RCFILE. Aktualnie w pliku BASE\RES6502.ASM znajdują się makra do obsługi 10 typów zasobów RCTYPE:

  `RCDATA` | `dowolny typ danych`
  `DOSFILE` | `plik z nagłówkiem Atari DOS, adres ładowania takiego pliku powiniem być identyczny jak RCLABEL`
  `RELOC` | `plik relokowalny w formacie MadAssemblera, plik zostanie poddany relokacji pod wskazany adres RCLABEL`
  `RMT` | `plik modułu Raster Music Tracker-a, plik zostanie poddany relokacji pod wskazany adres RCLABEL`
  `MPT` | `plik modułu Music ProTracker-a, plik zostanie poddany relokacji pod wskazany adres RCLABEL`
  `CMC` | `plik modułu Chaos Music Composer-a, plik zostanie poddany relokacji pod wskazany adres RCLABEL`
  `RMTPLAY` | `player dla modułu RMT, jako RCFILE podajemy plik *.FEAT oraz dodatkowo PAR0 tryb playera 0..3`
      0 => compile RMTplayer for 4 tracks mono
      1 => compile RMTplayer for 8 tracks stereo
      2 => compile RMTplayer for 4 tracks stereo L1 R2 R3 L4
      3 => compile RMTplayer for 4 tracks stereo L1 L2 R3 R4
  `MPTPLAY` | `player dla modułu MPT`
  `CMCPLAY` | `player dla modułu CMC`
  `XBMP` | `plik Windows Bitmap (8 BitsPerPixel) ładowany do pamięci VBXE pod wskazany adres RCLABEL od indeksu koloru PAR0 w palecie kolorów VBXE nr 1`

      Przykład:

      bmp1  RCDATA   'pic.mic'

      msx   MPT      'porazka.mpt'

      play  RMTPLAY   'modul.feat' 1

      bmp   XBMP     'pic.bmp' 80

  CONSTANTS

  Ordinary constants

  Do deklaracji stałych CONST służy znak '='. Dopuszczalne jest użycie operatorów +, -, *, /, not, and, or, div, mod, ord, chr, sizeof, pi

      Const
        e = 2.7182818;       { Real type constant }
        f : single = 3.14;   { Single type constant }
        a = 2;               { Ordinal BYTE type constant }
        c = '4';             { Character type constant }
        s = 'atari';         { String type constant }
        sc = chr(32);
        ls = SizeOf(cardinal);

        x: word = 5;         { wymuszenie typu stałej }

  TYPES

  `

  ## Typy porządkowe

  ` Typ porządkowy
  Ordinal types

  Type | Range | Size in bytes
  BYTE | 0 .. 255 | 1
  SHORTINT | -128 .. 127 | 1
  WORD | 0 .. 65535 | 2
  SMALLINT | -32768 .. 32767 | 2
  CARDINAL | 0 .. 4294967295 | 4
  LONGWORD | 0 .. 4294967295 | 4
  DWORD | 0 .. 4294967295 | 4
  UINT32 | 0 .. 4294967295 | 4
  INTEGER | -2147483648 .. 2147483647 | 4
  LONGINT | -2147483648 .. 2147483647 | 4

  `

  ## Typy logiczne

  ` Boolean types

  Name | Size | Ord(True)
  BOOLEAN | 1 | 1

  `

  ## Typy wyliczeniowe

  ` Enumeration types

  Typ wyliczeniowy w MP został zaimplementowany w podstawowej postaci, tzn.:

      Type
        Days = (monday,tuesday,wednesday,thursday,friday,
                saturday,sunday);

        Joy = (right_down = 5, right_up, right, left_down = 9, left_up, left, down = 13, up, none);

  Typ wyliczeniowy przechowywany jest tylko w pamięci kompilatora MP, do pliku wynikowego nie zostaną zapisane jakiekolwiek informacje dotyczące pól typu wyliczeniowego. Dopuszczalne jest użycie komendy ORD, SIZEOF oraz rzutowania dla typu wyliczeniowego.

      var
         d: Days;

         d:=friday;
         writeln(ord(d));
         writeln(ord(sunday));
         writeln(sizeof(days));
         writeln(sizeof(monday));

         d:=days(20);

         case d of
          sunday: writeln('sunday');
         end;

  Aktualnie kompilator MP nie sprawdzi poprawności typów wyliczeniowych dla operacji IF ELSE.

  `

  ## Typy rzeczywiste

  ` Real types

  Type | Range | Size in bytes
  SHORTREAL (Q8.8) | -128..127 | 2
  REAL (Q24.8) | -8388607..8388608 | 4
  SINGLE (IEEE-754) | 1.5E-45 .. 3.4E38 | 4
  FLOAT (IEEE-754) | 1.5E-45 .. 3.4E38 | 4

  `

  ## Typy znakowe

  ` Char
  Short strings

  Type | Range | Size in bytes
  CHAR | ATASCII (0 .. 255) | 1
  STRING | 1 .. 255 | 256

  Ciąg znaków STRING reprezentowany jest jako tablica o możliwym maksymalnym rozmiarze [0..255]. Pierwszym bajtem takiej tablicy [0] jest długość ciągu z zakresu 0..255. Od bajtu [1..] zaczyna się właściwy ciąg znaków.

  Dopuszczalne jest użycie dodatkowych znaków po końcowym apostrofie, takich jak '*', '~'. Znak '*' oznacza ciąg w inwersie, tylda '~' ciąg w kodach ANTIC-a.

       a: string = 'Atari'*;         // ciąg znaków w inwersie
       b: string = 'Spectrum'~;      // ciąg znaków w kodach ANTIC-a
       c: char = 'X'~*;              // znak w inwersie, kodach ANTIC-a

  `

  ## Wskaźniki

  ` Pointers

  Type | Range | Size in bytes
  POINTER | 0 .. 65535 | 2

  Wskaźniki w MP mogą być typowane i bez określonego typu, np.:

       a: ^word;         // wskaźnik typowany na słowo
       b: pointer;       // wskaźnik bez typu

  Niezaincjowany wskaźnik najczęściej będzie miał adres $0000, należy zadbać aby przed jego wykorzystaniem zaincjować go adresem odpowiedniej zmiennej, np.:

       a := @tmp;         // wskaźnikowi A zostaje przypisany adres zmiennej TMP

  Jeśli tego nie zrobimy to w przypadku uruchomienia takiego programu na PC spowodujemy błąd ochrony pamięci 'Access Violation'.

  Zwiększanie wskaźnika przez INC zwiększy go o rozmiar typu na jaki wskazuje. Zmniejszenie wskaźnika przez DEC zmniejszy go o rozmiar typu na jaki wskazuje. Jeśli typ jest nieokreślony, wówczas domyślną wartością zwiększania/zmniejszanie będzie 1.

  `

  ## Tablice

  ` Static Arrays

  Tablice w MP są tylko statyczne, jednowymiarowe lub dwuwymiarowe z początkowym indeksem =0, np.:

      var tb: array [0..100] of word;
      var tb2: array [0..15, 0..31] of Boolean;

  W przypadku początkowego indeksu innego niż zero zostanie wygenerowany błąd `'Error: Array lower bound is not zero'`.

  W pamięci tablica reprezentowana jest przez wskaźnik (POINTER), wskaźnik jest adresem tablicy w pamięci (WORD). Najszybszą metodą odwołania się do tablicy z poziomu assemblera jest zastosowanie przedrostka 'ADR.', np.:

      asm
      { lda adr.tb,y   ; bezpośrednie odwołanie do tablicy TB
        lda tb         ; odwołanie do wskaźnika tablicy TB
      };

  Kompilator generuje kod dla tablic zależnie od ich deklaracji:

  `array [0..255] of byte array [0..127] of word array [0..63] of cardinal` | `Gdy liczba bajtów zajmowanych przez tablicę nie przekracza 256 bajtów generowany jest najszybszy kod odwołujący się bezpośrednio do adresu tablicy (przedrostek ADR.) z pominięciem wskaźnika. Dla takiej tablicy nie ma możliwości zmiany adresu.`
       ldy #118
       lda adr.tb,y
  `array [0..0] of type` | `Gdy liczba elementów tablicy wynosi '1' jest ona traktowana specjalnie. Generowany kod odwołuje się do tablicy poprzez wzkaźnik. Istnieje możliwość ustalenia nowego adresu takiej tablicy.`
       lda TB
       add I
       tay
       lda TB+1
       adc #$00
       sta bp+1
       lda (bp),y
  `array [0..255+1] of byte array [0..127+1] of word array [0..63+1] of cardinal` | `Gdy liczba bajtów zajmowanych przez tablicę przekracza 256 bajtów generowany kod odwołuje się do tablicy poprzez wskaźnik. Istnieje możliwość ustalenia nowego adresu takiej tablicy.`
       lda TB
       add I
       tay
       lda TB+1
       adc #$00
       sta bp+1
       lda (bp),y

  `

  ## Rekordy

  ` Record types

  W pamięci rekord reprezentowany jest przez wskaźnik (POINTER).

      type
          TPoint = record x,y: byte end;

      var px: TPoint;

  Domyślnie rekordy w MP są typu PACKED.

  Jeśli zależy nam na zachowania kompatybilności z FPC należy dodatkowo poprzedzić słowo 'record' słowem 'packed'.
  Bez tego rozmiar pamięci jaki zajmuje rekord będzie mógł się różnić, bęzie mniej zajmował pamięci na Atari XE/XL, potencjalnie więcej o kilka bajtów na PC.

      type
          TPoint = packed record x,y: byte end;

      var px: TPoint;

  Dostęp do pól rekordu z poziomu asm:

       mwa px bp2
       ldy #px.x-DATAORIGIN
       lda (bp2),y

  `

  ## Obiekty

  ` Objects types

  Obiekty to rekordy z dodatkowymi metodami. W pamięci obiekt reprezentowany jest przez wskaźnik (POINTER).

      type
      	TRMT = Object

      	player: pointer;
      	modul: pointer;

      	procedure Init(a: byte); assembler;
      	procedure Play; assembler;
      	procedure Stop; assembler;

      	end;

  `

  ## Pliki

  ` File types

  Typ FILE reprezentuje uchwyt do pliku oraz definiuje rozmiar rekordu.

      type
       ftype = array [0..63] of cardinal;

      var f: file;               // rekord domyślny =128 bajtów
          f: file of byte;       // rekord 1 bajt
          f: file of ftype;      // rekord 256 bajtów (ftype = 64 * 4)

  W pamięci XE/XL uchwyt FILE reprezentowany jest przez wskaźnik (POINTER) do tablicy o strukturze (rozmiar 12 bajtów):

      .struct	s@file
      pfname   .word		; pointer to string with filename
      record   .word		; record size
      chanel   .byte		; channel *$10
      eof      .byte		; EOF status
      buffer   .word		; load/write buffer
      nrecord  .word		; number of records for load/write
      numread  .word		; pointer to variable, length of loaded data
      .ends

  Do procedur, funkcji typ FILE może być przekazywany tylko jako zmienna (VAR).

  INSTRUKCJE WARUNKOWE

  `

  ## CASE OF ELSE

  ` The Case statement

  Obecnie Mad Pascal akceptuje dla zmiennej CASE typy tylko o długości 1 bajta: SHORTINT, BYTE, CHAR, BOOLEAN

       case a of             // dla zmiennej A typu CHAR
        'A'..'Z': begin end;
        '0'..'9': begin end;
         '+','*': begin end;
       end;

  `

  ## IF THEN ELSE

  ` The If..then..else statement

  Instrukcje warunkowe IF mogą być zagnieżdżane. Wykorzystywane jest to przy budowie bardziej złożonych warunków.

  INSTRUKCJE ITERACYJNE

  `

  ## FOR TO DOWNTO DO

  ` The For..to/downto..do statement

      FOR zmienna := { wartość początkowa } TO { wartość końcowa } DO { instrukcje do wykonania }
      FOR zmienna := { wartość końcowa } DOWNTO { wartość początkowa } DO { instrukcje do wykonania }

  Instrukcja ta służy do organizacji obliczeń, które będą wykonywane z góry określoną liczbę razy. Zmienna sterująca musi być identyfikatorem typu porządkowego, a oba wyrażenia powinny być zgodne w sensie przypisania z typem zmiennej sterującej. W czasie realizacji pętli TO zmiennej sterującej przypisywana jest następna wartość w danym typie, w pętli DOWNTO poprzednia. Zabroniona jest "ręczna" zmiana wartości zmiennej sterującej. W przypadku takiej próby MP nie zasygnalizuje błędu.

  Kompilator dba o to aby nie wystąpiła pętla bez końca, dlatego można bez obaw stosować taką pętlę:

       for i:=0 to 255 do writeln(i);    // dla zmiennej I typu BYTE

  `

  ## WHILE DO

  ` The While..do statement

      while { warunek } do
      { instrukcja do wykonania }

  Konstrukcja ta służy do organizacji obliczeń, które będą wykonywane tak długo jak wyrażenie znajdujące się po słowie WHILE jest prawdą. Tak skonstruowana pętla może nie zostać wykonana ani razu.

       while BlitterBusy do;   // oczekiwanie na zakończenie działania blittera VBXE

  Ograniczenia dla instrukcji WHILE:

       while i<=255 do inc(i); // pętla bez końca gdy zmienna I typu BYTE

  `

  ## REPEAT UNTIL

  ` The Repeat..until statement

      repeat
        { instrukcje do wykonania }
      until { warunek zakończenia }

  Instrukcja ta wykonuje cyklicznie inne instrukcje zawarte pomiędzy słowami REPEAT i UNTIL do momentu gdy wyrażenie znajdujące się za słowem UNTIL nie przyjmie wartości PRAWDA (czyli TRUE).

  Efekt zastosowania pętli REPEAT jest bardzo podobny do działania pętli WHILE. Pętla ta także może być wykonywana ogromną liczbę razy. Jedyna różnica polega na tym, że w pętli REPEAT warunek zakończenia sprawdzany jest dopiero po wykonaniu instrukcji. Oznacza to, że pętla REPEAT zawsze będzie wykonana co najmniej raz. Dopiero po tej iteracji program sprawdzi, czy można zakończyć działanie pętli. W przypadku pętli WHILE warunek jest sprawdzany bezpośrednio przed jej wykonaniem, co w rezultacie może spowodować, że taka pętla nigdy niezostanie wykonana.

       i:=0;
       repeat
       inc(i);
       until i=0;		 // pętla wykona się 256 razy

  PROCEDURY I FUNKCJE

  `

  ## Procedure

  ` Procedure declaration

  MP pozwala na przekazanie do procedury maksymalnie 8 parametrów. Są dostępne trzy sposoby przekazywania parametrów - przez wartość, stałą (CONST) i zmienną (VAR). Możliwe jest użycie modyfikatora OVERLOAD w celu przeciążenia procedur.

  Dostępne modyfikatory procedur: OVERLOAD, ASSEMBLER, FORWARD, REGISTER, INTERRUPT.

  Możliwa jest rekurencja procedur, pod warunkiem że parametry procedury będą przekazywane przez wartość, będą typu prostego - porządkowego. Typ rekordowy, wskaźnikowy nie będzie właściwie alokowany w pamięci.

  `

  ## Function

  ` Function declaration

  MP pozwala na przekazanie do funkcji maksymalnie 8 parametrów. Są dostępne trzy sposoby przekazywania parametrów - przez wartość, stałą (CONST) i zmienną (VAR). Wynik funkcji zwracamy przypisując go do nazwy funkcji lub korzystając z automatycznie deklarowanej zmiennej RESULT, np.:

      function add(a,b: word): cardinal;
      begin

       Result := a+b;

      end;

      function mul(a,b: word): cardinal;
      begin

       mul := a*b;

      end;

  Dostępne modyfikatory funkcji: OVERLOAD, ASSEMBLER, FORWARD, REGISTER, INTERRUPT (nie zalecane dla funkcji).

  Możliwa jest rekurencja funkcji, pod warunkiem że parametry funkcji będą przekazywane przez wartość, będą typu prostego - porządkowego. Typ rekordowy, wskaźnikowy nie będzie właściwie alokowany w pamięci.

  MODYFIKATORY PROCEDUR I FUNKCJI

  `

  ## ASSEMBLER

  ` Procedury/Funkcje oznaczona przez ASSEMBLER mogą składać się tylko z bloku ASM. Kompilator nie dokonuje analizy składni takich bloków, traktuje je jak komentarz, ewentualne błędy zostaną wychwycone dopiero podczas asemblacji.

      procedure color(a: byte); assembler;
      asm
      {	mva a 712
      };
      end;

  `

  ## OVERLOAD

  ` Procedury/Funkcje przeciążone rozpoznawane są na podstawie listy parametrów.

      procedure suma(var i: integer; a,b: integer); overload;
      begin
       i := a+b;
      end;

      procedure suma(var i: integer; a,b,c: integer); overload;
      begin
       i := a+b+c;
      end;

      function fsuma(a,b: word): cardinal; assembler; overload;
      asm
      {
       adw a b result
      };
      end;

      function fsuma(a,b: real): real; overload;
      begin
       Result := a+b;
      end;

  `

  ## FORWARD

  ` Jeżeli chcemy aby procedura/funkcja była zadeklarowana za miejscem jej pierwszego wywołania, należy użyć modyfikator FORWARD.

      procedure nazwa [(lista-parametrów-formalnych)]; forward;

      ...
      ...
      ...

      procedure nazwa;
      begin
      end;

  `

  ## REGISTER

  ` Użycie modyfikatora REGISTER spowoduje że trzy pierwsze parametry formalne procedury/funkcji będą umieszczone na stronie zerowej, w 32-bitowych rejestrach programowych, odpowiednio EDX, ECX, EAX.

      procedure nazwa (a,b,c: cardinal); register;

      // a = edx
      // b = ecx
      // c = eax

  `

  ## INTERRUPT

  ` Procedury/Funkcje oznaczone przez INTERRUPT kompilator będzie kończył rozkazem RTI (standardowo RTS). Zaleca się używanie bloku ASM w przypadku takich procedur/funkcji, w innym przypadku stos programowy Mad Pascala zostanie zniszczony, co może doprowadzić do niestabilnego działania programu, łącznie z zawieszeniem się komputera. Na wejściu procedury/funkcji oznaczonej przez INTERRUPT programista musi zadbać o zachowanie rejestrów CPU (A, X, Y), na wyjściu o przywrócenie stanu takich rejestrów, kompilator ogranicza się tylko do wstawienia końcowego rozkazu RTI.

      procedure dli; interrupt;
      asm
      {	pha

      	lda #$c8
      	sta wsync
      	sta $d01a

      	pla
      };
      end;             // rozkaz RTI zostanie wstawiony automatycznie

  UNITS

  Units
  Moduły

  Moduły (UNIT) w MP składają się z sekcji INTERFACE (wymagany), IMPLEMENTATION (wymagany), INITIALIZATION (opcjonalny).

      unit test;

      interface

      type	TUInt24 =
      	record
      		byte0: byte;
      		byte1: byte;
      		byte2: byte;
      	end;

      const
      	LoRes = 1;
      	MedRes = 2;
      	HiRes = 3;

      	procedure Print(a: string);

      implementation

      uses test2;

      procedure Print(a: string);
      begin

       writeln(a);

      end;

      end.

  BIBLIOTEKA PODSTAWOWA

  W katalogu 'LIB' Mad-Pascala znajdują się potrzebne do kompilacji podstawowe moduły (unit), takie jak SYSTEM, CRT, GRAPH, SYSUTILS, MATH, DOS. W programie wybierane są przez instrukcję USES, np.:

      uses crt, sysutils;

  Moduł SYSTEM jest domyślnie dopisywany do listy USES i kompilowany jako pierwszy. `

  ## SYSTEM

  ` Reference for unit 'System': Procedures and functions

  [ Constants ]

      M_PI_2           = 6.283285;  // pi * 2
      D_PI_2           = 1.570796;  // pi / 2
      D_PI_180         = 0.017453;  // pi / 180

      mGTIA            = 0;
      mVBXE            = $80;
      WINDOW           = $10;
      NARROW           = $20;

      VBXE_XDLADR      = $0000;     // XDLIST
      VBXE_MAPADR      = $1000;     // COLOR MAP ADDRESS
      VBXE_BCBADR      = $0100;     // BLITTER LIST ADDRESS
      VBXE_OVRADR      = $5000;     // OVERLAY ADDRESS
      VBXE_WINDOW      = $B000;     // 4K WINDOW $B000..$BFFF

      iDLI             = 0;
      iVBL             = 1;

      CH_DELCHR        = $FE;
      CH_ENTER         = $9B;
      CH_ESC           = $1B;
      CH_CURS_UP       = 28;
      CH_CURS_DOWN     = 29;
      CH_CURS_LEFT     = 30;
      CH_CURS_RIGHT    = 31;

      CH_TAB           = $7F;
      CH_EOL           = $9B;
      CH_CLR           = $7D;
      CH_BEL           = $FD;
      CH_DEL           = $7E;
      CH_DELLINE       = $9C;
      CH_INSLINE       = $9D;

      COLOR_BLACK      = $00;
      COLOR_WHITE      = $0e;
      COLOR_RED        = $32;
      COLOR_CYAN       = $96;
      COLOR_VIOLET     = $68;
      COLOR_GREEN      = $c4;
      COLOR_BLUE       = $74;
      COLOR_YELLOW     = $ee;
      COLOR_ORANGE     = $4a;
      COLOR_BROWN      = $e4;
      COLOR_LIGHTRED   = $3c;
      COLOR_GRAY1      = $04;
      COLOR_GRAY2      = $06;
      COLOR_GRAY3      = $0a;
      COLOR_LIGHTGREEN = $cc;
      COLOR_LIGHTBLUE  = $7c;

  [ Types ]

  `TPoint` | ``TPoint = record x,y: SmallInt end;;`` Definicja współrzędnych (x,y).
  `TRect` | ``TRect = record left, top, right, bottom: smallint end;`` Definicja położenia i rozmiaru czworokąta o parametrach (left, top) - lewy górny narożnik, (right, bottom) - prawy dolny narożnik.
  `TString` | ``TString = string[32];`` Definicja krótkiego ciągu znakowego wykorzystywanego do przekazywania nazw plików itp.

  [ Variables ]

  `IOResult` | ``IOResult: byte;`` Kod błędu (>127) dla ostatnio przeprowadzonej operacji I/O.
  `ScreenWidth` | ``ScreenWidth: word = 40;`` Zmienna przechowująca aktualną szerokość ekranu. Domyślnie jest to wartość 40 dla ekranu edytora.
  `ScreenHeight` | ``ScreenHeight: word = 24;`` Zmienna przechowująća aktualną wysokość ekranu. Domyślnie jest to wartość 24 dla ekranu edytora.

  [ Procedures and functions ]

  `Abs` | ``function Abs(x: real): real; function Abs(x: integer): integer;`` Funkcja obliczająca wartość bezwzględną podanej liczby (ang. Absolute value). Wartość bezwzględna liczby nieujemnej to ta sama liczba, a liczby ujemnej - liczba do niej przeciwna. Funkcja w przypadku podania jej argumentu całkowitego zwraca wynik również typu całkowitego.
  `ArcTan` | ``function ArcTan(x: real): real;`` Funkcja ArcTan (arcus tangens) zwraca wartość kąta, którego tangens wynosi x.
  `Assign` | ``procedure Assign(var F:File; FileName:string)` Procedura przypisuje zmiennej plikowej F plik o nazwie FileName. Aby móc odwoływać się do jakiegoś pliku, zawsze należy najpierw użyć procedury Assign. Przy dalszych operacjach pliki są identyfikowane przy pomocy zmiennej plikowej, a nie nazwy.`
  `BinStr` | ``function BinStr(Value: cardinal; Digits: byte): TString;`` Funkcja BinStr zwraca ciąg znakowy z reprezentacją binarną wartości Value. Digits określa długość ciągu, który maksymalnie może liczyć 32 znaki.
  `Concat` | ``function Concat(a,b: string): string; assembler function Concat(a: string; b: char): string; assembler; function Concat(a: char; b: string): string; assembler; function Concat(a,b: char): string;`` Funkcja łączy dwa ciągi tekstowe w nowy ciąg znakowy.
  `Blockread Blockwrite` | ``procedure BlockRead(var f: file; var Buf; Count: word; var Result: word); procedure BlockWrite(var f: file; var Buf; Count: word; var Result: word);`` Procedura BlockRead wczytuje z pliku plik do zmiennej Buf nie więcej niż Count bajtów i umieszcza w zmiennej Result ilość rzeczywiście przeczytanych bajtów (która może być mniejsza od oczekiwanej np. ze względu na rzeczywistą długość pliku). Procedura BlockWrite działa tak samo, tylko zapisuje do pliku.
  `Chr` | ``function Chr(X: Byte): Char;` Funkcja zwraca znak (Char) o odpowiadającym kodzie ATASCII podanym w parametrze.
      Chr(65); // Zwraca znak A
      Chr(90); // Zwraca znak Z
      Chr(32); // Zwraca znak spacji
  Zamiennie z funkcją Chr, chcąc uzyskać odpowiedni znak możemy użyć jego kodu ATASCII poprzedzając go #
      Writeln(#65);       // Znak A
      Writeln(#65#32#65); // Napisze 'A Z'
  `
  `Cos` | ``function Cos(x: real): real;`` Cosinus kąta (x w radianach).
  `Close` | ``procedure Close(var f: file);`` Procedura służąca do zamykania otwartego pliku dowolnego typu. Każdy plik otwarty przy pomocy Reset lub Rewrite powinno się zamknąć przy pomocy Close.
  `Dec` | ``procedure Dec(var X [, N: int]);` Procedura zmniejsza wartość parametru X o 1 lub wartość parametru N. Wartość parametru X może być typu CHAR, BYTE, WORD, CARDINAL. Procedura DEC generuje optymalny kod, jest zalecana do używania w pętlach, zamiast operatora odejmowania (-).
       dec(tmp);
       dec(tmp[2]);
  `
  `DeleteFile` | ``function DeleteFile(FileName: string): Boolean;`` Funkcja pozwala skasować plik z dysku o nazwie FileName, zwraca TRUE kiedy operacja powiodła się, FALSE w przypadku wystąpienia błędu (najczęściej z powodu zabezpieczenia przed zapisem lub błędnej nazwy pliku).
  `DPeek` | ``function DPeek(a: word): word;` Funkcja zwraca słowo spod adresu A.`
  `DPoke` | ``procedure DPoke(a: word; value: word);` Procedura zapisuje słowo Value pod adresem A.`
  `Eof` | ``function Eof(var f: file): Boolean;` Funkcja zwraca wartość logiczną True jeśli osiągnięty został koniec pliku.`
  `Exit` | `Wywołanie procedury Exit powoduje natychmiastowe opuszczenie bloku programu, w którym to wywołanie nastąpiło. Można jej użyć do opuszczenia pętli, wyjścia z procedury/funkcji lub programu głównego.`
  `Exp` | ``function Exp(x: real): real;` Funkcja podnosząca liczbę e (=2.71) do potęgi podanej przez argument.`
  `FilePos` | ``function FilePos(var f: file): cardinal;` Funkcja zwraca aktualną pozycję pliku. Plik nie może być tekstowy i musi być otwarty (np. poleceniem Reset). Bity 0..15 zwróconej wartości to numer sektora dysku, bity 16..23 pozycja w sektorze [0..255]. Jest to odpowiednik instrukcji NOTE.`
  `FileSize` | ``function FileSize(var f: file): cardinal;` Funkcja zwraca długość pliku w bajtach (Sparta DOS X). Plik nie może być tekstowy i musi być otwarty (np. poleceniem Reset).`
  `FillChar` | ``procedure FillChar(a: pointer; count: word; value: char);` Procedura wypełnia bufor określony w parametrze X identycznymi znakami lub bajtami. Parametr Value musi określać dane, natomiast Count - ilość danych jakie zostaną przypisane do bufora.
      var
        Buffer : array[0..100] of Char;
      begin
        FillChar(Buffer, SizeOf(Buffer), 'A');
      end.
  `
  `Frac` | ``function Frac(x: real): real;` Zwraca część ułamkową liczby x w postaci rzeczywistej.`
  `GetIntVec` | ``procedure GetIntVec(intno: Byte; var vector: pointer);` Procedura odczytuje adres wektora przerwań wg. kodu INTNO. Obecnie dopuszczalnymi kodami są:
      iDLI - przerwanie DLI
      iVBL - przerwanie VBL
  `
  `Halt` | ``procedure halt;` Wywołanie powoduje natychmiastowe wyjście z programu. Można (opcjonalnie) podać kod błędu, w przypadku MP jest on ignorowany.`
  `Hi` | ``function Hi(x): byte` Funkcja zwracająca starszy bajt parametru X.`
  `HexStr` | ``function HexStr(Value: cardinal; Digits: byte): TString;`` Funkcja HexStr zwraca ciąg znakowy z reprezentacją heksadecymalną wartości Value. Digits określa długość ciągu, który maksymalnie może liczyć 32 znaki.
  `Inc` | ``procedure Inc(var X [, N: int]);` Procedura zwiększa wartość parametru X o 1 lub wartość parametru N. Wartość parametru X może być typu CHAR, BYTE, WORD, CARDINAL. Procedura INC generuje optymalny kod, jest zalecana do używania w pętlach, zamiast operatora dodawania (+).
       inc(tmp);
       inc(tmp[2]);
  `
  `Int` | ``function Int(x: real): real;` Funkcja zwraca część całkowitą argumentu będącego liczbą rzeczywistą.`
  `IOResult` | ``var IOResult: byte;` Zmienna IOResult przechowuje ostatni błąd operacji I/O. Kody błędów I/O`
  `Ln` | ``function Ln(x: real): real;` Funkcja licząca logarytm naturalny (o podstawie e) z podanej liczby. Argument funkcji musi być dodatni!`
  `Lo` | ``function Lo(x): byte;` Funkcja zwracająca młodszy bajt parametru X.`
  `LowerCase` | ``function LowerCase(a: char): char;` Funkcja zmieniająca znaki 'A'..'Z' na odpowiednie małe znaki 'a'..'z'`
  `Move` | ``procedure Move(source, dest: pointer; count: word);` Procedura służy do kopiowania danych ze źródła (parametr Source) do bufora oznaczonego jako przeznaczenie (parametr Dest). Ilość kopiowanych danych określa parametr Count.`
  `OctStr` | ``function OctStr(Value: cardinal; Digits: byte): TString;`` Funkcja OctStr zwraca ciąg znakowy z reprezentacją ósemkową wartości Value. Digits określa długość ciągu, który maksymalnie może liczyć 32 znaki.
  `Odd` | ``function Odd(x: cardinal): Boolean; function Odd(x: integer): Boolean;`` Funkcja Odd zwraca wartość True jeżeli liczba określona w parametrze X jest nieparzysta, False jeżeli jest parzysta.
  `Ord` | ``function Ord(X);` Funkcja ta działa odwrotnie do Chr. Z podanego znaku jako parametr zwraca nam jego kod w ATASCII.
      Ord('A'); // Zwraca 65
      Ord('Z'); // Zwraca 90
      Ord(' '); // Zwraca 32
  `
  `ParamCount` | ``function ParamCount: byte;` Funkcja ParamCount zwraca ilość dostępnych argumentów (Sparta Dos X, BWDos), tzn. maksymalny indeks dla procedury ParamStr. ParamCount określa ilość parametrów przekazanych do programu z linii poleceń.`
  `ParamStr` | ``function ParamStr(Index: byte): TString;` Funkcja ParamStr zwraca parametry programu (Sparta Dos X, BWDos). Index to numer parametru, czyli ciągu znaków oddzielonego spacją. Jeżeli uruchomimy program TEST.EXE w taki sposób:
      TEST.EXE parametr1 parametr2 parametr3
  To aby uzyskać parametr3 należy podać Index=3, zaś aby uzyskać parametr1 należy Index=1. Index=0 to specjalny argument, wtedy funkcja zwraca napęd z którego został uruchomiony programu, np. 'D1:'`
  `Pause` | ``procedure Pause; procedure Pause(n: word);` Zatrzymuje działanie programu na N * 1.50 sek`
  `Peek` | ``function Peek(a: word): byte;` Funkcja zwraca bajt spod adresu A.`
  `Point` | ``function Point(AX, AY: smallint): TPoint;` Na podstawie parametrów AX oraz AY tworzony jest rekord typu TPoint.`
  `PointsEqual` | ``function PointsEqual(const P1, P2: TPoint): Boolean;` Funkcja sprawdza czy wartości współrzędnych określone w parametrach P1 oraz P2 są sobie równe. W takim wypadku funkcja zwraca wartość True.`
  `Poke` | ``procedure Poke(a: word; value: byte);` Procedura zapisuje bajt Value pod adresem A.`
  `Pi` | `Zwraca wartość liczby pi.`
  `Pred` | ``function Pred(X: TOrdinal): TOrdinal;` Poprzednik elementu X.`
  `Random` | ``function Random: Real; assembler;` Funkcja zwraca losową wartość z przedziału <0 .. 1> `function Random(range: byte): byte; assembler;` Funkcja zwraca losową wartość z przedziału <0 .. range-1>, w przypadku Range=0 zwraca wartość losową z przedziału <0 .. 255 > `function Random(range: smallint): smallint;` Funkcja zwraca losową wartość z przedziału <0 .. range-1>`
  `ReadConfig` | ``function ReadConfig(devnum: byte): cardinal;` Odczyt statusu stacji DEVNUM. Wynikiem są cztery bajty DVSTAT ($02EA..$02ED).
      Byte 0 ($02ea):
      Bit 0:Indicates the last command frame had an error.
      Bit 1:Checksum, indicates that there was a checksum error in the last command or data frame
      Bit 2:Indicates that the last operation by the drive was in error.
      Bit 3:Indicates a write protected diskette. 1=Write protect
      Bit 4:Indicates the drive motor is on. 1=motor on
      Bit 5:A one indicates MFM format (double density)
      Bit 6:Not used
      Bit 7:Indicates Density and a Half if 1

      Byte 1 ($02eb):
      Bit 0:FDC Busy should always be a 1
      Bit 1:FDC Data Request should always be 1
      Bit 2:FDC Lost data should always be 1
      Bit 3:FDC CRC error, a 0 indicates the last sector read had a CRC error
      Bit 4:FDC Record not found, a 0 indicates last sector not found
      Bit 5:FDC record type, a 0 indicates deleted data mark
      Bit 6:FDC write protect, indicates write protected disk
      Bit 7:FDC door is open, 0 indicates door is open

      Byte 2 ($2ec):
      Timeout value for doing a format.

      Byte 3 ($2ed):
      not used, should be zero
  `
  `ReadSector` | ``procedure ReadSector(devnum: byte; sector: word; var buf);` Odczyt sektora SECTOR dyskietki w stacji dysków DEVNUM i zapisanie go w buforze BUF.`
  `Rect` | ``function Rect(ALeft, ATop, ARight, ABottom: smallint): TRect;` Na podstawie parametrów tworzony jest rekord typu TRect.`
  `RenameFile` | ``function RenameFile(OldName, NewName: string): Boolean;`` Funkcja pozwala zmienić nazwę pliku OldName na nową nazwę NewName, zwraca TRUE kiedy operacja powiodła się, FALSE w przypadku wystąpienia błędu (najczęściej z powodu zabezpieczenia przed zapisem lub błędnej nazwy pliku).
      RenameFile('D:OLDNAME.TMP', 'NEWNAME.TMP');
  `Reset` | ``procedure Reset(var f: file; l: Word);`` Otwiera istniejący plik z nazwą przekazaną do F poleceniem Assign. Opcjonalnie możemy podać rozmiar rekordu w bajtach L, domyślnie jest to wartość 128.
  `Rewrite` | ``procedure Rewrite(var f: file; l: Word);`` Tworzy i otwiera nowy plik. F jest nazwą przekazaną za pomocą polecenia Assign. Opcjonalnie możemy podać rozmiar rekordu w bajtach L, domyślnie jest to wartość 128.
  `Round` | ``function Round(x: real): integer;` Funkcja Round dokonuje zaokrąglenia podanej liczby rzeczywistej do najbliższej liczby całkowitej.`
  `Seek` | ``procedure Seek(var f: file; N: cardinal);` Ustawia pozycję w pliku na N. N powinno być wartością zwróconą przez FilePos. Jest to odpowiednik instrukcji POINT.`
  `SetLength` | ``procedure SetLength(var S: string; Len: byte);` Ustawia długość ciągu S na LEN.`
  `SetIntVec` | ``procedure SetIntVec(intno: Byte; vector: pointer);` Procedura ustawia adres wektora przerwań wg. kodu INTNO. Obecnie dopuszczalnymi kodami są:
      iDLI - przerwanie DLI
      iVBL - przerwanie VBL
  `
  `Sin` | ``function Sin(x: real): real;`` Sinus kąta (x w radianach).
  `Succ` | ``function Succ(X: TOrdinal): TOrdinal;` Następnik elementu X.`
  `Space` | ``function Space(Len: Byte): ^char;` Funkcja generuje nowy ciąg znakowy o długości LEN wypełniony znakami spacji.`
  `SizeOf` | ``function SizeOf(X: AnyType): byte;` Funkcja zwraca rozmiar podanej zmiennej (lub typu) w bajtach.`
  `Str` | ``procedure Str(var X: TNumericType; var S: string);` Instrukcja zamienia liczbę X na łańcuch znaków S.`
  `StringOfChar` | ``procedure StringOfChar(ch: Char; len: byte): ^char;` Funkcja generuje nowy ciąg znakowy o długości LEN wypełniony znakami CH.`
  `Sqr` | ``function Sqr(x: real): real; function Sqr(x: integer): integer;` Funkcja obliczająca kwadrat podanej liczby (ang. Square).`
  `Sqrt` | ``function Sqrt(x: real): real; function Sqrt(x: single): single; function Sqrt(x: integer): single;` Funkcja obliczająca pierwiastek kwadratowy podanej liczby (ang. Square root).`
  `Trunc` | ``function Trunc(x: real): integer;` Funkcja zwraca część całkowitą liczby rzeczywistej w postaci liczby całkowitej.`
  `UpCase` | ``function UpCase(a: char): char;` Funkcja zmieniająca znaki 'a'..'z' na odpowiednie duże znaki 'A'..'Z'`
  `Val` | ``procedure Val(const S: string; var V; var Code: Byte);` Procedura przekształca ciąg znaków S na liczbę V. Code przyjmie wartość 0 jeśli nie było błędnych znaków, w przeciwnym wypadku przyjmie numer znaku który spowodował błąd konwersji.`
  `WriteSector` | ``procedure WriteSector(devnum: byte; sector: word; var buf);` Zapis sektora SECTOR dyskietki w stacji DEVNUM na podstawie bufora BUF.`

  `

  ## CRT

  ` Reference for unit 'Crt': Procedures and functions

  [ Constants ]

      CN_START_SELECT_OPTION	= 0;
      CN_SELECT_OPTION	= 1;
      CN_START_OPTION		= 2;
      CN_OPTION		= 3;
      CN_START_SELECT		= 4;
      CN_SELECT		= 5;
      CN_START		= 6;
      CN_NONE			= 7;

  [ Variables ]

  `Consol` | ``Consol: byte absolute $d01f;` Zmienna 'Consol' zwraca kod naciśniętego klawisza/klawiszy konsoli.`
  `TextAttr` | ``TextAttr: byte = 0;` Zmienna 'TextAttr' przechowuje wartość jaka jest dodawana do każdego wyświetlanego znaku, np. TextAttr = $80 spowoduje że znaki będą wyświetlane w inwersie.`
  `WhereX` | ``WhereX: byte absolute $54;` Zmienna 'WhereX' przechowuje aktualną poziomą pozycję kursora.`
  `WhereY` | ``WhereY: byte absolute $55;` Zmienna 'WhereY' przechowuje aktualną pionową pozycję kursora.`

  [ Procedures and functions ]

  `ClrEol` | ``procedure ClrEol;` Procedura czyści wiersz od aktualnej pozycji kursora do prawej strony krawędzi ekranu. Pozycja kursora nie ulega zmianie.`
  `ClrScr` | ``procedure ClrScr;` Procedura czyści ekran edytora, wykonuje kod znaku CH_CLR`
  `CursorOff` | ``procedure CursorOff;` Procedura wyłącza kursor.`
  `CursorOn` | ``procedure CursorOn;` Procedura włącza kursor.`
  `Delay` | ``procedure Delay(MS: Word);` Procedura czeka zadaną ilość milisekund MS. W przybliżeniu Delay(1000) generuje opóźnienie jednej sekundy.`
  `DelLine` | ``procedure DelLine;` Procedura kasuje wiersz na aktualnej pozycji kursora, wykonuje kod znaku CH_DELLINE`
  `GotoXY` | ``procedure GotoXY(x, y: byte);` Procedura ustawia nową pozycję kursora.`
  `InsLine` | ``procedure InsLine;` Procedura wstawia pusty wiersz na aktualnej pozycji kursora, wykonuje kod znaku CH_INSLINE`
  `Keypressed` | ``function Keypressed: Boolean;` Funkcja zwraca TRUE gdy został naciśnięty jakiś klawisz klawiatury, w przeciwnym razie zwraca FALSE.`
  `NoSound` | ``procedure NoSound;` Procedura wycisza kanały obu POKEY-i ($D200, $D210)`
  `ReadKey` | ``function ReadKey: char;` Funkcja zwraca kod naciśniętego klawisza klawiatury.`
  `Sound` | ``procedure Sound(Chan,Freq,Dist,Vol: byte);` Procedura odtwarza dźwięk na kanale POKEY-a CHAN (0..3, 4..7), o częstotliwości FREQ (0..255), filtrach DIST (0..7), głośności VOL (0..15).`
  `TextBackground` | ``procedure TextBackground(a: byte);` Procedura ustawia nowy kolor tła znaków (działa najlepiej z włączonym VBXE).`
  `TextColor` | ``procedure TextColor(a: byte);` Procedura ustawia nowy kolor znaków (działa najlepiej z włączonym VBXE).`

  `

  ## GRAPH

  ` Reference for unit 'Graph': Procedures and functions

  [ Constants ]

      	{ graphic drivers }
      	D1bit	= 11;
      	D2bit	= 12;
      	D4bit	= 13;
      	D6bit	= 14;		// 64 colors Half-brite mode - Amiga
      	D8bit	= 15;
      	D12bit	= 16;		// 4096 color modes HAM mode - Amiga

      	m640x480 = 8 + 16;

      	{ error codes }
      	grOK		= 0;
      	grNoInitGraph	= -1;
      	grNotDetected	= -2;
      	grFileNotFound	= -3;
      	grInvalidDriver	= -4;
      	grNoLoadMem	= -5;
      	grNoScanMem	= -6;
      	grNoFloodMem	= -7;
      	grFontNotFound	= -8;
      	grNoFontMem	= -9;
      	grInvalidMode	= -10;
      	grError		= -11;
      	grIOerror	= -12;
      	grInvalidFont	= -13;
      	grInvalidFontNum= -14;
      	grInvalidVersion= -18;

  [ Variables ]

  `GraphResult` | ``GraphResult : byte;``

  [ Procedures and functions ]

  `Bar` | ``procedure Bar(x1, y1, x2, y2: Smallint);` Prostokąt, np. dla wykresów słupkowych.`
  `Bar3D` | ``procedure Bar3D(x1, y1, x2, y2: smallint; depth: word; top: boolean);` Słupek trójwymiarowy.`
  `Circle` | ``procedure Circle(x0,y0,radius: word);` Okrąg.`
  `ClipLine` | ``procedure ClipLine(x1, y1, x2, y2: smallint);``
  `Ellipse` | ``procedure Ellipse(x0, y0, a, b: word);` Elipsa.`
  `FillEllipse` | ``procedure FillEllipse(x0, y0, a, b: word);` Elipsa wypełniona wewnątrz.`
  `FillRect` | ``procedure FillRect(Rect: TRect);` Prostokąt wypełniony wewnątrz.`
  `FloodFill` | ``procedure FloodFill(x, y: smallint; color: byte);` Wypełnienie zamkniętego obszaru ekranu.`
  `GetColor` | ``function GetColor: byte; assembler;` Podaj bieżący kolor rysowania.`
  `GetMaxX` | ``function GetMaxX: word;` Podaj najwyższą wartość współrzędnej X na ekranie.`
  `GetMaxY` | ``function GetMaxY: word;` Podaj najwyższą wartość współrzędnej Y na ekranie.`
  `GetPixel` | ``function GetPixel(x,y: smallint): byte;` Podaj kolor danego punktu na ekranie.`
  `GetX` | ``function GetX: smallint;` Podaj bieżącą współrzędną X kursora graficznego.`
  `GetY` | ``function GetY: smallint;` Podaj bieżącą współrzędną Y kursora graficznego.`
  `InitGraph` | ``procedure InitGraph(mode: byte); procedure InitGraph(driver, mode: byte; pth: TString);` Zainicjuj tryb graficzny.`
  `Line` | ``procedure Line(x0, y0, x1, y1: smallint);` Linia prosta.`
  `LineTo` | ``procedure LineTo(x, y: smallint);` Linia od bieżącej pozycji kursora do wskazanego punktu.`
  `MoveRel` | ``procedure MoveRel(Dx, Dy: smallint);` Przesuń kursor graficzny.`
  `MoveTo` | ``procedure MoveTo(x, y: smallint);` Przesuń kursor graficzny do wskazanego punktu.`
  `PutPixel` | ``procedure PutPixel(x,y: smallint); procedure PutPixel(x,y: smallint; color: byte);` Zapal punkt na ekranie.`
  `Rectangle` | ``procedure Rectangle(x1, y1, x2, y2: smallint); procedure Rectangle(Rect: TRect);` Prostokąt.`
  `SetBkColor` | ``procedure SetBkColor(color: byte);` Ustaw kolor tła.`
  `SetClipRect` | ``procedure SetClipRect(x0,y0,x1,y1: smallint); procedure SetClipRect(Rect: TRect);``
  `SetColor` | ``procedure SetColor(color: byte);` Ustaw kolor pisaka.`
  `SetColorMapEntry` | ``procedure SetColorMapEntry; procedure SetColorMapEntry(a,b,c: byte);``
  `SetColorMapDimensions` | ``procedure SetColorMapDimensions(w,h: byte);``

  `

  ## SYSUTILS

  ` Reference for unit 'Sysutils': Procedures and functions

  [ Constants ]

      faReadOnly	= $01;
      faHidden	= $02;
      faSysFile	= $04;
      faVolumeID	= $08;
      faDirectory	= $10;
      faArchive	= $20;
      faAnyFile	= $3f;

  [ Types ]

  `TSearchRec` | `
      TSearchRec = record
      		Attr: Byte;
      		Name: TString;
      		FindHandle: Pointer;
      	     end;
  `

  [ Procedures and functions ]

  `AnsiUpperCase` | ``function AnsiUpperCase(const a: string): string;` Funkcja konwertuje znaki z łańcucha A na wielkie.`
  `Beep` | ``procedure Beep;` Sygnał brzęczka (buzzer).`
  `Click` | ``procedure Click;` Sygnał klawiatury.`
  `DeleteFile` | ``function DeleteFile(var FileName: TString): Boolean;` Funkcja kasuje plik określony w parametrze FileName, zwraca TRUE gdy operacja się powiodła.`
  `ExtractFileExt` | ``function ExtractFileExt(const FileName: string): TString;` Na podstawie nazwy pliku lub pełnej ścieżki do pliku (określonej w parametrze FileName), funkcja zwraca rozszerzenie (poprzedzone kropką - np. .txt).`
  `FileExists` | ``function FileExists(const FileName: string): Boolean;` Funkcja sprawdza czy plik określony w parametrze FileName, istnieje (True) czy też nie (False).`
  `FindFirst` | ``function FindFirst(const FileMask: TString; Attributes: Byte; var SearchResult: TSearchRec): byte;` Funkcja FindFirst wyszukuje pliki pasujące do wzorca FileMask i posiadające atrybuty określone w Attributes. Jeśli zostały znalezione pliki pasujące do szablonu to pierwszy z nich jest zwracany w zmiennej SerchResult.`
  `FindNext` | ``function FindNext(var f: TSearchRec): byte;` Funkcja przechodzi do następnego rekordu znalezionego wcześniej przy pomocy FindFirst. W parametrze musi zostać przekazane wskazanie na rekord, który wcześniej został użyty w funkcji FindFirst.`
  `FindClose` | ``procedure FindClose(var f: TSearchRec);` Procedura zwalnia zasoby (pamięć) zaalokowaną przez funkcję FindFirst. Procedura ta powinna być wywoływana za każdym razem po zakończeniu procesu wyszukiwania.`
  `GetTickCount` | ``function GetTickCount: cardinal;` GetTickCount zwraca 24-bitowy licznik czasu (PEEK(RTCLOK+2) + PEEK(RTCLOK+1)*256 + PEEK(RTCLOK)*65536). Jest to przydatne do pomiaru czasu.`
  `IntToHex` | ``function IntToHex(Value: cardinal; Digits: byte): TString;` Funkcja konwertuje wartość liczbową na jej odpowiednik łańcuchowy w systemie szesnastkowym.`
  `IntToStr` | ``function IntToStr(a: integer): ^char;` Funkcja służy do konwersji liczby całkowitej podanej w parametrze do postaci łańcuchowej.`
  `RenameFile` | ``function RenameFile(var OldName,NewName: TString): Boolean;` RenameFile próbuje zmienić nazwę pliku (określonego w parametrze OldName) na NewName. Jeżeli operacja się powiedzie, funkcja zwróci wartość True; w przeciwnym wypadku - False. Może się zdarzyć, że funkcja nie będzie mogła zmienić nazwy (np. gdy aplikacja nie ma prawa do tego) - wówczas funkcja zwróci False.`
  `StrToFloat` | ``function StrToFloat(var s: TString): real;` Funkcja konwertuje łańcuch do postaci zmiennoprzenkowej typu Real.`
  `StrToInt` | ``function StrToInt(const S: char): byte; function StrToInt (const S: TString): integer;` Funkcja służy do konwersji tekstu zapisanego w zmiennej S na liczbę całkowitą - o ile to możliwe.`

  `

  ## VBXE

  `

  Mapa pamięci dla VBXE zdefiniowana jest w module SYSTEM

      VBXE_XDLADR = $0000;	// XDLIST
      VBXE_MAPADR = $1000;	// COLOR MAP ADDRESS
      VBXE_BCBADR = $0100;	// BLITTER LIST ADDRESS
      VBXE_OVRADR = $5000;	// OVERLAY ADDRESS
      VBXE_WINDOW = $B000;	// 4K WINDOW $B000..$BFFF

  [ Constants ]

      LoRes  = 1;
      MedRes = 2;
      HiRes  = 3;

  [ Types ]

  `TUInt24` | `
      record
      	byte0: byte;
      	byte1: byte;
      	byte2: byte;
      end;
  ` | `Typ 24-bitowy wykorzystywany do definicji adresów pamięci VBXE.`
  `TXDL` | `
      record
      	xdlc_: word;
      	rptl_: byte;
      	xdlc: word;
      	rptl: byte;
      	ov_adr: TUInt24;
      	ov_step: word;
      	mp_adr: TUInt24;
      	mp_step: word;
      	mp_hscrol: byte;
      	mp_vscrol: byte;
      	mp_width: byte;
      	mp_height: byte;
      	ov_width: byte;
      	ov_prior: byte;
      end;
  ` | `Typ TXDL wykorzystywany przez procedury GetXDL i SetXDL. Pozwala na modyfikację programu dla VBXE wykorzystywanego przez MadPascal.`
  `TBCB` | `
      record
      	src_adr: TUInt24;
      	src_step_y: smallint;
      	src_step_x: shortint;
      	dst_adr: TUInt24;
      	dst_step_y: smallint;
      	dst_step_x: shortint;
      	blt_width: word;
      	blt_height: byte;
      	blt_and_mask: byte;
      	blt_xor_mask: byte;
      	blt_collision_mask: byte;
      	blt_zoom: byte;
      	pattern_feature: byte;
      	blt_control: byte;
      end;
  ` | `Typ TBCB (21 bajtów), Blitter Code Block. Definicja typu bloku programu dla Blittera VBXE.`
  `TVBXEMemoryStream` | `
      Object
      	Position: cardinal;
      	Size: cardinal;			// 0..Size-1

      	procedure Create;

      	procedure Clear;
      	procedure SetBank;

      	procedure ReadBuffer(var Buffer; Count: word);
      	procedure WriteBuffer(var Buffer; Count: word);

      	function ReadByte: Byte;
      	function ReadWord: Word;
      	function ReadDWord: Cardinal;

      	procedure WriteByte(b: Byte);
      	procedure WriteWord(w: Word);
      	procedure WriteDWord(d: Cardinal);
      end;
  ` | `Obiekt TVBXEMemoryStream pozwala na liniowy dostęp do pamięci VBXE.`

  [ Procedures and functions ]

  ``BlitterBusy` | `function BlitterBusy: Boolean; assembler; Funkcja zwraca TRUE jeśli blitter VBXE zajęty jest wykonywaniem programu blittera.``
  `ColorMapOff` | `procedure ColorMapOff; assembler; Wyłączenie mapy kolorów w programie XDLIST dla VBXE.`
  `ColorMapOn` | `procedure ColorMapOn; assembler; Włączenie mapy kolorów w programie XDLIST dla VBXE.`
  `DstBCB` | ``procedure DstBCB(var a: TBCB; dst: cardinal);` Procedura zmieniająca adres docelowy (dst_adr) w programie blittera A.`
  `GetXDL` | ``procedure GetXDL(var a: txdl); register; assembler;` Procedura przepisuje do zmiennej A program XDLIST spod adresu VBXE_XDLADR w pamięci VBXE.`
  `IniBCB` | ``procedure IniBCB(var a: TBCB; src,dst: cardinal; w0, w1: smallint; w: word; h: byte; ctrl: byte);` Procedura INIBCB pozwala zaincjować pamięć dla programu blittera pod adresem A. Dodatkowe parametry określają adres spod którego będą kopiowane dane SRC, adres docelowy kopiowanych danych DST, szerokość okna danych źródłowych W0, docelowych W1, rozmiar okna wynikowego, jego szerokość W, wysokość H, oraz określić parametry końcowe bloku programu blittera CTRL (ustawiony bit 3 CTRL nakazuje blitterowi odczyt kolejnego programu i jego wykonanie).`
  `OverlayOff` | `procedure OverlayOff; assembler; Wyłączenie trybu overlay w programie XDLIST.`
  `RunBCB` | ``procedure RunBCB(var a: TBCB); assembler;` Wystartowanie blittera VBXE na podstawie adresu programu A.`
  `SetHorizontalRes` | ``procedure SetHorizontalRes(a: byte); assembler;` `procedure SetHRes(a: byte); assembler;` Ustanowienie trybu overlay w programie XDLIST (LoRes: 160x240x256c, MedRes: 320x240x256c, HiRes: 640x240x16c).`
  `VBXEMemoryBank` | ``procedure VBXEMemoryBank(b: byte); assembler;` Włączenie 4K banku VBXE w okno pamięci XE/XL $B000..$BCFF`
  `SetXDL` | ``procedure SetXDL(var a: txdl); register; assembler;` Procedura przepisuje program A pod adres VBXE_XDLADR w pamięci VBXE.`
  `SrcBCB` | ``procedure SrcBCB(var a: TBCB; src: cardinal);` Procedura zmieniająca adres źródłowy (src_adr) w programie blittera A.`
  `VBXEControl` | ``procedure VBXEControl(a: byte); assembler;` Procedura ustawia wartośc FX_VIDEO_CONTROL.`
  `VBXEOff` | ``procedure VBXEOff` Wyłączenie, reset VBXE.`

  `

  ## MATH

  ` Reference for unit 'Math': Procedures and functions

  [ Procedures and functions ]

  `ArcCos` | ``function ArcCos(x: real): real;` Arcus cosinus jest funkcją odwrotną do funkcji Cos (cosinus). Wartość parametru X musi należeć do przedziału obustronnie domkniętego <-1; 1>. Wartością zwracaną przez funkcję jest kąt z przedziału <0; ?> wyrażony w mierze łukowej (radianach).`
  `ArcSin` | ``function ArcSin(x: real): real;` Funkcja ArcSin służy do obliczenia funkcji matematycznej arcus sinus z liczby X. Jest to funkcja odwrotna do funkcji sinus, tzn. sin(arcsin(x)) = x.`
  `ArcTan2` | ``function ArcTan2(y, x: real) : real;` Funkcja oblicza arcus tangens (odwrotność tangensa) z liczby Y/X i zwraca wartość w radianach.`
  `Ceil` | ``function Ceil(a: real): smallint;` Funkcja zwraca najmniejszą liczbę całkowitą większą lub równą od tej podanej w parametrze.`
  `CycleToRad` | ``function CycleToRad(cycle : real) : real;` Funkcja CycleToRad przelicza wartość kąta wyrażonego w cyklach (obrotach) na kąt wyrażony w radianach.`
  `DegNormalize` | ``function DegNormalize(deg : real) : real;``
  `DegToGrad` | ``function DegToGrad(deg : real) : real;` Funkcja DegToGrad przelicza wartość kąta wyrażonego w stopniach na kąt wyrażony w gradach.`
  `DegToRad` | ``function DegToRad(deg : real) : real;` Funkcja DegToRad przelicza wartość kąta wyrażonego w stopniach na kąt wyrażony w mierze łukowej, czyli radianach.`
  `DivMod` | ``procedure DivMod(Dividend: integer; Divisor: Word; var r, Remainder: Word); procedure DivMod(Dividend: integer; Divisor: Word; var r, Remainder: smallint);``
  `EnsureRange` | ``function EnsureRange(const AValue, AMin, AMax: byte): Integer; function EnsureRange(const AValue, AMin, AMax: Integer): Integer;``
  `Floor` | ``function Floor(a: real): smallint;` Funkcja zwraca najbliższą liczbę całkowitą mniejszą lub równą od tej podanej w parametrze.`
  `FMod` | ``function FMod(a, b: real): real;` Funkcja FMod zwraca resztę z dzielenia dwóch liczb rzeczywistych.`
  `GradToDeg` | ``function GradToDeg(grad : real) : real;` Funkcja GradToDeg przelicza wartość kąta wyrażonego w gradach na kąt wyrażony w stopniach.`
  `GradToRad` | ``function GradToRad(grad : real) : real;` Funkcja GradToRad przelicza wartość kąta wyrażonego w gradach na kąt wyrażony w radianach.`
  `InRange` | ``function InRange(const AValue, AMin, AMax: byte): Boolean; function InRange(const AValue, AMin, AMax: Integer): Boolean;``
  `IsNan` | ``function IsNan(const d : Single): Boolean;` Funkcja sprawdza czy wartość parametru D jest poprawną liczbą.`
  `Log2` | ``function log2(x : single): single;` Funkcja zwraca wartość logarytmu przy podstawie 2 dla parametru rzeczywistego X>0.`
  `Log10` | ``function log10(x : single): single;` Funkcja zwraca wartość logarytmu dziesiętnego (logarytmu przy podstawie 10) dla parametru rzeczywistego X>0.`
  `LogN` | ``function logN(n,x : single): single;` Funkcja zwraca wartość logarytmu przy podstawie N>0 dla parametru rzeczywistego X>0.`
  `Max` | ``function Max(a, b: real): real; function Max(a, b: integer): integer;` Przeciążona funkcja porównuje wartości dwóch parametrów: A i B, oraz zwraca ten, który jest większy.`
  `Min` | ``function Min(a, b: real): real; function Min(a, b: integer): integer;` Przeciążona funkcja porównuje wartości dwóch parametrów A i B, oraz zwraca wartość tego który jest mniejszy.`
  `Power` | ``function Power(base : real; const exponent : shortint): real; power(base : integer; const exponent : shortint): integer;` Funkcja podnosi liczbę A do dowolnej potęgi N, potęga może być ułamkiem.`
  `RadToCycle` | ``function RadToCycle(rad : real) : real;` Funkcja RadToCycle przelicza wartość kąta wyrażonego w radianach na kąt wyrażony w cyklach (obrotach).`
  `RadToDeg` | ``function RadToDeg(rad : real) : real;` Funkcja RadToDeg przelicza wartość kąta wyrażonego w radianach na kąt wyrażony w stopniach (deg).`
  `RadToGrad` | ``function RadToGrad(rad : real) : real;` Funkcja RadToGrad przelicza wartość kąta wyrażonego w radianach na kąt wyrażony w gradach.`
  `RandG` | ``function RandG(mean, stddev : single) : single;` RandG reprezentuje generator liczb pseudolosowych o rozkładzie Gaussa wokół średniej Mean. Parametr StdDev jest odchyleniem standardowym generowanych liczb od wartości średniej (Mean).`
  `RandomRange` | ``function RandomRange(const aFrom, aTo: smallint): smallint;` Funkcja zwraca losową liczbę z przedziału AFrom - ATo (łącznie z wartością ATo).`
  `RandomRangeF` | ``function RandomRangeF(const min, max: single): single;``
  `Tan` | ``function Tan(x: Real): Real;` Funkcja zwraca wartość tangensa kąta podanego w parametrze X.`

`

## HISTORIA

1.5.6 - 1.5.7

- SYSUTILS: Click
- SYSTEM: Sqrt(Integer): Single
- MATH: Sign
- dodana możliwość użycia nazwy funkcji dla zwracanej wartości, dotychczas tylko przez RESULT
- dodana obsługa tablic typu STRING
- dodana obsługa dyrektywy {$LIBRARYPATH path1;path2;...}
- nowa biblioteka BLIBS
- nowa dokumentacja dla LIB, BLIBS wygenerowana przez PASDOC (https://gitlab.com/bocianu/pasdoc)

1.5.3 - 1.5.5

- CRT: TextMode
- SYSUTILS: ExtractFilePath
- SYSTEM: EoLn
- dodana obsługa linii poleceń z poziomu DOS II/D dla ParamCount, ParamStr
- OBJECT, można zdefiniować je bez zmiennych, tylko same metody
- OBJECT, można wywołać metodę z poziomu metody
- dodana automatyczna konwersja wyrażeń typu INTEGER na REAL

1.5.2

- nowy typ FLOAT jako odpowiednik typu SINGLE
- SYSTEM unti: FileSize (SDX)
- SYSTEM unit: EXP:Single, LN:Single, LN:Real, EXP:Real (wysoka precyzja obliczeń)
- SYSUTILS unit: AnsiUpperCase, ExtractFileExt
- TYPES unit: Bounds, CenterPoint, EqualRect, InflateRect, IntersectRect, IsRectEmpty, NormalizeRect, OffsetRect, Point, PointsEqual, PtInRect, PtInEllipse, Rect, RectWidth, RectHeight, Size, UnionRect
- IMAGE unit: LoadMIC, LoadPIC, LoadBMP, LoadPCX, LoadGIF
- VIMAGE unit: LoadVBMP, LoadVPCX, LoadVGIF
- GRAPH, FASTGRAPH unit: SetClipRect, ClipLine, FillRect(TRect), Rectangle(TRect)

1.5.1

- dodane nowe przełączniki -CODE:$address, -DATA:$address -STACK:$address, -ZPAGE:$address
- SYSTEM unit: RandomF (Result as Single), VAL (Integer, Single)
- GRAPH, FASTGRAPH unit: Bar, Bar3D, GetX, GetY, MoveRel, FloodFill
- MATH unit: RandomRange, RandomRangeF, RandG (gaussian distributed random number)
- CRT unit: SOUND (działa identycznie jak SOUND w Atari BASIC)
- VBXE unit: TVBXEMemoryStream
- dodany komunikat ostrzeżenia 'Comparison might be always true/false due to range of constant and expression'
- zasoby RCASM, CMCPLAY, MPTPLAY można teraz ładować pod ROM
- dodana możliwość oznaczenia kodowania ciągu znakowego jako internal ANTIC-a poprzez znak tyldy '~', np.:

     txt0: string = 'Atari'~;      // ciąg w kodach ANTIC-a
     txt1: string = 'Spectrum'*~;  // ciąg w inwersie w kodach ANTIC-a

1.5.0

- poprawiona i uzupełniona inicjalizacja tablic typu POINTER
- poprawiona i uzupełniona inicjalizacja zmiennych typu wyliczeniowego
- wprowadzony typ LONGWORD, DWORD, UINT32 jako odpowiednik CARDINAL
- wprowadzony typ LONGINT jako odpowiednik INTEGER
- zreorganizowane typy rzeczywiste, typ ShortReal (fixed point Q8.8), Real (fixed point Q24.8), Single (32bit IEEE-754)
- unit SYSTEM (const SINGLE): NaN, Infinity, NegInfinity
- unit SYSTEM (type SINGLE): SIN, COS, ABS, SQRT, ISQRT, ROUND, TRUNC
- unit MATH (type SINGLE): LOG2, LOG10, LOGN, IsNaN
- dla WRITE/WRITELN akceptowane i ingorowane jest formatowanie wyniku, np.: writeln(f:8:8)

1.4.8 / 1.4.9

- zmniejszenie wskaźnika stosu programowego w przypadku wywołania funkcji bez odebrania jej wartości
- lepsza ocena możliwości ustalenia adresu stałej/zmiennej, dodany komunikat "Can't take the address of constant expressions"

1.4.7

- optymalizacja dla imulBYTE, imulWORD, imulCARD, mulSHORTINT, mulSMALLINT, mulINTEGER
- dodana obsługa wskaźnika rekordu, np.:

    type
    	TPoint = record x,y: smallint end;
    var
    	a,b: ^TPoint;
    begin
    	a^.y := b^.x;
    	a^ := b^;
    end.

- dodana obsługa sekcji INITIALIZATION w modułach UNIT
- dodany nowy typ EXTMEM dla pliku resource $R, pozwalajacy ładować dane do pamięci dodatkowej
- dodany nowy typ OBJECT, czyli RECORD z dodatkowymi metodami

    type
    	TMemoryStream = Object

    	Position: cardinal;
    	Size: cardinal;

    	procedure Create;
    	procedure ReadBuffer(var Buffer; Count: word);
    	procedure WriteBuffer(var Buffer; Count: word);

    	end;

- poprawione biblioteki CMC, MPT, RMT

1.4.6

- dodana obsługa dyrektyw warunkowych $IFDEF, $IFNDEF, $ELSE, $ENDIF, $DEFINE, $UNDEF przez DMSC

    {$define test}

    const
    	{$ifdef test}
    	a=1;
    	{$else}
    	a=2;
    	{$endif}

- dodana możliwość przekazania wartości funkcji przez EXIT(expression)
- dodana podstawowa implementacja dla typu wyliczeniowego (w pliku wynikowym nie są zapisywane nazwy etykiet)
- dodana obsługa tablic dwuwymiarowych

1.4.4/1.4.5

- poprawione porównanie typów tego samego rozmiaru ale o przeciwnych znakach
- dodana możliwość użycia klauzuli USES w blokach modułów UNIT
- dodany wymóg deklaracji funkcji/procedur w sekcji INTERFACE modułów UNIT
- poprawione zauważone błędy optymalizatora

1.4.3

- dodana możliwość zwrócenia wartości funkcji przez RECORD, np:

      var p: TPoint;

      p:=Point(x,y);

- {$f page} FAST_MUL, procedury szybkiego mnożenia dla BYTE, SHORTINT, WORD, SMALLINT, SINGLE
- SYSTEM: ReadConfig, ReadSector, WriteSector
- SYSTEM: Point, Rect, Bounds, PointsEqual
(https://github.com/graemeg/freepascal/blob/577d99e594f4958bad4f343fb419b8dddda2ebe6/rtl/objpas/classes/classes.inc)
- DOS: CurrentMinuteOfDay, CurrentSec100OfDay, CurrentSecondOfDay, MinuteOfDay, MinutesToTime, SecondOfDay, SecondsToTime
(https://github.com/graemeg/freepascal/blob/master/packages/fv/src/time.pas#L309)
- MATH: Power, ArcTan2, InRange, EnsureRange, CycleToRad, DegNormalize, DegToGrad, DegToRad, DivMod, GradToDeg, GradToRad, RadToCycle, RadToDeg, RadToGrad
(https://github.com/graemeg/freepascal/blob/master/rtl/objpas/math.pp)
- nowy typ LABEL
- dodana obsługa GOTO label

1.4.1 / 1.4.2

- optymalizacja kodu wynikowego 6502 generowanego dla pętli FOR
- poprawiony odczyt plików include i resource
- MISC: DetectCPUSpeed
- dodatkowy typ danych rzeczywistych SINGLE <-128..127>

1.4.0

- w parametrach formalnych procedur i funkcji dodana możliwość podania typu UNTYPED (tylko przez VAR), np.

     procedure move(var x,y; count: word);
     begin
     end;

     move(tab[100], tab[200], 50);

- SYSTEM: poprawki dla FILLCHAR, FILLBYTE, MOVE

     fillchar(pointer($bc40+40*8), 100, ord('a'));
     fillchar(scr[40*8], 100, ord('a'));            // teraz takie wywołanie też jest możliwe

- funkcja INTTOREAL usunięta, zastąpiona przez wbudowaną konwersję typu REAL, np.

     var f: real;
         i: word;

     f:=real(i);

- FASTGRAPH: SetClipRect, ClipLine (Cohen-Sutherland algorithm)
- poprawki dla {$i filename}, poprawne liczenie linii kompilowanego programu

1.3.8

- SYSTEM: RANDOM(RANGE: BYTE): BYTE; RANDOM(RANGE: INTEGER): SMALLINT;
- CRT: WHEREX, WHEREY
- SYSUTILS: BEEP
- dodatkowy znak * po apostrofie '' oznacza inwers znaków, np.:

     writeln('inwers'*'bez inwersu');

1.3.7

- dodana możliwość ładowania bloku resource {$R} pod adres tablicy

1.3.6

- dodane rozkazy GetIntVec, SetIntVec w zastępstwie rozkazu Intr
- umożliwione zwracanie wartości RESULT dla funkcji poprzez tablice
- poprawki dla MOVE (downwards, upwards)
- optymalizacja ASM dla procedur/funkcji POKE, DPOKE, PEEK, DPEEK, FILLCHAR, MOVE, INTTOREAL
- SYSTEM: ParamCount, ParamStr (SDX, BWDOS)

1.3.5

- dodana możliwość odczytu adresu stałej, np.:

      const tb: array [0..0] of byte = ( lo(word(@tb)) );

- dodany odczyt wektorów DLI, VBL przez rozkaz INTR

      intr(rVBL, label);
      intr(rDLI, label);

1.3.4

- dodana dodatkowa informacja o zajmowanej pamięci przez kolejne kompilowane moduły
- dodany nowy moduł VBXE (tryb OVERLAY, BLITTER)
- dodana obsługa błędów dla operacji I/O {I+} {I-} IOCHECK ON/OFF
- dwie dodatkowe poprawki Greblusa dla $I, $R z myślą o działaniu w środowisku Linuxa

1.3.3

- Greblus dodał poprawki umożliwiające działanie kompilatora z Linux-em
- dodana możliwość zaincjowania wskaźnika

    	tmp: byte;
    	p: pointer = @tmp;
    	a: ^byte = @tmp;

- dodana możliwość przypisania rekordu

    type a = record x,y: byte end;
    var k,w: a;

    	k:=w;

- GRAPH: SetVideoBank, SetColorMapDimensions, SetColorMapEntry
- VBXE: GetXDL, SetXDL, RunBlit, ClrVideoBank

1.3.2

- DOS: GetTime, SetTime
- MATH: Ceil
- SYSUTILS: GetTickCount
- FindFirst ... obsługa Attributes
- wbudowanie funkcji w kompilator: INT, FRAC, TRUNC, ROUND, ODD

1.3.1

- dodana obsługa rekordów RECORD
- {$i filename}
- {$r filename}, Resource Type: RCDATA, DOSFILE, RELOC, RMT, MPT, CMC
- dodany przełącznik -o Optimize code
- możliwość wymuszenia typu dla CONST

      const
          a: word = 5;     // WORD
          b = 5;           // BYTE

- dodana obsługa modyfikatorów INTERRUPT, FORWARD, REGISTER dla procedur i funkcji
- dodana obsługa mapy kolorów (40x30x8x8) VBXE (moduł GRAPH, CRT), SetColorMap, SetColorCell, SetVideoBank
- SYSUTILS: TSearchRec, FindFirst, FindNext, FindClose
- GRAPH, FASTGRAPH: FillRect, FillEllipse
- SYSTEM: ODD, INT, LOW, HIGH, SIZEOF, INTR (INTERRUPT_NUMBER), BinStr, OctStr, HexStr, Pause, Sound, NoSound, Concat
- RMT: RMTINIT, RMTPLAY, RMTSTOP
- MPT: MPTINIT, MPTPLAY, MPTSTOP
- CMC: CMCINIT, CMCPLAY, CMCSTOP