ACX: Różnice pomiędzy wersjami

Z Atariki
Przejdź do nawigacji Przejdź do wyszukiwania
Trub (dyskusja | edycje)
mNie podano opisu zmian
Trub (dyskusja | edycje)
Nie podano opisu zmian
 
(Nie pokazano 11 wersji utworzonych przez 3 użytkowników)
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 ==
Rekordy takie przechowują kod ładowanego programu. W zależności od typu określają sposób umieszczenia go w pamięci:
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ą
* $00 - relokacja poza stroną zerową
* $0A - relokacja na stronie zerowej
* $01 - relokacja na stronie zerowej
* $01 - bez relokacji.
* $0A - bez relokacji.


'''Format rekordu kodu'''
'''Format rekordu kodu'''
<table
<table
  style="text-align: left; " 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 (ew. $00 dla kodu na stronie zerowej).
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 $0A). 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 58: Linia 58:
<table
<table
  style="text-align: left; " 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; " 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 112: Linia 112:
Rekord końcowy oznacza koniec pliku (brak dalszych segmentów). Dodatkowo określa sposób uruchomienia załadowanego kodu.
Rekord końcowy oznacza koniec pliku (brak dalszych segmentów). Dodatkowo określa sposób uruchomienia załadowanego kodu.


'''Format rekordu końcowego $0B'''
'''Format rekordu końcowego'''
<table
<table
  style="text-align: left; " border="1"
  style="text-align: left; " border="1"
  cellpadding="2" cellspacing="2">
  cellpadding="5" cellspacing="2">
     <tr>
     <tr>
       <td style="width: 60px;">$0B (Typ)<br>
       <td style="width: 60px;">$0B (Typ)<br>
(1B)</td>
(1 bajt)</td>
       <td style="width: 60px;">Flaga startu<br>
       <td style="width: 60px;">Flaga startu<br>
(1B)</td>
(1 bajt)</td>
       <td style="width: 120px;">Adres startu<br>
       <td style="width: 120px;">Adres startu<br>
(2B)</td>
(2 bajty)</td>
     </tr>
     </tr>
</table>
</table>
Linia 130: Linia 130:
* $01 - uruchomienie programu od adresu bezwzględnego podanego w polu ''Adres startu''
* $01 - uruchomienie programu od adresu bezwzględnego podanego w polu ''Adres startu''
* $02 - uruchomienie programu od adresu relokowanego podanego w polu ''Adres startu''.
* $02 - uruchomienie programu od adresu relokowanego podanego w polu ''Adres startu''.
{{stub}}
 
[[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 z 13 sty 2025, 20:25

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.

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ą
  • $01 - relokacja na stronie zerowej
  • $0A - 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 $0A). 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.