ACX
From Atariki
Wersja z dnia 19:40, 22 mar 2007 Trub (Dyskusja | wkład) (sygnatura pliku) ← Previous diff |
Aktualna wersja Krótki (Dyskusja | wkład) (Ja tam nie mam pewności czy Amy Chen to kobieta.) |
||
Linia 1: | Linia 1: | ||
- | ACX - od ang. ''Amy Chen Executable'' - jest formatem pliku przeznaczonym do przechowywania relokowalnych binariów. Format ten został stworzony dla doładowywanych z zewnątrz handlerów urządzeń podłączonych do łącza szeregowego ([[SIO]]) oraz szyny równoległej ([[PBI]]), zwłaszcza ekspandera [[1090]]. | + | ACX - od ang. ''Amy Chen eXecutable'' - jest formatem pliku przeznaczonym do przechowywania relokowalnych binariów. Format ten został stworzony dla doładowywanych z zewnątrz handlerów urządzeń podłączonych do łącza szeregowego ([[SIO]]) oraz szyny równoległej ([[PBI]]), zwłaszcza ekspandera [[1090]]. |
Procedury obsługujące ten format znajdują się w [[XL OS]], w każdym seryjnym egzemplarzu [[1200XL]], [[600XL]], [[800XL]], [[65XE]] i [[130XE]]. System korzysta z nich podczas ładowania sterowników (handlerów) z podłączonych urządzeń, np. z modułu [[1090]]. Objawem tego jest znane wszystkim posiadaczom Atari "pierdzenie" wydobywające się z głośnika monitora przy starcie systemu oraz przy odwołaniu do urządzenia niezarejestrowanego w [[CIO]]. Jest to próba skomunikowania się z urządzeniami peryferyjnymi w celu ściągnięcia odpowiednich sterowników. | Procedury obsługujące ten format znajdują się w [[XL OS]], w każdym seryjnym egzemplarzu [[1200XL]], [[600XL]], [[800XL]], [[65XE]] i [[130XE]]. System korzysta z nich podczas ładowania sterowników (handlerów) z podłączonych urządzeń, np. z modułu [[1090]]. Objawem tego jest znane wszystkim posiadaczom Atari "pierdzenie" wydobywające się z głośnika monitora przy starcie systemu oraz przy odwołaniu do urządzenia niezarejestrowanego w [[CIO]]. Jest to próba skomunikowania się z urządzeniami peryferyjnymi w celu ściągnięcia odpowiednich sterowników. | ||
- | Zamierzeniem twórców była dostępność procedury relokującej dla programistów. Planowane było umieszczenie legalnego skoku pod adresem $E486, umożliwiającego relokowanie "zwykłych" programów. Niestety, z niewiadomych przyczyn zrezygnowano z tego rozwiązania. | + | Zamierzeniem twórców była dostępność procedury relokującej dla programistów. Planowane było umieszczenie oficjalnego skoku pod adresem $E486, umożliwiającego relokowanie "zwykłych" programów. Niestety, z niewiadomych przyczyn zrezygnowano z tego rozwiązania. |
- | W systemie operacyjnym [[DracOS]] od wersji 2.22 przywrócono w tablicy skoków legalne odwołanie do procedury relokatora. Skok do niej umieszczono jednak pod adresem $E483, ze względu na zajęcie pierwotnego adresu przez inną procedurę. | + | W systemie operacyjnym [[DracOS]] od wersji 2.22 przywrócono w [[Tablica skoków|tablicy skoków]] legalne odwołanie do procedury relokatora. Skok do niej umieszczono jednak pod adresem $E483, ze względu na zajęcie pierwotnego adresu przez inną procedurę. |
- | Loader i związany z nim format binarny zostały przeanalizowane przez [[Trub]]a w 2006 roku na podstawie dokumentacji pochodzącej z Atari, pod którą podpisana jest niejaka Amy Chen. Stąd pochodzi nadana formatowi nieoficjalna nazwa. | + | Loader i związany z nim format binarny zostały przeanalizowane przez [[Trub]]a w 2006 roku na podstawie dokumentacji pochodzącej z Atari. Według kodu źródłowego autorem procedur obsługi jest Y.M. "Amy" Chen; stąd pochodzi nadana formatowi nieoficjalna nazwa. |
== Ogólna struktura pliku == | == Ogólna struktura pliku == | ||
Właściwą strukturę pliku stanowią segmenty, z których każdy dotyczy pewnego fragmentu ładowanego programu. Segment jest podzielony na rekordy, z których pierwszy zawiera kod lub dane programu (''Text record'', zwany dalej ''rekordem kodu''), zaś dalej następują rekordy informacyjne, określające parametry dla relokatora (''Information records''). W typowej sytuacji program musi zostać podzielony na porcje po maksymalnie 253 bajty, ponieważ segment nie może opisywać większych fragmentów. Ostatnim rekordem w pliku jest rekord końcowy (''End record''). | Właściwą strukturę pliku stanowią segmenty, z których każdy dotyczy pewnego fragmentu ładowanego programu. Segment jest podzielony na rekordy, z których pierwszy zawiera kod lub dane programu (''Text record'', zwany dalej ''rekordem kodu''), zaś dalej następują rekordy informacyjne, określające parametry dla relokatora (''Information records''). W typowej sytuacji program musi zostać podzielony na porcje po maksymalnie 253 bajty, ponieważ segment nie może opisywać większych fragmentów. Ostatnim rekordem w pliku jest rekord końcowy (''End record''). | ||
- | Już poza oficjalną specyfikacją przyjęto, że plik dyskowy w formacie ACX posiada dodatkowo nagłówek (sygnaturę) w dwóch pierwszych bajtach, które wynoszą kolejno $F0,$FF (nie dotyczy sterowników ładowanych z urządzeń peryferyjnych). | + | Już poza oficjalną specyfikacją przyjęto, że plik dyskowy w formacie ACX zawiera dodatkowo nagłówek (sygnaturę) w dwóch pierwszych bajtach; ich wartości wynoszą kolejno $F0,$FF (nie dotyczy sterowników ładowanych z urządzeń peryferyjnych). |
== Rekord kodu == | == Rekord kodu == | ||
Linia 21: | Linia 21: | ||
'''Format rekordu kodu''' | '''Format rekordu kodu''' | ||
<table | <table | ||
- | style="text-align: left; width: 573px;" border="1" | + | style="text-align: left; " border="1" |
- | cellpadding="2" cellspacing="2"> | + | cellpadding="5" cellspacing="2"> |
<tr> | <tr> | ||
<td style="width: 60px;">Typ<br> | <td style="width: 60px;">Typ<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 60px;">Długość<br> | <td style="width: 60px;">Długość<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 120px;">Adres | <td style="width: 120px;">Adres | ||
- | względny lub bezwzględny (2B)</td> | + | względny lub bezwzględny (2 bajty)</td> |
<td style="width: 300px;">Kod | <td style="width: 300px;">Kod | ||
- | programu (max. 253B)</td> | + | programu (max. 253 bajty)</td> |
</tr> | </tr> | ||
</table> | </table> | ||
- | Na długość składają się, oprócz kodu programu także 2 bajty adresu, stąd powinna się mieścić w zakresie 2-255. Adres bezwględny dotyczy miejsca umieszczenia w pamięci kodu nierelokowanego (typ $01). Dla kodu relokowalnego adres względny określa jego przemieszczenie względem adresu bazowego programu, który powinien wynosić $0000. | + | Na długość składają się, oprócz kodu programu także 2 bajty adresu, stąd powinna się mieścić w zakresie 2-255. Adres bezwględny dotyczy miejsca umieszczenia w pamięci kodu nierelokowanego (typ $01). Dla kodu relokowalnego adres względny określa jego przemieszczenie względem adresu bazowego programu, który powinien wynosić $0000 (ew. $00 dla kodu na stronie zerowej). |
== Rekord informacyjny == | == Rekord informacyjny == | ||
- | Rekordy takie zawierają informacje konieczne do relokowania fragmentu programu zawartego w poprzedzającym rekordzie kodu. Zawierają indeksy (offsety) elementów w kodzie, które ulegają zmianie przy jego przemieszczaniu. W zależności od rodzaju wskazywanych elementów stosuje się następujące typy rekordów informacyjnych: | + | Rekordy takie zawierają tzw. fixupy, czyli informacje konieczne do relokowania fragmentu programu zawartego w poprzedzającym rekordzie kodu. Są to indeksy (offsety) elementów w kodzie, które ulegają zmianie przy jego przemieszczaniu. W zależności od rodzaju wskazywanych elementów stosuje się następujące typy rekordów informacyjnych: |
Dla kodu ładowanego poza stronę zerową: | Dla kodu ładowanego poza stronę zerową: | ||
Linia 53: | Linia 53: | ||
* $05 - indeksy 1-bajtowych adresów komórek na stronie zerowej. | * $05 - indeksy 1-bajtowych adresów komórek na stronie zerowej. | ||
- | Struktura rekordu informacyjnego jest inna dla typów relokujących adresy i młodsze bajty niż dla typów relokujących starsze bajty. Dla pierwszego przypadku podaje się odpowiednie indeksy (offsety) elementów w poprzedzającym rekordzie kodu (pierwszy bajt porcji kodu ma indeks 0), które podlegają relokacji. | + | Struktura rekordu informacyjnego jest inna dla typów relokujących adresy i młodsze bajty niż dla typów relokujących starsze bajty. Dla pierwszego przypadku podaje się odpowiednie indeksy (offsety) elementów w poprzedzającym rekordzie kodu, które podlegają relokacji (pierwszy bajt porcji kodu ma indeks 0). |
'''Format rekordu informacyjnego dla typów $02,$03,$04,$05,$06,$07 (relokacja adresów lub młodszych bajtów)''' | '''Format rekordu informacyjnego dla typów $02,$03,$04,$05,$06,$07 (relokacja adresów lub młodszych bajtów)''' | ||
<table | <table | ||
- | style="text-align: left; width: 573px;" border="1" | + | style="text-align: left; " border="1" |
- | cellpadding="2" cellspacing="2"> | + | cellpadding="5" cellspacing="2"> |
<tr> | <tr> | ||
<td style="width: 60px;">Typ<br> | <td style="width: 60px;">Typ<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 60px;">Długość<br> | <td style="width: 60px;">Długość<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 60px;">Indeks 1<br> | <td style="width: 60px;">Indeks 1<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 60px;">Indeks 2<br> | <td style="width: 60px;">Indeks 2<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 60px;">Indeks 3<br> | <td style="width: 60px;">Indeks 3<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 60px;"> ... </td> | <td style="width: 60px;"> ... </td> | ||
</tr> | </tr> | ||
Linia 75: | Linia 75: | ||
Długość powinna mieścić się w zakresie 1-253. | Długość powinna mieścić się w zakresie 1-253. | ||
- | W przypadku relokowania starszych bajtów adresów, do właściwej ich aktualizacji potrzebne jest dodatkowo uwzględnienie wartości młodszych bajtów (LSB). Ponieważ w kodzie ich nie musi być, umieszcza się je w rekordzie informacyjnym. | + | W przypadku relokowania starszych bajtów adresów, do właściwej ich aktualizacji potrzebne jest dodatkowo uwzględnienie wartości młodszych bajtów (LSB). Ponieważ w kodzie może ich nie być, umieszcza się je w rekordzie informacyjnym. |
'''Format rekordu informacyjnego dla typów $08,$09 (relokacja starszych bajtów)''' | '''Format rekordu informacyjnego dla typów $08,$09 (relokacja starszych bajtów)''' | ||
<table | <table | ||
- | style="text-align: left; width: 573px;" border="1" | + | style="text-align: left; " border="1" |
- | cellpadding="2" cellspacing="2"> | + | cellpadding="5" cellspacing="2"> |
<tr> | <tr> | ||
<td style="width: 60px;">Typ<br> | <td style="width: 60px;">Typ<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 60px;">Długość<br> | <td style="width: 60px;">Długość<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 60px;">Indeks 1<br> | <td style="width: 60px;">Indeks 1<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 60px;">LSB 1<br> | <td style="width: 60px;">LSB 1<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 60px;">Indeks 2<br> | <td style="width: 60px;">Indeks 2<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 60px;">LSB 2<br> | <td style="width: 60px;">LSB 2<br> | ||
- | (1B)</td> | + | (1 bajt)</td> |
<td style="width: 60px;"> ... </td> | <td style="width: 60px;"> ... </td> | ||
</tr> | </tr> | ||
Linia 99: | Linia 99: | ||
Długość powinna mieścić się w zakresie 0-255. | Długość powinna mieścić się w zakresie 0-255. | ||
- | Uwzględnienie przy relokacji części adresów (osobno starszy, młodszy bajt) umożliwia m.in. stosowanie w programie konstrukcji typu ''lda #<adres, ldx #>adres'', co nie jest typowe dla innych formatów relokowalnych stosowanych w Atari. Interesujące jest również specjalne potraktowanie strony zerowej, np. typ $04 pozwala poprawnie relokować następujący program: | + | Uwzględnienie przy relokacji części adresów (osobno starszy, młodszy bajt) umożliwia m.in. stosowanie w programie konstrukcji typu ''lda #<adres / ldx #>adres'', co nie jest typowe dla innych formatów relokowalnych stosowanych w Atari. Interesujące jest również specjalne potraktowanie strony zerowej, np. typ $04 pozwala poprawnie relokować następujący program: |
<pre> | <pre> | ||
org $600 ;kod poza stroną zerową | org $600 ;kod poza stroną zerową | ||
Linia 109: | Linia 109: | ||
</pre> | </pre> | ||
- | {{stub}} | + | == Rekord końcowy == |
+ | Rekord końcowy oznacza koniec pliku (brak dalszych segmentów). Dodatkowo określa sposób uruchomienia załadowanego kodu. | ||
+ | |||
+ | '''Format rekordu końcowego''' | ||
+ | <table | ||
+ | style="text-align: left; " border="1" | ||
+ | cellpadding="5" cellspacing="2"> | ||
+ | <tr> | ||
+ | <td style="width: 60px;">$0B (Typ)<br> | ||
+ | (1 bajt)</td> | ||
+ | <td style="width: 60px;">Flaga startu<br> | ||
+ | (1 bajt)</td> | ||
+ | <td style="width: 120px;">Adres startu<br> | ||
+ | (2 bajty)</td> | ||
+ | </tr> | ||
+ | </table> | ||
+ | |||
+ | Wartości pola ''Flaga startu'' oznaczają: | ||
+ | * $00 - brak uruchomienia programu, zawartość pola ''Adres startu'' jest ignorowana | ||
+ | * $01 - uruchomienie programu od adresu bezwzględnego podanego w polu ''Adres startu'' | ||
+ | * $02 - uruchomienie programu od adresu relokowanego podanego w polu ''Adres startu''. | ||
+ | |||
[[Kategoria:Atari 8-bit]] | [[Kategoria:Atari 8-bit]] | ||
[[Kategoria:Programowanie Atari 8-bit]] | [[Kategoria:Programowanie Atari 8-bit]] | ||
[[Kategoria:Formaty plików]] | [[Kategoria:Formaty plików]] |
Aktualna wersja
ACX - od ang. Amy Chen eXecutable - jest formatem pliku przeznaczonym do przechowywania relokowalnych binariów. Format ten został stworzony dla doładowywanych z zewnątrz handlerów urządzeń podłączonych do łącza szeregowego (SIO) oraz szyny równoległej (PBI), zwłaszcza ekspandera 1090.
Procedury obsługujące ten format znajdują się w XL OS, w każdym seryjnym egzemplarzu 1200XL, 600XL, 800XL, 65XE i 130XE. System korzysta z nich podczas ładowania sterowników (handlerów) z podłączonych urządzeń, np. z modułu 1090. Objawem tego jest znane wszystkim posiadaczom Atari "pierdzenie" wydobywające się z głośnika monitora przy starcie systemu oraz przy odwołaniu do urządzenia niezarejestrowanego w CIO. Jest to próba skomunikowania się z urządzeniami peryferyjnymi w celu ściągnięcia odpowiednich sterowników.
Zamierzeniem twórców była dostępność procedury relokującej dla programistów. Planowane było umieszczenie oficjalnego skoku pod adresem $E486, umożliwiającego relokowanie "zwykłych" programów. Niestety, z niewiadomych przyczyn zrezygnowano z tego rozwiązania. W systemie operacyjnym DracOS od wersji 2.22 przywrócono w tablicy skoków legalne odwołanie do procedury relokatora. Skok do niej umieszczono jednak pod adresem $E483, ze względu na zajęcie pierwotnego adresu przez inną procedurę.
Loader i związany z nim format binarny zostały przeanalizowane przez Truba w 2006 roku na podstawie dokumentacji pochodzącej z Atari. Według kodu źródłowego autorem procedur obsługi jest Y.M. "Amy" Chen; stąd pochodzi nadana formatowi nieoficjalna nazwa.
Spis treści |
Ogólna struktura pliku
Właściwą strukturę pliku stanowią segmenty, z których każdy dotyczy pewnego fragmentu ładowanego programu. Segment jest podzielony na rekordy, z których pierwszy zawiera kod lub dane programu (Text record, zwany dalej rekordem kodu), zaś dalej następują rekordy informacyjne, określające parametry dla relokatora (Information records). W typowej sytuacji program musi zostać podzielony na porcje po maksymalnie 253 bajty, ponieważ segment nie może opisywać większych fragmentów. Ostatnim rekordem w pliku jest rekord końcowy (End record).
Już poza oficjalną specyfikacją przyjęto, że plik dyskowy w formacie ACX zawiera dodatkowo nagłówek (sygnaturę) w dwóch pierwszych bajtach; ich wartości wynoszą kolejno $F0,$FF (nie dotyczy sterowników ładowanych z urządzeń peryferyjnych).
Rekord kodu
Rekordy takie przechowują kod ładowanego programu. W zależności od typu określają sposób umieszczenia go w pamięci:
- $00 - relokacja poza stroną zerową
- $0A - relokacja na stronie zerowej
- $01 - bez relokacji.
Format rekordu kodu
Typ (1 bajt) |
Długość (1 bajt) |
Adres względny lub bezwzględny (2 bajty) | Kod programu (max. 253 bajty) |
Na długość składają się, oprócz kodu programu także 2 bajty adresu, stąd powinna się mieścić w zakresie 2-255. Adres bezwględny dotyczy miejsca umieszczenia w pamięci kodu nierelokowanego (typ $01). Dla kodu relokowalnego adres względny określa jego przemieszczenie względem adresu bazowego programu, który powinien wynosić $0000 (ew. $00 dla kodu na stronie zerowej).
Rekord informacyjny
Rekordy takie zawierają tzw. fixupy, czyli informacje konieczne do relokowania fragmentu programu zawartego w poprzedzającym rekordzie kodu. Są to indeksy (offsety) elementów w kodzie, które ulegają zmianie przy jego przemieszczaniu. W zależności od rodzaju wskazywanych elementów stosuje się następujące typy rekordów informacyjnych:
Dla kodu ładowanego poza stronę zerową:
- $06 - indeksy 2-bajtowych adresów (przy relokacji aktualizowane zostaną oba bajty)
- $02 - indeksy młodszych bajtów 2-bajtowych adresów
- $08 - indeksy starszych bajtów 2-bajtowych adresów
- $04 - indeksy 1-bajtowych adresów komórek na stronie zerowej
Dla kodu ładowanego na stronę zerową:
- $07 - indeksy 2-bajtowych adresów (przy relokacji aktualizowane zostaną oba bajty)
- $03 - indeksy młodszych bajtów 2-bajtowych adresów
- $09 - indeksy starszych bajtów 2-bajtowych adresów
- $05 - indeksy 1-bajtowych adresów komórek na stronie zerowej.
Struktura rekordu informacyjnego jest inna dla typów relokujących adresy i młodsze bajty niż dla typów relokujących starsze bajty. Dla pierwszego przypadku podaje się odpowiednie indeksy (offsety) elementów w poprzedzającym rekordzie kodu, które podlegają relokacji (pierwszy bajt porcji kodu ma indeks 0).
Format rekordu informacyjnego dla typów $02,$03,$04,$05,$06,$07 (relokacja adresów lub młodszych bajtów)
Typ (1 bajt) |
Długość (1 bajt) |
Indeks 1 (1 bajt) |
Indeks 2 (1 bajt) |
Indeks 3 (1 bajt) |
... |
Długość powinna mieścić się w zakresie 1-253.
W przypadku relokowania starszych bajtów adresów, do właściwej ich aktualizacji potrzebne jest dodatkowo uwzględnienie wartości młodszych bajtów (LSB). Ponieważ w kodzie może ich nie być, umieszcza się je w rekordzie informacyjnym.
Format rekordu informacyjnego dla typów $08,$09 (relokacja starszych bajtów)
Typ (1 bajt) |
Długość (1 bajt) |
Indeks 1 (1 bajt) |
LSB 1 (1 bajt) |
Indeks 2 (1 bajt) |
LSB 2 (1 bajt) |
... |
Długość powinna mieścić się w zakresie 0-255.
Uwzględnienie przy relokacji części adresów (osobno starszy, młodszy bajt) umożliwia m.in. stosowanie w programie konstrukcji typu lda #<adres / ldx #>adres, co nie jest typowe dla innych formatów relokowalnych stosowanych w Atari. Interesujące jest również specjalne potraktowanie strony zerowej, np. typ $04 pozwala poprawnie relokować następujący program:
org $600 ;kod poza stroną zerową lda zvar ;adresowanie strony zerowej ... org $80 ;kod na stronie zerowej zvar .byte 0
Rekord końcowy
Rekord końcowy oznacza koniec pliku (brak dalszych segmentów). Dodatkowo określa sposób uruchomienia załadowanego kodu.
Format rekordu końcowego
$0B (Typ) (1 bajt) |
Flaga startu (1 bajt) |
Adres startu (2 bajty) |
Wartości pola Flaga startu oznaczają:
- $00 - brak uruchomienia programu, zawartość pola Adres startu jest ignorowana
- $01 - uruchomienie programu od adresu bezwzględnego podanego w polu Adres startu
- $02 - uruchomienie programu od adresu relokowanego podanego w polu Adres startu.