Aktualizacja:
8 V 2016




== Akceleratory ==
* Opis
* Pliki
== IDE Plus ==
* Opis
* Pliki
== MultiBASIC ==
* Opis
* Lista zmian
* Pliki
== SysInfo ==
* Opis
* Pliki
== Rozmaitości ==
* Pliki
== U-BASIC ==
* Opis
* Pliki
== 65C816 XL OS ==
* Opis
* Lista zmian
* Lista zgodności
* Pliki
== Poprawki ==
* Pliki
== SpartaDOS X ==
* Opis
* Pliki
== VBXE ==
* Opis
* Pliki














 

Wersja XL OS dla 65C816

WDC 65C816S, zwany w skrócie 65C816, to wytworzony i sprzedawany przez Western Design Center mikroprocesor, który jest wersją rozwojową mikroprocesora 6502. Różne wersje 6502 zastosowano m.in. w komputerach Apple II, Atari 400/800/XL/XE oraz Commodore C-64, C-128.

W odróżnieniu od 6502, który jest układem w pełni ośmiobitowym, układ 65C816, mimo ośmiobitowej magistrali danych, ma strukturę wewnętrzną pozwalającą na szesnastobitowe ich przetwarzanie. Dostępne są szesnastobitowe rejestry, do 64 kB stosu, wiele nowych trybów adresowania i rozkazów (w tym nieznane na 6502 przesłania pamięć-pamięć). Oraz, przede wszystkim, dzięki 24-bitowej szynie adresowej możliwy jest montaż do 16 MB pamięci adresowanej wprost. Mikroprocesor może też pracować z dużo większą niż 6502 częstotliwością - do 14 MHz.

Wszystkie te cechy sprawiają, że zamiana 6502 na 65C816 staje się bardzo interesującym rozszerzeniem, jakie można sobie zamontować do małego Atari. Ta strona poświęcona jest niektórym aspektom takiego rozszerzenia.



I. Notki wstępne

65C816 ma dwa tryby pracy. Pierwszy z nich, to tryb emulacji 6502, w którym procesor się "budzi" dla zachowania zgodności z systemami operacyjnymi pisanymi dla 6502. Drugi tryb, to tryb natywny, który pozwala na skorzystanie z większości rozszerzeń, tj. np. z 16-bitowych rejestrów. Niestety, żeby użyć trybu natywnego, trzeba zmodyfikować zawartość ROM-u Atari XL/XE, z powodów objaśnionych poniżej. Ta konieczność natchnęła mnie do tego, żeby do sprawy podejść kompleksowo i nie poprzestając na samym tylko umożliwieniu pracy w trybie natywnym, sprezentować istniejącym jeszcze użytkownikom Atari nową wersję systemu operacyjnego. Zawarłem tam pewne rozszerzenia, które wydały mi się niezbędne, albo przynajmniej przydatne.

Wszystkie prace nad kodem systemu wykonuję na moim Atari 65XE. Komputer wyposażony jest w mikroprocesor 65C816, wewnętrzną kartę SpartaDOS X, 256 kB bankowanej pamięci RAM, 2,5 calowy twardy dysk Toshiba MK2103MAV o pojemności 2,1 GB (podpięty przez interfejs KMK/JŻ IDE), oraz oczywiście opisywany niniejszym ROM. System pisany jest i kompilowany pod asemblerem MAE 1.2 autorstwa Johna Harrisa.

Modyfikacja ROM-u ma na celu:

  1. uczynić możliwym użycie trybu natywnego 65C816 przy programowaniu na Atari XL/XE, bez problemów i z włączonymi przerwaniami. Dotychczasowe wersje XL OS nie zawierają niczego sensownego w miejscu, gdzie 65C816 oczekuje wektorów przerwań dla trybu natywnego. Dlatego przełączenie w tryb natywny powoduje zwis.
  2. uczynić możliwym użycie dodatkowej pamięci mogącej znajdować się w obszarze ($010000-$FFFFFF). Uruchamianie programów w tej pamięci wymaga przełączenia się w tryb natywny, a co do trybu natywnego patrz powyżej.
  3. dodanie kilku prostych funkcji związanych z nowym procesorem, np. nowe wektory przerwań, obsługę dodatkowej pamięci itd.
  4. dodanie nowego mechanizmu wywoływania funkcji systemowych, bo dotychczasowy jest bezużyteczny dla programów uruchamianych w dodatkowej pamięci (powyżej adresu $00FFFF).
  5. przyspieszenie nieco procedur matematycznych, ale to nie jest jakoś super ważne i pierwszorzędne zadanie;
  6. zaoferowanie coś bardziej sensownego na miejsce Self Test-u, dodatkowe procedury testowania rozszerzonej pamięci itd.
  7. ulepszenie procedur drukarki, tak żeby można ich było używać wprost ze współczesnymi drukarkami (bez konwersji EOL > CR/LF itd.), o ile się to okaże potrzebne;
  8. usunięcie znanych błędów.

II. Instrukcja obsługi

Obsługa systemu praktycznie nie różni się od obsługi XL OS, oba systemy zachowują się podobnie. Jedyna większa różnica występuje w funkcjach klawiszy konsoli:

  • klawisz OPTION wciśnięty przy starcie systemu włącza wewnętrzny interpreter Atari BASIC-a (w XL OS wciśnięcie OPTION wyłącza BASIC).
  • klawisz SELECT wciśnięty razem z klawiszem RESET, wymusza zimny start.
  • klawisz START wciśnięty przy starcie systemu wywołuje na ekran menu służące do wyboru dysku, z którego komputer ma wystartować. W XL OS przytrzymanie klawisza START powoduje próbę dokonania odczytu wstępnego z magnetofonu. W nowym OS-ie ta możliwość została usunięta.

1) Domyślna stacja dysków

Inaczej niż w XL OS, numer napędu, z którego ma przebiegać start systemu (boot) jest ustalany nie po, ale przed zainicjowaniem sterowników urządzeń podłączonych do szyny równoległej. W efekcie sterownik twardego dysku ma możliwość łatwej - bez żadnych, a koniecznych pod XL OS, sztuczek - zmiany numeru tego dysku. Korzysta z tego interfejs KMK/JŻ.

2) Menu

Menu, jako się rzekło, służy do wyboru dysku, z którego ma się odbyć start systemu. Wyboru dokonuje się albo klawiszami kursora (strzałki góra/dół), albo wciskając klawisz z jedną z liter widniejących z lewej strony ekranu. Po każdej zmianie komputer próbuje się skomunikować z wybranym napędem i wypisuje krótką informację na jego temat:

  • NO RESPONSE - oznacza, że system nie doczekał się odpowiedzi od napędu; dysk nie jest podłączony.
  • ULTRA - oznacza, że napęd odpowiedział i że jest to stacja dysków zgodna z US Doublerem.
  • XF-551 - oznacza, że napęd odpowiedział i że jest to stacja dysków zgodna (pod względem protokołu transmisji) z CA-2001, IndusGT lub LDW 2000 Super (z załadowanym programem Synchromesh), albo XF-551.
  • PIO - napęd odpowiedział, ale nie jest to urządzenie szeregowe obsługiwane przez SIO, lecz urządzenie równoległe PIO, prawdopodobnie partycja twardego dysku.
  • brak jakiejkolwiek notki świadczy, że napęd odpowiedział i jest to zwykła stacja dysków.

Jeśli tryb przyspieszonej transmisji jest z jakichś względów niepożądany, można go wyłączyć wcisnąwszy klawisz "T". Wybór dysku zatwierdza się wciśnieciem klawisza RETURN. Powoduje to opuszczenie menu i kontynuację inicjowania systemu.

Menu korzysta w stu procentach z urządzenia "E:", tak więc powinno bez problemu wyświetlać się i działać nawet, jeśliby ktoś podłączył np. kartę graficzną przez interfejs równoległy, a ta zainstalowałaby urządzenie systemowe zgodne z "E:". Starałem się też, żeby menu miało typowy dla produktów Atari, powściągliwy styl - za wzór posłużył "klasyczny" DOS 2.5.

3) Start systemu

Istnieje też drobna - ale dość łatwo zauważalna - różnica w dalszym przebiegu startu komputera. Jeśli domyślna stacja dysków (D1:) nie jest podłączona i gotowa do pracy, albo jeśli użytkownik wybrał z menu startowego napęd, który nie jest podłączony (a wolno mu to zrobić, jeśli ma takie życzenie), wtedy zaczyna się procedura poszukiwania pierwszego napędu gotowego do pracy. System próbuje się skomunikować kolejno z wszystkimi stacjami dysków po kolei, od domyślnej (lub wybranej z menu) poczynając, i na niej też, sprawdziwszy wszystkie, kończąc.

Powoduje to, że start komputera, do którego nie jest podłączona żadna stacja, i nie jest włożony żaden moduł ROM, który zabroniłby bootowania, trwa dość długo - przeszukanie wszystkich napędów trwa ok. 30 sekund.

4) Klawisze funkcyjne F1-F4

XL OS zawiera procedury obsługi klawiszy funkcyjnych F1-F4, których jednak nie ma na konsoli. Istnieją rozwiązania rozszerzające komputery XL/XE o te klawisze, nie biorą one jednak na ogół pod uwagę faktu, że procedura ich obsługi zawarta w XL OS koliduje z rozszerzeniami pamięci takimi jak np. w Atari 130XE. Mówiąc krótko, wciskanie niektórych kombinacji klawiszy F1-F4 powoduje niekontrolowane przełączenia banków pamięci 130XE, co może skutkować niespodziewanym zawieszaniem się systemu, i na ogół właśnie tym skutkuje.

Powodem jest to, że komputery 1200XL, 1400XL i 1450XLD mają na konsoli lampki sygnalizujące wybór pewnych funkcji klawiszami F1-F4. Lampki te podłączone są do bitów rejestru PORTB - tego samego, który w 130XE steruje rozszerzeniem pamięci. Procedura przerwania klawiatury wykrywszy fakt wciśnięcia którejś kombinacji klawiszy F1-F4 usiłuje oczywiście sterować tymi lampkami nie zdając sobie sprawy, że nie istnieją.

W nowym systemie zostało to poprawione: używanie klawiszy F1-F4 jest zupełnie bezpieczne i nie powoduje żadnych skutków ubocznych na komputerach z rozszerzeniem pamięci. Natomiast na komputerach bez rozszerzenia pamięci wszystko będzie działać po staremu - to znaczy przy braku rozszerzenia pamięci typu 130XE system zakłada, że bity PORTB sterują wymienionymi wyżej lampkami komputera 1200XL.


Programowanie


III. Uwagi na temat przerwań

Procedury obsługi przerwań dla trybu natywnego nie są tak proste do wymyślenia, jakby się to na pierwszy rzut oka wydawało. Przede wszystkim, z powodu niewielkiej ilości miejsca w ROM-ie, nie można sobie pozwolić na zduplikowanie wszystkich procedur obsługi przerwań i przygotowanie oddzielnego ich zestawu dla trybu natywnego. Dlatego rozdzieleniu ulegają jedynie procedury wstępne (czyli istnieją np. dwie oddzielne wersje procedury NMIFIRST, jedna dla trybu emulacji, a druga natywnego), główne procedury obsługi natomiast (np. SYSVBL) pozostają w jednej kopii i obsługują przerwania zarówno w trybie natywnym jak i w trybie emulacji.

Ogólne założenia dla systemowych procedur przerwań są następujące:

  1. wszystkie procedury przerwań wykonują się w banku 0 (PBR=0, DBR=0); systemowa procedura obsługi zeruje rejestr DBR, a potem przywraca jego wartość przy wyjściu z przerwania;
  2. wszystkie przerwania operują na "prawdziwej" stronie zerowej (adresy od $000000 do $0000FF); systemowa procedura obsługi zeruje rejestr D, a potem przywraca jego wartość przy wyjściu z przerwania;
  3. wszystkie przerwania operują na tym samym stosie, który używany jest przez program użytkownika;
  4. wszystkie procedury obsługi przerwań muszą się prawidłowo wykonywać w trybie emulacji;
  5. żadna z procedur przerwań nigdy nie przełącza CPU z trybu natywnego na emulacji albo odwrotnie (chodzi o to, żeby program użytkownika przez cały czas miał pełną kontrolę nad trybem pracy CPU); wyjątkiem są przerwania programowe COP, które mogą przełączać tryby pracy CPU zależnie od potrzeb;
  6. ten sam kod powrotny nadaje się zarówno dla przerwań w trybie natywnym jak i emulacji; to jest konieczność dla zachowania kompatybilności z przejmującymi wektory przerwań nakładkami na system, nad którymi OS nie ma pełnej kontroli (patrz niżej);

Wady podsystemu przerwań opracowanego wg. powyższych założeń:

  1. zwiększone obciążenie przerwań w trybie natywnym; kontekst CPU musi zostać przechowany na stosie bez względu na wszystko, a 65C816 ma o wiele więcej rejestrów i stanów niż 6502. W przypadku DLI nie wszystko musi (a nawet nie wszystko może) zostać zapisane na stosie, ale procedura obsługi musi być uruchamiana przy dobrze określonym stanie procesora; ustawienie procesora w ten stan również kosztuje nieco cykli maszynowych wstępnej procedury obsługi (z drugiej strony, przełączenie CPU w tryb natywny zwiększa obciążenie przerwania VBL o ok. 0,3 promila, co jest niczym w porównaniu z 2,5 procenta, które zabiera druga faza SYSVBL);
  2. główne procedury obsługi przerwań nie są optymalne, bo ze względu na kompatybilność z trybem emulacji muszą być napisane w czysto ośmiobitowym kodzie;

Ma to jednak też pewne zalety:

  1. oszczędność miejsca w ROM-ie;
  2. kompatybilność ze starymi nakładkami systemowymi, które przejmują wektory przerwań; np. program przejmujący opóźnione przerwanie VBL może zakończyć jego obługę skokiem do EXITVBL, ale równie dobrze może wykonać procedurę identyczną z EXITVBL nie skoczywszy do systemu - obecne rozwiązanie systemu przerwań gwarantuje, że przerwanie będzie nadal prawidłowo obsługiwane, nawet jeśli program użytkownika przełączy CPU w tryb natywny;
  3. stabilne obciążenie przerwań w trybie pracy CPU wybranym przez użytkownika: system nie dokonuje cyklicznych przełączeń trybu pracy CPU, dzięki czemu możliwa jest precyzyjniejsza ocena czasu CPU pozostającego do dyspozycji programu (ważne w grach i demach);
  4. użytkownik może używać w swoim programie tej samej procedury obsługi przerwania dla obu trybów;

Z drugiej strony obciążenie przerwań w trybie emulacji jest cokolwiek zredukowane dzięki zastosowaniu nowych rozkazów i trybów adresowania. Na przykład procedura obsługi NMI zajmuje 32 cykle na 6502, ale tylko 26 cykli na 65C816. Podobnie procedura EXITVBL została skrócona z 23 do 19 cykli, a dochodzą do tego też oszczędności wewnątrz samej procedury SYSVBL. To wszystko nie równoważy zwiększonego obciążenia w trybie natywnym, niemniej nieco je redukuje.

Uwagi na temat DLI

DLI jest szczególnym przypadkiem, bo jest to przerwanie krytyczne czasowo. Jak twierdzą niektóre żrodła, jedna linia obrazu "zawiera" tylko 104 cykle CPU, a wobec tego obciążenie DLI kodem wstępnym o długości 94 cykli - opcja "zapisz wszystko" - nie jest możliwością, jaką można byłoby serio rozważać na dłuższą metę.

Z wyżej wyłuszczonego powodu procedura obsługi DLI jest uruchamiana przy nie do końca zdefiniowanym stanie CPU. Rejestry PBR i DBR są ustawione na zero, a rozmiar akumulatora na osiem bitów. Rozmiar rejestrów indeksowych jest niezdefiniowany (8 albo 16 bitów), żaden z rejestrów nie jest też przechowany na stosie. Procedura musi się kończyć przez RTI, system operacyjny bierze przywrócenie zawartości DBR na siebie.

Uwaga: akumulator też nie jest przechowany na stosie, programista musi zadbać o to sam przed jego użyciem, i przywrócić pierwotną wartość przed wykonaniem się rozkazu RTI. Trzeba też mieć baczenie na fakt, iż użycie 16-bitowego akumulatora spowoduje, że procedura nie będzie działać w trybie emulacji!

Uwaga: rejestry X/Y nie są przechowane na stosie. Co więcej, ich rozmiar nie jest określony. Jeśli programista zamierza ich użyć, powinien najpierw zapisać je na stosie, a potem ustawić pożądany rozmiar. Przykłady:

; Przykład 1
; Użycie w DLI rejestru X o rozmiarze 8 bitów.
; Uwaga: trzeba zapisać OBYDWA rejestry indeksowe
; nawet jeśli używamy TYLKO JEDNEGO!!!

	rep #$10	;ustawienie obu rejestrów na 16 bitów
	phx		;zapis OBYDWU przed przełączeniem na 8 bitów
	phy
	sep #$10	;przełączenie
	...
	kod
	...
	rep #$10	;przełączenie z powrotem do pełnego rozmiaru
	ply
	plx
	rti

Powód, dla którego należy przełączyć rejestry X/Y najpierw na 16 bitów jest taki, że rozmiar tych rejestrów nie jest określony w momencie wejścia do procedury obsługi przerwania DLI (patrz wyżej). Pominięcie rozkazów REP zaoszczędziłoby 10 cykli, jeśli byłoby pewne, że w momencie wystąpienia przerwania rejestry są ośmiobitowe (2 razy po 3 cykle na rozkazy REP i 4 razy po cyklu na rozkazy PHX/PHY i PLX/PLY); ale jeśli ten warunek NIE jest spełniony, rozkazy PLY/PLX na końcu procedury zdejmą ze stosu niewłaściwą liczbę bajtów, co spowoduje natychmiastowy zwis systemu.

; Przykład 2
; Użycie rejestru X o rozmiarze 16 bitów.
; W tym wypadku wystarczy zapisać na stos
; tylko te rejestry, których się użyje.
; Uwaga: ten kod nie będzie działał w
; trybie emulacji!

	rep #$10
	phx
	...
	kod
	...
	plx
	rti

Podobnie, jeśli programista ma zamiar użyć rejestrów na stronie zerowej, będzie najprawdopodobniej musiał zapisać na stos i wyzerować rejestr D. To się robi tak:

; Przykład 3

	phd		;zapisz rejestr D
	pea $0000	;wyzeruj go
	pld
	...
	kod
	...
	pld
	rti

; Przykład 4
; Tu oszczędzamy 5 cykli, jeśli i tak używamy do
; czegoś 16-bitowego akumulatora.

	rep #$20
	pha
	phd
	lda #$0000
	tcd
	...
	kod
	...
	pld
	pla
	rti

Niemniej zapisywania i resetowania rejestru D można uniknąć, jeśli:

  1. procedura przerwania nie używa rejestrów na stronie zerowej;
  2. procedura przerwania używa rejestrów strony zerowej za pośrednictwem absolutnego lub absolutnego długiego trybu adresowania;
  3. program zakłada sobie prywatną stronę zerową, a procedura przerwania korzysta tylko z niej;

To ostatnie podejście jest przypuszczalnie najlepsze, przynajmniej tak długo, jak nie mamy systemu z wieloprocesowością.

Uwagi na temat VBL

W trybie natywnym procedura obsługi VBL jest wykonywana z D=0, DBR=0 i PBR=0. Wszystkie rejestry są zapisane na stosie za wyjątkiem starszego bajtu akumulatora: jeśli programista zamierza użyć 16-bitowego akumulatora albo rozkazu XBA we własnej procedurze obsługi, musi najpierw zachować wartość całego akumulatora na stosie, a potem przywrócić ją przy wyjściu.

Szczyt stosu wygląda tak samo w trybie emulacji i natywnym: na samej górze leży ośmiobitowy rejestr Y, potem idąc w głąb stosu znajdują się ośmiobitowy rejestr X oraz ośmiobitowy akumulator, rejestr znaczników P oraz szesnastobitowy adres powrotny.

Ale w trybie natywnym to nie jest koniec zgromadzonych na stosie danych, bo pod spodem odłożone są wartości dodatkowych rejestrów (w tym pełne wartości rejestrów X i Y), 24-bitowy adres powrotny itd. Wszystko to jest zdejmowane ze stosu PO wykonaniu się procedury EXITVBL.

Uwagi na temat IRQ

W trybie natywnym procedura obsługi IRQ jest wykonywana z D=0, DBR=0 i PBR=0. Wszystkie rejestry są zapisane na stosie za wyjątkiem starszego bajtu akumulatora: jeśli programista zamierza użyć 16-bitowego akumulatora albo rozkazu XBA we własnej procedurze obsługi, musi najpierw zachować wartość całego akumulatora na stosie, a potem przywrócić ją przy wyjściu.

Szczyt stosu wygląda tak samo w trybie emulacji i natywnym: na samej górze leży rejestr znaczników P, a pod nim szesnastobitowy adres powrotny.

Ale w trybie natywnym to nie jest koniec zgromadzonych na stosie danych, bo pod spodem odłożone są wartości dodatkowych rejestrów (w tym pełne wartości rejestrów X i Y), 24-bitowy adres powrotny itd. Wszystko to jest zdejmowane ze stosu PO wykonaniu się rozkazu RTI kończącego obsługę przerwania.

Czasy odpowiedzi na przerwanie

Czasy wykonywania się wstępnych i końcowych procedur przerwań, mierzone w cyklach CPU, w porównaniu do XL OS. Czas dla NMI jest liczony od momentu przyjęcia przerwania przez procesor do chwili wejścia do głównej procedury obsługi (wskazywanej przez wektory DLIV i VVBLKI); oraz od zakończenia rozkazu RTI do rzeczywistego powrotu z przerwania.

Czas dla IRQ jest mierzony od momentu przyjęcia przerwania przez procesor do chwili wejścia do procedury rozpoznania źrodła przerwania IRQ (SINRDYI); oraz od zakończenia rozkazu RTI do rzeczywistego powrotu z przerwania.

XL OSTryb
emulacji
Tryb
natywny
DLI18/018/048/12
VBL38/032/098/30
IRQ14/012/063/30

Zauważmy, że w trybie natywnym zarówno przyjęcie przerwania, jak i RTI zajmują po cykl więcej, i ta różnica jest tu już uwzględniona.

Trzeba też pamiętać, że zarówno NMI jak i IRQ mają dodatkowe, "główne" wektory w pamięci RAM, które to wektory wskazują wstępne procedury obsługi przerwania znajdujące się w ROM-ie. Skok przez te wektory dodaje po 6 cykli do początku obsługi przerwania i ten dodatkowy czas jest tu już uwzględniony (gdyby takie wektory istniały w XL OS, czasy dla XL OS wynosiłyby 23, 42 i 19 cykli odpowiednio dla DLI, VBL i IRQ).

IV. Nowy mechanizm wywoływania systemu

Stary mechanizm wywoływania systemu operacyjnego, zaimplementowany w XL OS, który bazuje na tablicy skoków i wywołaniach przez JSR, ma niestety pewnie ograniczenie, które czyni jego użycie problematycznym w programach pisanych dla 65C816, a umieszczających swój kod w pamięci powyżej pierwszych 64k.

Mianowicie, rozkaz JSR ma szesnastobitowy argument, w związku z czym skokiem JSR nie można przekroczyć granicy 64k. W efekcie skok JSR $E459 osiągnie pożądany adres, tj. $00E459, tylko wtedy, kiedy rozkaz znajduje się w pierwszych 64 kilobajtach pamięci (a na 6502 ten warunek jest zawsze spełniony). Ale kiedy rozkaz taki znajdzie się w banku nr 1, skok zostanie wykonany pod $01E459, czyli nie tam, gdzie powinien.

Z drugiej strony 65C816 oferuje rozkaz JSL, który ma 24-bitowy argument i zapisuje na stosie 24-bitowy adres powrotny. Niestety, procedury znajdujące się w ROM-ie kończą się zwykłym, 16-bitowym rozkazem RTS, i nie można tego zmienić, bo trzeba utrzymywać kompatybilność ze starymi programami. Z tego powodu rozkaz JSL nie nadaje się do wywoływania funkcji systemu.

Oczywiście rozwiązaniem mogłaby być alternatywna tablica skoków zgodna z "długimi" skokami JSL. Tyle że szkoda na to miejsca w ROM-ie, a poza tym tablica skoków nie jest w ogóle rozwiązaniem najszczęśliwszym, bo nie da się przejąć wywołań systemu jeśli są wektorowane przez ROM.

Nowa metoda wywołań

Nowa metoda wykorzystuje niemaskowalne przerwanie programowe wywoływane rozkazem COP, który spełnia podobną funkcję, jak rozkaz TRAP na Motoroli 68k. Rozkaz COP przyjmuje jednobajtową stałą jako argument natychmiastowy. Rozkazy o argumentach z zakresu od $80 do $FF są zarezerwowane do przyszłych zastosowań przez producenta procesora, reszta natomiast, tj. argumenty z zakresu $00-$7F, jest dostępna naszej definicji.

Nowe wektory systemowe w pamięci RAM

Handler przerwania COP znajdujący się w pamięci ROM definiuje pięć nowych wektorów w pamięci, większość z nich jest 24-bitowa. Są to:

VCOPE $000251-$000252 WORD
VCOPN $000256-$000258 LONG

Dwa wektory przerwania COP, odpowiednio dla trybu emulacji i natywnego. Pierwszy z nich nie jest na razie używany, wskazuje RTI. Przyczyna tego jest taka, że w trybie emulacji nowy mechanizm wywoływania systemu nie jest potrzebny: programista może używać starego (skoków JSR), bo w trybie emulacji i tak możliwość uruchamiania kodu w nowych obszarach pamięci jest mocno ograniczona.

Drugi wektor, VCOPN, wskazuje na handler systemowy. Jeśli programista zmienia wartość tego wektora, to swój kod musi zakończyć albo przez skok JMP pod stary adres, albo przez RTI.

VCOP0 $000262-$000264 LONG
VCOPU $000265-$000267 LONG
VCOPC $000268-$00026a LONG

To są wektory "drugiego stopnia", wywoływane z wnętrza systemowego handlera COP. Kod wskazywany przez nie jest wywoływany długim skokiem JSL i musi się kończyć przez RTL (albo skok JMP/JML pod stary adres).

Pierwszy z wektorów jest używany, kiedy wykonuje się rozkaz COP #$00. Rozkaz ten jest zarezerwowany do użycia przez system operacyjny, szczegóły poniżej.

Drugi wektor jest używany, kiedy wykonuje się rozkaz COP z argumentem z zakresu od $01 do $7F. Trzeci wektor jest przeznaczony do wywołania, gdy wykonuje się "zarezerwowany" rozkaz COP, czyli z argumentem z zakresu od $80 do $FF.

W momencie skoku przez te wektory 24-bitowy wskaźnik znajdujący się pod adresem $000018 wskazuje na argument rozkazu COP (tj., jeśli wykonuje się rozkaz COP #$00, wskaźnik wskazuje jego argument, czyli część oznaczoną mnemonicznie jako "#$00").

Wszystkie wektory drugiego stopnia wywoływane są w trybie natywnym, z D=0, PBR=0, DBR=0 i rejestrami ustawionymi na 16 bitów. Zawartość rejestrów jest przechowywana przez handler i powinna być taka sama, jak w momencie wywołania rozkazu COP (za wyjątkiem VCOP0, gdzie rejestry zawierają wartości umieszczone tam przez XL OS). Handler pierwszego stopnia (wskazywany przez VCOPN) odpowiada za przywrócenie kontekstu CPU do stanu sprzed wykonania się rozkau COP.

Specjalne znaczenie rozkazów COP #$00 i COP #$01

Rozkaz COP #$00 służy do emulowania funkcji systemowych XL OS. Handler tego przerwania jako parametr przyjmuje 16-bitowy adres procedury wewnątrz pierwszych 64k, wywołuje ten adres przez JSR, a potem zwraca wynik do programu wywołującego. Zarówno zawartość rejestrów A/X/Y, jak i bity rejestru P zawierają wartości umieszczone tam przez wywołaną procedurę. Jedynie bity MX rejestru P są ustawione na wartość jaką miały przed wywołaniem COP #$00.

Oto przykład wywołania funkcji systemu tą metodą:

	sep #$30	;ustaw rejestry na osiem bitów
	ldx #$10	;IOCB #1
	lda #$0c	;rozkaz: CLOSE
	sta >iccmd,x	;zapisz do IOCB
	pea jciomain	;zapisz na stosie adres funkcji systemu
	cop #$00	;wywołanie
	pla		;zdejmij zbędny już adres ze stosu
	pla

Wywołanie przez wektor CIO:

	rep #$20	;akumulator na 16-bitów
	lda $e400	;wektor CIO: otwarcie edytora E:
	inc		;wektor jest zmniejszony o 1, trzeba skorygować
	pha		;gotowa wartość na stos
	cop #$00	;wywołanie
	pla		;zbędny parametr usuwamy ze stosu

Wywołanie procedury PUT przez kanał IOCB #1:

	rep #$20	;akumlator na 16 bitów
	sep #$10	;X/Y na 8 bitów
	ldx #$10	;IOCB #1
	lda icputb,x	;pobierz wektor
	inc		;zwiększ o 1
	pha		;na stos
	sep #$20	;akumulator na 8 bitów
	lda data	;dana do wysłania
	cop #$00	;wywołanie systemu
	rep #$20	;akumulator na 16 bitów
	pla		;usunięcie zbędnego argumentu

To jest jedyna bezpieczna metoda wywoływania funkcji XL OS w trybie natywnym CPU.

Tradycyjną metodą można wywoływać funkcje ROM-u *tylko* w trybie emulacji. Nawet jeśli procedury zawarte w ROM-ie powinny działać tak samo w obu trybach, nie mogę jednak zagwarantować tego samego w przypadku zewnętrznych sterowników urządzeń, zwłaszcza DOS-u. Mogą one zawierać kod, który nie będzie kompatybilny z trybem natywnym CPU.

Rozkaz COP #$01 służy do wywoływania rezydujących w ROM-ie funkcji, które nie mają odpowiednika w XL OS. W tej chwili przez COP #$01 można wywoływać funkcje zarządzania pamięcią.

V. Nowe funkcje SIO

Istnienie większości nowych funkcji można sprawdzić w pliku @:SYSDEF. Poleganie przy tym na numerze wersji ROM-u raczej nie jest zalecane - wszelkie uwagi poniższe o tym, że funkcja jest dostępna od tej czy tamtej wersji, mają tylko charakter informacyjny.

Począwszy od wersji BB 02.08 SIO jest w stanie zapisywać dane (np. sektory dyskietki) bezpośrednio w dodatkowej pamięci powyżej adresu $00FFFF, oraz odczytywać je bezpośrednio z niej. Blok DCB został rozszerzony do 16 bajtów, najstarszy bajt adresu bufora znajduje się pod adresem $00030E.

Jednak, dla utrzymania zgodności z dotychczasowym oprogramowaniem, a już zwłaszcza z dotychczasowymi sterownikami urządzeń podłączanych do szyny równoległej, wpisanie pod $000304/5/E 24-bitowego adresu nie da pożądanego wyniku; jeśliby bowiem urządzenie brało pod uwagę tylko 16 najmłodszych bitów adresu ignorując najstarszy bajt wpisany pod $00030E, wtedy - przy odczycie - dane zostałyby umieszczone nie tam, gdzie trzeba. Musi więc istnieć mechanizm, który zapobiega tego typu nieporozumieniom.

W tym celu SIO definiuje trzy nowe urządzenia wirtualne, o kodach jak następuje:

  • $B1 (= $31 + $80) - stacja dysków
  • $C0 (= $40 + $80) - drukarka
  • $D0 (= $50 + $80) - RS-232C

Wywołanie urządzenia z takim kodem w DDEVIC powiadamia sterownik SIO, że adres bufora w DCB jest 24-bitowy i że najstarszy bajt adresu jest pod $00030E (w przeciwnym wypadku SIO zakłada, że najstarszy bajt adresu to 0). Poza tym działanie urządzeń wirtualnych jest identyczne, jak tradycyjnych (odpowiednio $31, $40 i $50), a kod urządzenia jest przed wysłaniem na port szeregowy przekładany na kod rzeczywisty.

Przyjmując komendę do wykonania SIO w żaden sposób nie sprawdza, czy dodatkowa pamięć w ogóle istnieje - zakłada się, że program sam stwierdzi jej istnienie (choćby za pomocą funkcji alokacji pamięci) przed próbą odczytu do niej danych.

VI. Nowe funkcje CIO

1.

Począwszy od wersji BB 02.03 CIO akceptuje 0 (zero) jako numer urządzenia, np. nazwa "D0:" zostanie zdekodowana jako "urządzenie D: nr 0". W poprzednich wersjach systemu było to po cichu zmieniane na "D1:". To rozszerzenie pochodzi z ROM-u przygotowanego przez Atari dla komputera Atari 1450XLD.

2.

Począwszy od wersji BB 02.05 umieszczony w ROM-ie interfejs CIO ma nową funkcję wyszukiwania pierwszego wolnego (zamkniętego) kanału IOCB. Wywołanie:

	ldx #-1
	jsr jciomain

zwraca status w rejestrze Y (1 - sukces lub ujemny kod błędu), a w rejestrze X pomnożony przez 16 numer znalezionego kanału.

3.

Począwszy od wersji BB 02.08 umieszczony w ROM-ie sterownik klawiatury rozpoznaje następujące funkcje XIO:

  • XIO 16,#1,4,0,"K:" - wyłącza klik klawiatury
  • XIO 16,#1,4,1,"K:" - włącza klik klawiatury
  • XIO 16,#1,4,255,"K:" - zwraca (w ICAX3) informację na temat kliku klawiatury (0 - wyłączony)
  • XIO 19,#1,4,0,"K:" - generuje klik klawiatury, jeśli ten jest włączony, w przeciwnym wypadku nic nie robi

4.

Od wersji BB 02.08 zawarty w ROM-ie sterownik klawiatury ma nową funkcję "skanowania" stanu klawiszy. W tym trybie wywołanie funkcji GET dla klawiatury nie powoduje "ugrzęźnięcia" programu w pętli oczekującej na naciśnięcie klawisza, lecz następuje natychmiastowy powrót do miejsca wywołania niezależnie od tego, czy użytkownik nacisnął jakiś klawisz, czy nie.

Taki tryb pracy klawiatury włącza się przez otwarcie kanału IOCB z ustawionym bitem 1 bajtu ICAX2; na przykład:

OPEN #1,4,1,"K:"

Gdy jakiś klawisz był naciśnięty, GET #1 zwraca jego kod ASCII w akumulatorze i status 1 w rejestrze Y. W przeciwnym wypadku, gdy żaden klawisz nie był naciśnięty, w rejestrze Y umieszczany jest kod statusu -78 (178, $B2), a wartość akumulatora jest bez znaczenia.

Ustawienie tego trybu dla jednego kanału IOCB nie ma wpływu na inne, ani też na funkcjonowanie edytora ekranowego ("E:").

Niestety, tego trybu nie da się użyć spod BASIC-a, bo -78 w rejestrze Y jest przez interpreter BASIC-a traktowane jako błąd i powoduje przerwanie wykonywania programu.

VII. Urządzenie "N:"

Od wersji BB 01.93 w pamięci ROM znajduje się sterownik urządzenia "N:" (null). Ma ono następujące cechy:

  • przy odczycie urządzenie zachowuje się w jeden z trzech sposobów zależnie od tego, czy otwarto je jako "N:", "N2:", czy "N3:" (patrz tabela);
  • przy zapisie urządzenie akceptuje każdą ilość danych nie zapisując ich nigdzie;
  • brak jest operacji specjalnych;
NazwaFunkcja
"N:"lub"N1:"Przy odczycie urządzenie zachowuje się jak plik o długości 0 bajtów, czyli zawsze zwraca błąd 136 (EOF). Jest to odpowiednik /dev/null Unixa.
"N2:"Przy odczycie urządzenie zachowuje się jak plik o nieskończonej długości zawierający same zera. Jest to odpowiednik /dev/zero Unixa.
"N3:"Przy odczycie urządzenie zachowuje się jak plik o nieskończonej długości i losowej zawartości. Jest to odpowiednik /dev/random Unixa.

VIII. Urządzenie "@:"

Urządzenie "@:" jest pseudodyskiem zawierającym jeden plik o nazwie "SYSDEF"; plik ten ma długość 128 bajtów. Zawiera garść informacji o systemie na użytek programów, które chciałyby się np. dowiedzieć, czy można używać kodu 65C816 i czy bezpieczne jest używanie trybu natywnego.

Zawartość pliku "@:SYSDEF" jest następująca:

BajtZawartość
0-2Data rewizji systemu: dzień, miesiąc, dwie ostatnie cyfry roku ($23 $12 $04 = 23.XII.2004.)
3Opcja (0)
4-9Numer wersji systemu ($42 $42 $00 $00 $02 $04 = BB 000002.04)
10Kod CPU (0 - 6502, 1 - 65C02, 2 - 65C816). Kody poniżej 2 są na wypadek, gdyby komuś przyszło do głowy zaimplementować to na zwykłym systemie.
11Zarezerwowane na kod koprocesora (na razie 0 - brak)
12Liczba dodatkowych banków pamięci po 64k
13Natywne procedury przerwań:
* bit 0 = 1 - dostępne
Jeśli bajt 10 jest równy dwa, a tu jest zero, to nie można przełączać procesora w tryb natywny przy włączonych przerwaniach.
14Dostępność procedur zarządzania pamięcią:
* bit 0 = 1 - dostępne
To pole i następne zawierają poprawne wartości dopiero od wersji 2.05 systemu.
15Rozszerzenia SIO:
* bit 0 = 1 - rozszerzony blok DCB (16 bajtów)
* bit 1 = 1 - SIO jest w stanie czytać/zapisywać dane do/z dodatkowej pamięci
16Szybkie procedury szeregowe dla stacji dysków:
* bit 0 = 1 - US Doubler
* bit 1 = 1 - XF-551/Indus GT
17Rozszerzenia CIO:
* bit 0 = 1 - funkcja wyszukiwania zamkniętych kanałów CIO dostępna
18Maksymalny numer kanału CIO pomnożony przez 16 ($70)
19-20Mapa bitowa dostępnych funkcji XIO dla urządzenia E: Kolejne bity, jeśli są ustawione, oznaczają dostępność kolejnych funkcji począwszy od numeru 16:
BitZnaczenie
01 = XIO 16 dostępne
11 = XIO 17 dostępne
21 = XIO 18 dostępne
31 = XIO 19 dostępne
41 = XIO 20 dostepne
51 = XIO 21 dostępne
61 = XIO 22 dostępne
71 = XIO 23 dostępne
81 = XIO 24 dostępne
91 = XIO 25 dostępne
101 = XIO 26 dostępne
111 = XIO 27 dostępne
121 = XIO 28 dostępne
131 = XIO 29 dostępne
141 = XIO 30 dostępne
151 = XIO 31 dostępne
21-22Jak wyżej dla urządzenia S:
23-24Jak wyżej dla urządzenia K:
25-26Jak wyżej dla urządzenia P:
27-28Jak wyżej dla urządzenia N:
29-30Jak wyżej dla urządzenia @:
31-32Zarezerwowane

W wypadku zupełnego braku tego urządzenia albo tego pliku (błąd 138, 170 albo podobny przy otwieraniu "@:SYSDEF"), wartości bajtów od 10 do 127 trzeba przyjąć jako zera.

Pozostałe bajty na razie są zarezerwowane i czytają się jako zera.

Odczyt bajtów może być sekwencyjny, można też przesunąć znacznik odczytu funkcją nr 37 działającą tak, jak SEEK (czy też POINT) w SpartaDOS X, i odczytać konkretny bajt. Ustawienie znacznika poza końcem pliku powoduje błąd przy następnym odczycie. Funkcja XIO 37 musi być zawsze dostępna dla tego urządzenia.

IX. Funkcje zarządzania pamięcią

Począwszy od wersji 2.04 system definiuje trzy funkcje zarządzania pamięcią. Pierwsza z nich - kpsize - opisana jest w dalszej części dokumentu. Druga - kmalloc - służy do zajmowania (alokowania) bloków pamięci, trzecia - kfree - do ich zwalniania.

Prototypy funkcji w C wyglądałyby następująco:

unsigned int kpsize(void);

int kmalloc(int size, unsigned int mode);

int kfree(unsigned int page);

Jednostką miary pamięci, którą posługują się te funkcje, nie jest bajt, lecz strona. Rozmiar tej strony podaje funkcja kpsize. W obecnej implementacji jest to 256 bajtów - a to niewiele, zważywszy, że programy zarządzania pamięcią w systemach budowanych dla np. m68k potrafią stronicować pamięć po 8 albo 16 kilobajtów.

W związku z taką organizacją funkcja kmalloc nie przyjmuje jako parametru size liczby bajtów do pozyskania z systemu, ale liczbę stron. Zwraca też nie adres początku bloku, ale numer strony, od którego się on zaczyna. Tak samo numer strony przyjmuje jako parametr page funkcja kfree. Przy bieżącej implementacji - gdzie strona to 256 bajtów - "numer strony" są to po prostu dwa najstarsze bajty adresu zaalokowanego bloku pamięci.

Jeśli funkcji kmalloc podamy -1 (czyli $FFFF) jako size, to nic nie będzie alokować, a jedynie obliczy i zwróci liczbę aktualnie wolnych, 256-bajtowych stron pamięci.

Stronicowanie powoduje niewielkie straty pamięci (do 255 bajtów na zaalokowany blok), ale ma tę zaletę, że adres mieści się na szesnastu bitach, co znakomicie upraszcza przekazywanie parametrów do funkcji, odbieranie od niej wyników oraz jej wewnętrzne działanie, a także wydatnie upraszcza i skraca mapę alokacji pamięci.

Gdy już mowa o mapie, liczy ona w obecnej implementacji 64 sloty (42 w starszych wersjach OS-u). Oznacza to, że system może ogólnie zarządzać sześćdziesięcioma czterema blokami pamięci o dowolnej liczbie stron każdy. Jeśli program będzie chciał zająć 32 kB (128 stron) pamięci wywołując 128 razy funkcję kmalloc, to za 65 razem zwróci ona błąd braku pamięci - mimo że zajęte jest dopiero 16 kilobajtów! Dlatego funkcji kmalloc trzeba używać oszczędnie: w danym przykładzie najlepiej jest zająć całe 32k za jednym zamachem - to jest za jednym wywołaniem kmalloc.

Parametr mode funkcji kmalloc modyfikuje jej działanie zależnie od potrzeb. Jest to 16 bitów - znaczników włączających i wyłączających kolejne funkcje. Obecnie zdefiniowane są następujące bity:

BitEtykietaOpis
0KM_RES Jeśli ten bit jest ustawiony, to blok pamięci staje się "rezydentny" - nie da się go zwolnić przez kfree. Zwolniony zostaje dopiero po wciśnięciu klawisza RESET.
1KM_RPR Jeśli ten bit jest ustawiony w połączeniu z ustawieniem bitu KM_RES, to rezydentny blok pamięci staje się "odporny na reset": zwalnia go dopiero zimny start.
2KM_A64 Ustawienie tego bitu powoduje zaalokowanie bloku nie w pierwszym wolnym miejscu, ale na pierwszej wolnej granicy bloku 64k.
3KM_EXE Ustawienie tego bitu oznacza, że alokuje się pamięć do załadowania do niej kodu programu. Bloki mniejsze niż 64k są tak alokowane, żeby mieściły się w całości w segmencie 64k. Bloki większe są automatycznie dorównywane do najblizszej granicy 64k.
7KM_CLR Ustawienie tego bitu powoduje, że blok pamięci jest po alokacji zerowany.

Pozostałe bity argumentu mode są zarezerwowane i powinny być skasowane dla kompatybilności.

Funkcja kfree przyjmuje jako parametr numer strony zwrócony przez kmalloc. Jeśli od strony o podanym numerze zaczyna się zaalokowany i nierezydentny blok pamięci, to jest zwalniany.

Opisane wyżej funkcje wywołuje się przerwaniem COP #$01 przekazując parametry na stosie:

	rep #$30
	pea $0000	;mode
	pea $0100	;size (256 stron = 64k)
	pea $0001	;kod funkcji kmalloc
	cop #$01
	plx		;usuń niepotrzebne argumenty
	plx
	plx

Po powrocie funkcja zwraca status w rejestrze Y. Jeśli rejestr Y zawiera wartość dodatnią, to akumulator zawiera numer strony, od której zaczyna się zaalokowany blok (numer strony, czyli dwa najstarsze bajty adresu bloku). Jeśli rejestr Y zawiera wartość ujemną, oznacza to błąd i zawartość akumulatora nie ma wtedy żadnego znaczenia.

Użycie pozostałych funkcji jest podobne, z tym że kpsize nie wymaga żadnych parametrów. Kody funkcji są następujące:

  • $0000 - kpsize
  • $0001 - kmalloc
  • $0002 - kfree

Pozostałe kody są na razie zarezerwowane, ich wywołanie zwraca w rejestrze Y błąd -110 (w starszych wersjach systemu pod numerem $0003 była jeszcze jedna funkcja - kfreeall - ale od wersji 2.12 została usunięta jako niepotrzebna).

UWAGA. Wszystkie wymienione funkcje działają (1) tylko w trybie natywnym, (2) tylko na dodatkowej pamięci (adresy powyżej 65535) oraz (3) tylko wtedy, kiedy ta pamięć istnieje. Wywołania w trybie emulacji nie przynoszą żadnego efektu (handler przerwania COP dla trybu emulacji istnieje, ale składa się tylko z rozkazu RTI). W przypadu braku dodatkowej pamięci wszystkie funkcje zwracają ujemny kod błędu w rejestrze Y.

X. Zmiany w mapie pamięci

AdresRozmiarEtykietaOpis
$00024DBYTELOSEGM Zawiera najstarszy bajt adresu pierwszego, istniejącego fizycznie segmentu liniowej pamięci RAM ulokowanego ponad pierwszymi 64k.
$00024EBYTEHISEGM Zawiera liczbę istniejących fizycznie, dodatkowych segmentów pamięci liniowej oprócz pierwszych 64k. Zero oznacza, że dodatkowych banków nie ma. $FF oznacza, że dostępne jest pełne 16 MB pamięci adresowalnej liniowo (czyli że wszystkiego jest 256 banków po 64k).
$00024F
$000253
WORD
LONG
VABTE
VABTN
Wektory przerwania ABORT, odpowiednio dla trybu emulacji i natywnego. Oba wskazują na RTI.
$000251
$000256
WORD
LONG
VCOPE
VCOPN
Wektory przerwania COP, odpowiednio dla trybu emulacji i natywnego. Pierwszy z nich nie jest używany, wskazuje na RTI. Drugi wskazuje na systemową procedurę obsługi, która rozdziela obsługę rozkazu COP pomiędzy wektory VCOP0, VCOPU or VCOPC. Jeśli ten wektor ulega zmianie, to wskazywana nim procedura musi się kończyć albo przez JMP pod stary adres, albo przez RTI, jeśli zastępuje systemowy handler całkowicie.
$000259LONGVNMIN Główny wektor NMI dla trybu natywnego. Wskazuje na procedurę rozpoznania źrodła przerwania NMI.
$00025CLONGVIRQN Główny wektor IRQ dla trybu natywnego. Wskazuje na procedurę rozpoznania źrodła przerwania IRQ.
$00025FLONGVBRKN Wektor przerwania BRK dla trybu natywnego (w trybie emulacji BRK jest obsługiwane razem z innymi przerwaniami IRQ). Wskazuje na RTI.
$000262LONGVCOP0 Wektor obsługi rozkazu COP #$00. Skok pod wskazywany tu adres jest wykonywany rozkazem JSL, procedura musi się kończyć przez RTL. Wektor wskazuje procedurę systemową odpowiedzialną za emulowanie wywołań "starych" funkcji systemowych, tj. tych z XL OS. W momencie wywołania tej procedury wektor VTEMP $000018-$1a wskazuje argument rozkazu COP. Używanie tego wektora do własnych celów, innych niż zdefiniowane przez system operacyjny, jest raczej niewskazane.
$000262
$000268
LONG
LONG
VCOPU
VCOPC
VCOPU to wektor obsługi rozkazu COP z argumentami z zakresu od #$01 do #$7F. VCOPC - to samo dla argumentów z zakresu od #$80 do #$FF. Rola wektora VTEMP $000018 jest taka sama jak powyżej. Użycie rozkazów COP z argumentem z zakresu od $80 do $FF jest zarezerwowane przez producenta do przyszłych rozszerzeń funkcji procesora.
$00029FBYTEXMS Liczba dodatkowych banków pamięci po 16k dostępna w obszarze $4000-$7FFF.
$00030C
$00030D
BYTE
BYTE
DAUX3
DAUX4
Starsze słowo 32-bitowego numeru sektora (odpowiednio młodszy/starszy bajt)
$00030E
$00030F
BYTE
BYTE
DBFX1
DBFX2
DBFX1 to najstarszy bajt 24-bitowego adresu bufora dla operacji DCB. DBFX2 zarezerwowany, musi być równy zero.
$0003EDBYTENEWINI Import z ROM-u Atari 1450XLD: początek procedury inicjowania "na ciepło" handlera załadowanego z urządzenia PBI.
W wysokiej pamięciSTRUCTMEMTAB Tablica alokacji pamięci. W różnych wersjach OS-u położona w różnych miejscach. Jeśli dodatkowej pamięci nie ma (HIBANK = 0), tablica nie istnieje.

XI. Inne zmiany

Od wersji 2.10 CHARSET 2 został zmodyfikowany przez zmianę kształtów trzech ostatnich znaków o kodach ASCII 125, 126 i 127. Są to znaki kontrolne edytora ekranowego, odpowiednio CLR/HOME, DEL oraz TAB.

Nowe kształty to:

  • ATASCII 125: tylda (~)
  • ATASCII 126: lewa klamra ({)
  • ATASCII 127: prawa klamra (})

Po zmianie zachowują one swoją funkcję, to jest działają jak poprzednio, a wyświetlać je można tylko w sekwencji z poprzedzającym znakiem ESC (ASCII 27).

Kody ATASCII niestety nie pokrywają się z kodami ASCII tych znaków (lewa klamra - 123, prawa klamra - 125, tylda - 126). Zastosowanie kodów znanych z PC nie było możliwe, gdyż w CHARSET 2 kod ATASCII 123 jest już przypisany do niemieckiej litery "A umlaut". W celu poprawnego przeniesienia pliku tekstowego zawierającego te znaki trzeba dokonać konwersji (co i tak trzeba zrobić ze względu na inny kod końca linii w ASCII oraz w ATASCII).

XII. Kompatybilność

System będzie działał TYLKO z komputerami serii XL/XE, na maszynie z serii 400/800 nawet nie wystartuje.

Z punktu widzenia użytkownika są następujące zmiany:

  • usunięty został SELF TEST
  • usunięty został handler magnetofonu - nie można dokonać startu systemu z kasety
  • dodane zostało menu wyboru dysku, z którego komputer ma wystartować; żeby je uaktywnić, trzeba przy starcie systemu wcisnąć i przytrzymać klawisz START.
  • SELECT/RESET powoduje zimny start;
  • dla stacji zgodnych z US Doublerem, XF-551 i Indus GT automatycznie włączana jest szybka transmisja.
  • poprawione zostało kilka drobnych błędów i niedociągnięć, jakie były w XL OS.
  • wprowadzono większość zmian i poprawek, jakie znalazły się w Atari XL OS ver. 2.03.
  • nieco przyspieszone zostały procedury graficzne i edytora, oraz obsługa przerwań.
  • w procedurze bootowania dodano obsługę dysków z sektorem 512-bajtów oraz poszukiwanie pierwszego dysku gotowego do pracy.
  • wprowadzono możliwość bootowania z każdego dysku (a nie tylko z D1:).
  • poprawiono obsługę klawiszy funkcyjnych F1-F4 tak, żeby nie było konfliktu z rozszerzeniami pamięci.
  • rozszerzono CIO o nowe funkcje i sterowniki.
  • dodano procedury alokacji pamięci znajdującej się powyżej adresu $FFFF.
  • dodano procedury obsługi przerwań dla trybu natywnego 65C816.
  • dodano mechanizm wywoływania systemu za pomocą przerwań programowych COP.

Jednocześnie zostały zachowane takie rzeczy jak drugi generator znaków (CHARSET2) oraz procedury obsługi modułu 1090XL, bo mogą się jeszcze przydać.

Z punktu widzenia oprogramowania powinna zostać zachowana stuprocentowa zgodność z takimi i tylko takimi programami, które używają legalnych wejść do systemu (tablica skoków, tablice wektorów itd.). Programy, które odwołuja się do procedur i tablic systemowych bez pośrednictwa odpowiednich wektorów, będą się zawieszać dokładnie tak samo, jak na "starym" systemie od Atari 400/800.

Lekarstwem na to jest nałożenie łatek binarnych na program tak, żeby korzystał z tablicy skoków oraz wektorów w RAM-ie. Częstym przypadkiem - nagminnym w programach JBW - jest odwoływanie się bezpośrednim adresem do tablicy definicji klawiatury. Łatka polega tu na zmianie tego na odwołanie pośrednie przez wektor KEYDEFP ($79).

Lista zgodności z niektórymi programami jest tutaj.

Miłej zabawy

http://drac030.atari8.info © KMK
free counters