ACX: Różnice pomiędzy wersjami

Z Atariki
Przejdź do nawigacji Przejdź do wyszukiwania
Trub (dyskusja | edycje)
Rekord informacyjny
Trub (dyskusja | edycje)
Nie podano opisu zmian
 
(Nie pokazano 17 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 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; 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 $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ą:


* $06 - indeksy 2-bajtowych adresów (przy relokacji aktualizowane zostaną oba bajty)
* $06 - indeksy 2-bajtowych adresów (przy relokacji aktualizowane zostaną oba bajty)
* $02 - indeksy młodszych bajtów (LSB) 2-bajtowych adresów
* $02 - indeksy młodszych bajtów 2-bajtowych adresów
* $08 - indeksy starszych bajtów (MSB) 2-bajtowych adresów
* $08 - indeksy starszych bajtów 2-bajtowych adresów
* $04 - indeksy 1-bajtowych adresów komórek na stronie zerowej
* $04 - indeksy 1-bajtowych adresów komórek na stronie zerowej


Linia 51: 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, 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'''
'''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 73: 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. 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 97: 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 107: 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 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.