Pakiet matematyczny
From Atariki
Wersja z dnia 05:55, 4 sty 2006 KMK (Dyskusja | wkład) (→Format liczb FP) ← Previous diff |
Aktualna wersja KMK (Dyskusja | wkład) |
||
Linia 1: | Linia 1: | ||
- | [[Pakiet matematyczny]], zwany też pakietem procedur zmiennoprzecinkowych, to zawarty w systemie operacyjnym zestaw podprogramów służących do obliczeń na liczbach rzeczywistych. Zajmuje 2k pamięci ROM w obszarze od $D800 do $DFFF i jest intensywnie wykorzystywany przez interpreter [[Atari BASIC]]-a oraz wiele innych programów użytkowych (np. [[MAC/65]], [[UmonXL]] itp., by już przemilczeć napisane w BASIC-u gry w rodzaju [[Crusade in Europe]]). | + | Pakiet matematyczny, zwany też pakietem procedur zmiennoprzecinkowych (lub "pakietem FP"), to zawarty w systemie operacyjnym ośmiobitowego Atari zestaw podprogramów służących do obliczeń na liczbach rzeczywistych. Zajmuje 2k pamięci ROM w obszarze od $D800 do $DFFF i jest intensywnie wykorzystywany przez interpreter [[Atari BASIC]]-a oraz wiele innych programów użytkowych (np. [[MAC/65]], [[UMON XL]] itp., by już przemilczeć napisane w BASIC-u gry w rodzaju [[Crusade in Europe]]). |
- | Pakiet matematyczny jest jedyną częścią systemu nie mającą własnej tablicy wektorów. Bardzo utrudnia to przygotowanie jego ulepszonych wersji. | + | Pakiet matematyczny jest jedyną częścią systemu nie mającą własnej tablicy wektorów. Bardzo utrudnia to przygotowanie jego ulepszonych wersji. Jest też często krytykowany za niewielką szybkość działania. Faktycznie standardowy pakiet FP jest w stanie wykonać średnio 2500 dodawań albo odejmowań oraz 145 mnożeń lub 90 dzieleń zmiennoprzecinkowych na sekundę. |
- | == Format liczb FP == | + | == FASTCHIP == |
- | Dopuszczalny zakres liczb rzeczywistych dla obliczeń to od 10<sup>-98</sup> do 10<sup>97</sup>, z dokładnością do 10 cyfr. Liczba kodowana jest na sześciu bajtach: pierwszy bajt zajmuje 1 bit znaku oraz siedem bitów wykładnika, pozostałe pięć bajtów to mantysa zapisana w kodzie BCD, po dwie cyfry na bajt, w kolejności od najstarszej do najmłodszej. Wykładnik jest to właściwy wykładnik liczby 100 zwiększony o 64. Liczby zapisywane są w postaci: | + | Istnieje "w obiegu" alternatywny pakiet zmiennoprzecinkowy, tzw. '''FASTCHIP''', którego autorem jest [[Charles Marslett]]. Tak samo jak pakiet Atari zajmuje on 2k w pamięci ROM i zawiera pod tymi samymi adresami procedury wykonujące analogiczne obliczenia. Wydajność: 4880 dodawań, 4650 odejmowań, 380 mnożeń, 256 dzieleń na sekundę. Pakietem tym można zastąpić standardowy pakiet FP systemu operacyjnego (pamiętając jednak o sumach kontrolnych ROM-u), co wpływa dodatnio na szybkość wbudowanego interpretera [[Atari BASIC]]. Dodatkowo ulepszone są procedury potęgowania i logarytmowania, dzięki czemu odpowiednie obliczenia w BASIC-u są dokładniejsze (zob. [[Atari BASIC#Błędy w Atari BASIC|Błędy w Atari BASIC]]). |
- | '''100<sup>(C-64)</sup> x M''' | + | Niestety, zaaplikowanie FASTCHIP-a do ROM-u systemu operacyjnego powoduje zakłócenia w pracy [[Turbo BASIC XL|Turbo BASIC-a XL]]: przestaje działać prawidłowo potęgowanie i logarytmowanie z powodu nielegalnego odwoływania się Turbo-BASIC-a XL do niepublikowanych adresów tablic współczynników wewnątrz ROM-u pakietu FP, które - dla optymalizacji kodu - w szybszym pakiecie skonstruowane są inaczej i/lub znajdują się pod innymi adresami. |
+ | |||
+ | FASTCHIP wkompilowano do [[U-BASIC|U-BASIC-a]]. | ||
+ | |||
+ | == Format liczb FP == | ||
+ | Dopuszczalny zakres liczb rzeczywistych dla obliczeń to od 10<sup>-98</sup> do 10<sup>97</sup>, z dokładnością do 10 cyfr (FASTCHIP: od 10<sup>-126</sup> do 10<sup>119</sup>). Liczba kodowana jest na sześciu bajtach: pierwszy bajt zajmuje 1 bit znaku oraz siedem bitów wykładnika, pozostałe pięć bajtów to mantysa zapisana w kodzie BCD, po dwie cyfry na bajt, w kolejności od najstarszej do najmłodszej. Wykładnik jest to właściwy wykładnik liczby 100 zwiększony o 64. Liczby zapisywane są w postaci: | ||
- | gdzie C to cecha, a M - mantysa. | + | '''100<sup>(cecha-64)</sup> x mantysa''' |
Przykładowo, w ciągu liczb $41,$15,$36,$00,$00,$00 pierwszy bajt o wartości $41 to cecha. Najstarszy bit jest skasowany, jest to więc liczba dodatnia. Na pozostałych siedmiu bitach zapisany jest wykładnik liczby 100 zwiększony o 64 ($40). Wykładnik ten w danym przykładzie wynosi więc 1. | Przykładowo, w ciągu liczb $41,$15,$36,$00,$00,$00 pierwszy bajt o wartości $41 to cecha. Najstarszy bit jest skasowany, jest to więc liczba dodatnia. Na pozostałych siedmiu bitach zapisany jest wykładnik liczby 100 zwiększony o 64 ($40). Wykładnik ten w danym przykładzie wynosi więc 1. | ||
Linia 20: | Linia 25: | ||
'''100<sup>-1</sup> x 50 = 0,01 x 50 = 0,5''' | '''100<sup>-1</sup> x 50 = 0,01 x 50 = 0,5''' | ||
- | Pierwszy bajt liczby FP - wykładnik - jest zawsze różny od zera; wyjątkiem jest liczba zero (0) - jest reprezentowana przez sześć bajtów o wartości zero. Do sprawdzenia, czy liczba zmiennoprzecinkowa ma wartość zero wystarczy więc sprawdzenie, czy zerową wartośc ma wykładnik. | + | Pierwszy bajt liczby FP - wykładnik - jest zawsze różny od zera; wyjątkiem jest liczba zero (0) - jest reprezentowana przez sześć bajtów o wartości zero. Do sprawdzenia, czy liczba zmiennoprzecinkowa ma wartość zero wystarczy więc sprawdzenie, czy zerową wartość ma wykładnik. |
== Lista procedur == | == Lista procedur == | ||
- | <p>Procedury zmiennoprzecinkowe używają części strony zerowej (od adresu $D4 do $FF) oraz drugiej połówki strony piątej (od $0580 do $05FF). Dane wejściowe procedur obliczeniowych oczekiwane są w tzw. rejestrach zmiennoprzecinkowych, czyli sześciobajtowych obszarach pamięci, kolejno FR0 ($D4-$D9) i FR1 ($E0-$E5). Wyniki umieszczane są w FR0.</p> | + | <p>Procedury zmiennoprzecinkowe używają części [[strona zerowa|strony zerowej]] (od adresu $D4 do $FF) oraz drugiej połówki strony piątej (od $0580 do $05FF). Dane wejściowe procedur obliczeniowych oczekiwane są w tzw. rejestrach zmiennoprzecinkowych, czyli sześciobajtowych obszarach pamięci, kolejno FR0 ($D4-$D9) i FR1 ($E0-$E5). Wyniki umieszczane są w FR0.</p> |
<table border = 1 cellpadding = 5> | <table border = 1 cellpadding = 5> | ||
Linia 33: | Linia 38: | ||
</td></tr> | </td></tr> | ||
<tr><td>$D8E6</td><td>FASC</td><td> | <tr><td>$D8E6</td><td>FASC</td><td> | ||
- | <p>Konwersja liczby zmiennoprzeciwnkowej na ciąg ASCII (Floating Point to ASCII conversion). Liczbę do konwersji trzeba umieścić w rejestrze FR0 ($D4), wynikowy ciąg znaków po zakończeniu procedury wskazywany jest przez wektor INBUFP ($F3/$F4). Ostatni znak jest w inwersie (ma ustawiony bit 7).</p> | + | <p>Konwersja liczby zmiennoprzecinkowej na ciąg ASCII (Floating Point to ASCII conversion). Liczbę do konwersji trzeba umieścić w rejestrze FR0 ($D4), wynikowy ciąg znaków po zakończeniu procedury wskazywany jest przez wektor INBUFP ($F3/$F4). Ostatni znak jest w inwersie (ma ustawiony bit 7).</p> |
</td></tr> | </td></tr> | ||
<tr><td>$D9AA</td><td>IFP</td><td> | <tr><td>$D9AA</td><td>IFP</td><td> | ||
Linia 39: | Linia 44: | ||
</td></tr> | </td></tr> | ||
<tr><td>$D9D2</td><td>FPI</td><td> | <tr><td>$D9D2</td><td>FPI</td><td> | ||
- | <p>Konwersja liczby zmiennoprzecinkowej na całkowitą (Floating Point to Integer conversion). Liczba zmiennoprzecinkowa umieszczona w rejestrze FR0 ($D4) przekształcana jest na dwubajtową liczbę całkowita bez znaku. Wynik umieszczany jest w pierwszych dwóch bajtach rejestru FR0 ($D4/$D5). Procedura przekształca liczby z zakresu od 0 do 65535, większe albo mniejsze wartości powodują błąd (ustawiony bit C przy powrocie z procedury).</p> | + | <p>Konwersja liczby zmiennoprzecinkowej na całkowitą (Floating Point to Integer conversion). Liczba zmiennoprzecinkowa umieszczona w rejestrze FR0 ($D4) przekształcana jest na dwubajtową liczbę całkowitą bez znaku. Wynik umieszczany jest w pierwszych dwóch bajtach rejestru FR0 ($D4/$D5). Procedura przekształca liczby z zakresu od 0 do 65535, większe albo mniejsze wartości powodują błąd (ustawiony bit C przy powrocie z procedury).</p> |
</td></tr> | </td></tr> | ||
<tr><td colspan = 3>Przesłania itp. rejestrów FP</td></tr> | <tr><td colspan = 3>Przesłania itp. rejestrów FP</td></tr> | ||
<tr><td>$DA44</td><td>ZFR0</td><td><p>Zerowanie rejestru FR0 ($D4)</p></td></tr> | <tr><td>$DA44</td><td>ZFR0</td><td><p>Zerowanie rejestru FR0 ($D4)</p></td></tr> | ||
<tr><td>$DD89</td><td>FLD0R</td><td> | <tr><td>$DD89</td><td>FLD0R</td><td> | ||
- | <p>Załadowanie liczby zmiennoprzecinkowej do rejestru FR0 ($D4). Wskaźnik do liczby FP trzeba umieścić w rejerstrach X (młodszy bajt) i Y (starszy bajt).</p> | + | <p>Załadowanie liczby zmiennoprzecinkowej do rejestru FR0 ($D4). Wskaźnik do liczby FP trzeba umieścić w rejestrach X (młodszy bajt) i Y (starszy bajt).</p> |
</td></tr> | </td></tr> | ||
<tr><td>$DD8D</td><td>FLD0P</td><td> | <tr><td>$DD8D</td><td>FLD0P</td><td> | ||
Linia 50: | Linia 55: | ||
</td></tr> | </td></tr> | ||
<tr><td>$DD98</td><td>FLD1R</td><td> | <tr><td>$DD98</td><td>FLD1R</td><td> | ||
- | <p>Załadowanie liczby zmiennoprzecinkowej do rejestru FR1 ($E0). Wskaźnik do liczby FP trzeba umieścić w rejerstrach X (młodszy bajt) i Y (starszy bajt).</p> | + | <p>Załadowanie liczby zmiennoprzecinkowej do rejestru FR1 ($E0). Wskaźnik do liczby FP trzeba umieścić w rejestrach X (młodszy bajt) i Y (starszy bajt).</p> |
</td></tr> | </td></tr> | ||
<tr><td>$DD9C</td><td>FLD1P</td><td> | <tr><td>$DD9C</td><td>FLD1P</td><td> | ||
Linia 74: | Linia 79: | ||
</td></tr> | </td></tr> | ||
<tr><td>$DADB</td><td>FMUL</td><td> | <tr><td>$DADB</td><td>FMUL</td><td> | ||
- | <p>Dodawanie liczb FP umieszczonych w FR0 i FR1. Wynik w FR0.</p> | + | <p>Mnożenie liczb FP umieszczonych w FR0 i FR1. Wynik w FR0.</p> |
</td></tr> | </td></tr> | ||
<tr><td>$DB28</td><td>FDIV</td><td> | <tr><td>$DB28</td><td>FDIV</td><td> | ||
Linia 96: | Linia 101: | ||
W rzeczywistości ROM pakietu zmiennoprzecinkowego zawiera więcej procedur, poza wymienionymi jednak nie są one specjalnie przydatne. Z procedur potęgowania i logarytmowania korzystają funkcje trygonometryczne oraz operator potęgowania [[Atari BASIC]]. | W rzeczywistości ROM pakietu zmiennoprzecinkowego zawiera więcej procedur, poza wymienionymi jednak nie są one specjalnie przydatne. Z procedur potęgowania i logarytmowania korzystają funkcje trygonometryczne oraz operator potęgowania [[Atari BASIC]]. | ||
+ | |||
+ | == Download == | ||
+ | * [http://drac030.krap.pl/fastfp.arc FASTCHIP] | ||
[[Kategoria:Programowanie Atari 8-bit]] | [[Kategoria:Programowanie Atari 8-bit]] |
Aktualna wersja
Pakiet matematyczny, zwany też pakietem procedur zmiennoprzecinkowych (lub "pakietem FP"), to zawarty w systemie operacyjnym ośmiobitowego Atari zestaw podprogramów służących do obliczeń na liczbach rzeczywistych. Zajmuje 2k pamięci ROM w obszarze od $D800 do $DFFF i jest intensywnie wykorzystywany przez interpreter Atari BASIC-a oraz wiele innych programów użytkowych (np. MAC/65, UMON XL itp., by już przemilczeć napisane w BASIC-u gry w rodzaju Crusade in Europe).
Pakiet matematyczny jest jedyną częścią systemu nie mającą własnej tablicy wektorów. Bardzo utrudnia to przygotowanie jego ulepszonych wersji. Jest też często krytykowany za niewielką szybkość działania. Faktycznie standardowy pakiet FP jest w stanie wykonać średnio 2500 dodawań albo odejmowań oraz 145 mnożeń lub 90 dzieleń zmiennoprzecinkowych na sekundę.
Spis treści |
FASTCHIP
Istnieje "w obiegu" alternatywny pakiet zmiennoprzecinkowy, tzw. FASTCHIP, którego autorem jest Charles Marslett. Tak samo jak pakiet Atari zajmuje on 2k w pamięci ROM i zawiera pod tymi samymi adresami procedury wykonujące analogiczne obliczenia. Wydajność: 4880 dodawań, 4650 odejmowań, 380 mnożeń, 256 dzieleń na sekundę. Pakietem tym można zastąpić standardowy pakiet FP systemu operacyjnego (pamiętając jednak o sumach kontrolnych ROM-u), co wpływa dodatnio na szybkość wbudowanego interpretera Atari BASIC. Dodatkowo ulepszone są procedury potęgowania i logarytmowania, dzięki czemu odpowiednie obliczenia w BASIC-u są dokładniejsze (zob. Błędy w Atari BASIC).
Niestety, zaaplikowanie FASTCHIP-a do ROM-u systemu operacyjnego powoduje zakłócenia w pracy Turbo BASIC-a XL: przestaje działać prawidłowo potęgowanie i logarytmowanie z powodu nielegalnego odwoływania się Turbo-BASIC-a XL do niepublikowanych adresów tablic współczynników wewnątrz ROM-u pakietu FP, które - dla optymalizacji kodu - w szybszym pakiecie skonstruowane są inaczej i/lub znajdują się pod innymi adresami.
FASTCHIP wkompilowano do U-BASIC-a.
Format liczb FP
Dopuszczalny zakres liczb rzeczywistych dla obliczeń to od 10-98 do 1097, z dokładnością do 10 cyfr (FASTCHIP: od 10-126 do 10119). Liczba kodowana jest na sześciu bajtach: pierwszy bajt zajmuje 1 bit znaku oraz siedem bitów wykładnika, pozostałe pięć bajtów to mantysa zapisana w kodzie BCD, po dwie cyfry na bajt, w kolejności od najstarszej do najmłodszej. Wykładnik jest to właściwy wykładnik liczby 100 zwiększony o 64. Liczby zapisywane są w postaci:
100(cecha-64) x mantysa
Przykładowo, w ciągu liczb $41,$15,$36,$00,$00,$00 pierwszy bajt o wartości $41 to cecha. Najstarszy bit jest skasowany, jest to więc liczba dodatnia. Na pozostałych siedmiu bitach zapisany jest wykładnik liczby 100 zwiększony o 64 ($40). Wykładnik ten w danym przykładzie wynosi więc 1.
Dalej znajduje się mantysa zapisana w kodzie BCD. Punkt dziesiętny zawsze znajduje się po pierwszym jej bajcie, mamy tu więc zapisaną wartość 15,36 (piętnaście i trzydzieści sześć setnych). W połączeniu z obliczonym wyżej wykładnikiem liczby sto daje to
1001 x 15,36 = 100 x 15,36 = 1536
Przykład drugi: $3F,$50,$00,$00,$00,$00. Najstarszy bit cechy jest skasowany, jest to więc znowu liczba dodatnia. Wykładnik powiększony o $40 ma wartość $3F, a więc jego właściwa wartość to -1. Jako że pierwszy bajt mantysy zawiera jej część całkowitą, a reszta ułamek, widać, iż mantysa ma wartość 50,00. W połączeniu z obliczonym wcześniej wykładnikiem dostajemy
100-1 x 50 = 0,01 x 50 = 0,5
Pierwszy bajt liczby FP - wykładnik - jest zawsze różny od zera; wyjątkiem jest liczba zero (0) - jest reprezentowana przez sześć bajtów o wartości zero. Do sprawdzenia, czy liczba zmiennoprzecinkowa ma wartość zero wystarczy więc sprawdzenie, czy zerową wartość ma wykładnik.
Lista procedur
Procedury zmiennoprzecinkowe używają części strony zerowej (od adresu $D4 do $FF) oraz drugiej połówki strony piątej (od $0580 do $05FF). Dane wejściowe procedur obliczeniowych oczekiwane są w tzw. rejestrach zmiennoprzecinkowych, czyli sześciobajtowych obszarach pamięci, kolejno FR0 ($D4-$D9) i FR1 ($E0-$E5). Wyniki umieszczane są w FR0.
Adres | Etykieta | Opis |
Konwersja liczb | ||
$D800 | AFP |
Konwersja liczby zapisanej znakami ASCII na liczbę zmiennoprzecinkową (ASCII to Floating Point conversion). Ciąg znaków do konwersji musi być wskazany wektorem INBUFP ($F3/$F4), przed wywołaniem procedury AFP trzeba też wyzerować rejestr CIX ($F2). Konwersja przeprowadzana jest aż do napotkania niedozwolonego znaku, opuszczenie procedury z ustawionym bitem C sygnalizuje błąd. Gdy C=0, wynik znajduje się w rejestrze FR0 ($D4). |
$D8E6 | FASC |
Konwersja liczby zmiennoprzecinkowej na ciąg ASCII (Floating Point to ASCII conversion). Liczbę do konwersji trzeba umieścić w rejestrze FR0 ($D4), wynikowy ciąg znaków po zakończeniu procedury wskazywany jest przez wektor INBUFP ($F3/$F4). Ostatni znak jest w inwersie (ma ustawiony bit 7). |
$D9AA | IFP |
Konwersja liczby całkowitej na zmiennoprzecinkową (Integer to Floating Point conversion). Dwubajtowa liczba binarna umieszczona w pierwszych dwóch bajtach rejestru FR0 ($D4/$D5) w kolejności młodszy-starszy bajt jest przekształcana na postać zmiennoprzecinkową. Wynik umieszczany jest w rejestrze FR0 ($D4). Dana wejściowa traktowana jest jako liczba całkowita bez znaku. |
$D9D2 | FPI |
Konwersja liczby zmiennoprzecinkowej na całkowitą (Floating Point to Integer conversion). Liczba zmiennoprzecinkowa umieszczona w rejestrze FR0 ($D4) przekształcana jest na dwubajtową liczbę całkowitą bez znaku. Wynik umieszczany jest w pierwszych dwóch bajtach rejestru FR0 ($D4/$D5). Procedura przekształca liczby z zakresu od 0 do 65535, większe albo mniejsze wartości powodują błąd (ustawiony bit C przy powrocie z procedury). |
Przesłania itp. rejestrów FP | ||
$DA44 | ZFR0 | Zerowanie rejestru FR0 ($D4) |
$DD89 | FLD0R |
Załadowanie liczby zmiennoprzecinkowej do rejestru FR0 ($D4). Wskaźnik do liczby FP trzeba umieścić w rejestrach X (młodszy bajt) i Y (starszy bajt). |
$DD8D | FLD0P |
Analogicznie do FLD0R, lecz adres liczby umieszczamy w wektorze FLPTR ($FC/$FD). |
$DD98 | FLD1R |
Załadowanie liczby zmiennoprzecinkowej do rejestru FR1 ($E0). Wskaźnik do liczby FP trzeba umieścić w rejestrach X (młodszy bajt) i Y (starszy bajt). |
$DD9C | FLD1P |
Analogicznie do FLD1R, lecz adres liczby umieszczamy w wektorze FLPTR ($FC/$FD). |
$DDA7 | FST0R |
Zapis liczby zmiennoprzecinkowej znajdującej się we FR0 ($D4) do miejsca w pamięci wskazanego przez rejestry X/Y (odpowiednio młodszy i starszy bajt adresu). |
$DDAB | FST0P |
Analogicznie do FST0R, lecz adres docelowy umieszczamy w wektorze FLPTR ($FC/$FD). |
$DDB6 | FMOV01 | Przesłanie liczby zmiennoprzecinkowej z FR0 ($D4) do FR1 ($E0). |
$DD28 | FMOV12 | Przesłanie liczby zmiennoprzecinkowej z FR1 ($E0) do FR2 ($E6). |
$DD34 | FMOV0E |
Przesłanie liczby zmiennoprzecinkowej z FR0 ($D4) do FRE ($DA). |
Obliczenia | ||
$DA60 | FSUB |
Odejmowanie liczby FP umieszczonej w FR1 od liczby FP umieszczonej w FR0. Wynik w FR0. |
$DA66 | FADD |
Dodawanie liczb FP umieszczonych w FR0 i FR1. Wynik w FR0. |
$DADB | FMUL |
Mnożenie liczb FP umieszczonych w FR0 i FR1. Wynik w FR0. |
$DB28 | FDIV |
Dzielenie liczby FP umieszczonej w FR0 przez liczbę FP umieszczoną w FR1. Wynik w FR0. |
$DDC0 | EXP |
Podnosi liczbę E (2,71828182) do potęgi o wykładniku wpisanym do FR0. |
$DDCC | EXP10 |
Podnosi liczbę 10 do potęgi o wykładniku wpisanym do FR0. |
$DECD | LOG |
Oblicza logarytm naturalny liczby FP wpisanej do FR0. |
$DED1 | LOG10 |
Oblicza logarytm dziesiętny liczby FP wpisanej do FR0. |
W rzeczywistości ROM pakietu zmiennoprzecinkowego zawiera więcej procedur, poza wymienionymi jednak nie są one specjalnie przydatne. Z procedur potęgowania i logarytmowania korzystają funkcje trygonometryczne oraz operator potęgowania Atari BASIC.