Ma być nowy wspaniały świat. Atarki z procesorem 65c816, 4/8/16 MHz, 16 MB RAM-u, cuda wianki. Wymyśliłem, że do tego trzeba może trochę odświeżyć format pliku binarnego, bo $FFFF to zawsze była żenada, a teraz tym bardziej. W końcu jest XXI wiek ;)
Kiedyś już taki format wymyśliłem, nawet wypuściłem w tym SI 2.06 czy coś takiego. Po latach stwierdzam, że to chyba dobry wynalazek, tym bardziej że jeszcze nad tym popracowałem. Założenia:
1) binaria mają być relokowalne;
2) ma nie być ograniczeń dla programisty, tj. taki plik powinien być zdolny do przechowania każdego możliwego rodzaju kodu na 6502;
3) ma pozwalać na ładowanie plików do rozszerzonej pamięci 65c816.
Format pliku:
bajty 0-3: sygnatura formatu, $52, $45, $4c, $31 (tekst: "REL1")
bajty 4-5: flagi
Flagi (znaczenie gdy = 1):
bit 0 - TSR - program ma jest rezydentem
bit 1 - RUN - uruchomić od offsetu RUNAD
bit 2 - INIT - uruchomić od offsetu INITAD
bit 3 - LWORD - wszystkie dalsze słowa nagłówka 24-bit (16-bit w przeciwnym razie)
bity 4-7: MEMFLG - zakodowany rodzaj pamięci, do którego program ma *najchętniej* być załadowany: 0 - podstawowa ($0000-$FFFF), 1 - rozszerzona ($010000-$FFFFFF), reszta wartości zarezerwowana.
bit 8 - APAGE (Align to PAGE ;-)) - adres ładowania wyrównać w górę do najbliższej wolnej granicy stron.
bit 9 - ABANK - adres ładowania wyrównać w górę do najbliższej wolnej granicy banków.
bity 10-15 - zarezerwowane for future extensions.
Dalszy wygląd nagłówka zależy od wartości bitu 3 we flagach, jak napisano wyżej. W każdym razie:
słowo 0 - długość bloku binarnego programu (nie licząc nagłówka i fixupów)
słowo 1 - długość bloku fixupów 16-bitowych (offsety z zakresu 0-65535), zero jeśli takowego bloku nie ma.
słowo 2 - długość bloku fixupów 24-bitowych (offsety większe od 65535), zero jeśli takowego nie ma
słowo 3 - na razie zarezerwowane
słowo 4 - RUNAD - offset (liczony od początku kodu programu), od którego program należy uruchomić; uruchomienie następuje skokiem JMP tylko wtedy, kiedy flaga RUN w nagłówku jest ustawiona. Rejestry CPU osmiobitowe przy tym myślę.
słowo 5 - INITAD - offset (liczony od początku kodu program), od którego program należy uruchomić; uruchomienie następuje skokiem JSR tylko wtedy, kiedy flaga INIT w nagłówku jest ustawiona. Program ma wrócić przez RTS oddając status zwykłą metodą (czyli LDY #$01 na przykład). Rejestry CPU jak wyżej.
bajt - długość następującego stringu (albo zero, kiedy go nie ma)
string - opcjonalna informacja tekstowa o długości do 254 znaków, zakończona zerem (czyli razem do 255 bajtów).
Dalej jedzie segment binarny o długości jak wykazano w słowie 0. Segment jest jeden i ciągły, bo chyba nie ma sensu robić wielu jak program i tak jest relokowalny.
Po nim fixupy. Fixup to są po prostu dwa bajty (albo trzy, patrz wyżej) offsetu wewnątrz pliku (licząc od początku kodu), gdzie jest adres absolutny odnoszący się do wnętrza programu; np. argument wewnętrznego skoku JSR. Do słowa znajdującego się w miejscu wskazanym przez fixupa dodajemy adres ładowania programu (czyli np. wartość MEMLO).
Teraz: wiadomo, że adresy w Atari są w kolejności młodszy/starszy; fixup wskazuje oczywiście bajt młodszy, loader ma po uzupełnieniu go sam zwiększyć offset o 1 i fiksnąć też bajt starszy.
Ale, w takim układzie oczywiście nie przejdzie konstrukcja następująca, chyba wszyscy wiedzą czemu:
lda #<label+1
ldx #>label+1
...
label .by "tu cośtam",0
Do załatwienia tego służy flaga APAGE w nagłówku: program jest ładowany zawsze od początku granicy stron, co oznacza, że młodsze bajty wszystkich adresów pozostają zawsze niezmienne, i że przy fixupowaniu trzeba zmieniać tylko bajty starsze. W takim układzie fixupy pokazują właśnie na nie i loader po ich uzupełnieniu nie ma już niczego kombinować.
Napisałem dzisiaj loader do tego, który powinien działać pod Spartą oraz DOS II+/D, a poza tym program, który przerabia binaria wypuszczone przez np. MAE na ten nowy format, pozwala na ustawianie wszystkich flag z linii komend itede.
W formacie tym będzie SysInfo 2.08, to jest jedyna metoda, żeby program pozwalał sobie załadować tapetę, kiedy jest wystarczająco dużo pamięci, oraz żeby dalej działał, kiedy nie jest.
Uwagi?
? HEX$(6670358)