Programowanie: Użycie OS-a przy wyłączonym ROM-ie
From Atariki
| Wersja z dnia 01:27, 4 gru 2019 Mono (Dyskusja | wkład) (→Restrykcje pamięciowe) ← Previous diff |
Aktualna wersja Mono (Dyskusja | wkład) (→Przelotki - function not implemented) |
||
| Linia 1: | Linia 1: | ||
| - | Żeby swobodnie używać mechanizmów [[OS]]-a a przy tym mieć dostęp do całego [[RAM]]-u trzeba zadbać tylko o poprawne wykonanie przerwań będących w [[ROM]]-ie w sytuacji kiedy ten jest wyłączony. | + | Żeby swobodnie używać mechanizmów [[OS]]-a a przy tym mieć dostęp do całego [[RAM]]-u trzeba zadbać tylko o poprawne wykonanie procedur przerwań umieszczonych w [[ROM]]-ie w sytuacji kiedy ten jest wyłączony. |
| = Handler = | = Handler = | ||
| Linia 6: | Linia 6: | ||
| <pre> | <pre> | ||
| nmiint sec | nmiint sec | ||
| - | scs | + | .byte $24 ;BIT $18 ($18 to opcode CLC niżej) |
| irqint clc | irqint clc | ||
| + | |||
| + | ;wlaczenie OS ROM | ||
| + | |||
| + | inc PORTB ;$D301 | ||
| pha | pha | ||
| Linia 14: | Linia 18: | ||
| pha | pha | ||
| tsx | tsx | ||
| - | |||
| - | ;wlaczenie OS ROM | ||
| - | |||
| - | inc PORTB ;$D301 | ||
| ;odlozenie na stos danych dla powrotu z przerwania (RTI) | ;odlozenie na stos danych dla powrotu z przerwania (RTI) | ||
| Linia 34: | Linia 34: | ||
| jmp (IRQVEC) ;$FFFE | jmp (IRQVEC) ;$FFFE | ||
| - | iret ;wylaczenie OS ROM | + | iret pla |
| + | tax | ||
| + | pla | ||
| + | |||
| + | ;wylaczenie OS ROM | ||
| dec PORTB ;$D301 | dec PORTB ;$D301 | ||
| - | |||
| - | pla | ||
| - | tax | ||
| - | pla | ||
| rti | rti | ||
| </pre> | </pre> | ||
| Linia 72: | Linia 72: | ||
| = Działanie = | = Działanie = | ||
| - | W przypadku kiedy ROM jest włączony przerwanie obsługiwane jest przez standardowe procedury umieszczone w ROM (ponieważ wektory NMIVEC oraz IRQVEC znajdują się wtedy w obszarze ROM). | + | W przypadku kiedy OS ROM jest włączony przerwanie obsługiwane jest przez standardowe procedury umieszczone w systemie operacyjnym (ponieważ wektory NMIVEC oraz IRQVEC znajdują się wtedy w obszarze ROM). |
| - | Kiedy ROM jest odłączony wektor wejścia w przerwanie pobierany jest z NMIVEC lub IRQVEC, które znajdują się w RAM i wykonywana jest procedura przerwania nmiint lub irqint. | + | |
| - | Obydwie te procedury mają za zadanie włączenie ROM-u, wykonanie procedury obsługi przerwania według wektora znajdującego się już w ROM, oraz przywrócenie konfiguracji ROM po powrocie. | + | Kiedy OS ROM jest odłączony wektor wejścia w przerwanie pobierany jest z NMIVEC lub IRQVEC, które znajdują się w RAM i wykonywana jest procedura przerwania nmiint lub irqint zależnie od rodzaju zgłoszonego przerwania. |
| - | Odbywa się to poprzez zapalenie najmłodszego bitu PORTB (włączenie OS ROM), odłożenie na stos adresu powrotu do procedury iret oraz wartości rejestru F procesora odłożonego na stos w sekwencji wywołania przerwania. Zduplikowanie tej wartości jest niezbędne dla poprawnego działania procedur obsługi przerwań zachowanych w ROM, ponieważ testują one: | + | W obydwu przypadkach ma ona za zadanie włączenie ROM-u, wykonanie procedury obsługi przerwania według wektora znajdującego się już w ROM, oraz przywrócenie konfiguracji pamięci po powrocie. |
| + | Odbywa się to poprzez zapalenie najmłodszego bitu PORTB (włączenie OS ROM), odłożenie na stos adresu powrotu do procedury iret oraz zawartości rejestru stanu F procesora odłożonego na stos w sekwencji wywołania przerwania. Zduplikowanie tej wartości jest niezbędne dla poprawnego działania systemowych procedur obsługi przerwań (tylko wartość rejestru F odłożona na stosie zawiera poprawne wartości znaczników I i B), ponieważ testują one: | ||
| * czy przerwane zostało wykonanie przerwania IRQ (w przypadku obsługi przerwania NMI), | * czy przerwane zostało wykonanie przerwania IRQ (w przypadku obsługi przerwania NMI), | ||
| * czy przerwanie IRQ zostało zgłoszone przez układ I/O, czy może przerwanie zostało wywołane przez rozkaz BRK (w przypadku obsługi przerwania IRQ). | * czy przerwanie IRQ zostało zgłoszone przez układ I/O, czy może przerwanie zostało wywołane przez rozkaz BRK (w przypadku obsługi przerwania IRQ). | ||
| Po wykonaniu procedury z ROM sterowanie przekazywane jest do procedury iret, której jedynym zadaniem jest ponowne odtworzenie konfiguracji pamięci (odłączenie ROM). | Po wykonaniu procedury z ROM sterowanie przekazywane jest do procedury iret, której jedynym zadaniem jest ponowne odtworzenie konfiguracji pamięci (odłączenie ROM). | ||
| + | |||
| + | Podczas obsługi przerwania IRQ może się zdarzyć, że nadejdzie nowe zgłoszenie IRQ. W tej sytuacji, po powrocie z procedury obsługi bieżącego przerwania a jeszcze przed wykonaniem procedury iret, obsłużone zostanie nowe przerwanie za pomocą systemowej procedury zawartej w ROM. Dzieje się tak z powodu duplikacji rejestru F odkładanego na stos w procedurze irqint, w którym znacznik I jest zgaszony. Dopiero po zakończeniu obsługi wszystkich zgłoszonych przerwań następuje wykonanie procedury iret przywracającej konfigurację PORTB. | ||
| = Wywoływanie procedur OS = | = Wywoływanie procedur OS = | ||
| Linia 96: | Linia 99: | ||
| = Przelotki = | = Przelotki = | ||
| - | Wygodnym sposobem realizowania skoków do procedur OS jest zdefiniowanie tzw. "przelotek", które zadbają o konfigurację pamięci i jej odtworzenie już po wykonaniu skoku. | + | Wygodnym sposobem realizowania skoków do procedur OS jest zdefiniowanie tzw. "przelotek", które zadbają o konfigurację pamięci i jej odtworzenie po powrocie z procedury. |
| <b>UWAGA!</b> Takie "przelotki" analogicznie, jak procedura handlera przerwań, powinny również znajdować się poza obszarem, w którym może pojawić się ROM (patrz "Restrykcje pamięciowe"). | <b>UWAGA!</b> Takie "przelotki" analogicznie, jak procedura handlera przerwań, powinny również znajdować się poza obszarem, w którym może pojawić się ROM (patrz "Restrykcje pamięciowe"). | ||
| Linia 117: | Linia 120: | ||
| Nieco odmienna jest metoda wywoływania procedur dostępnych przez [[Tablice_wektor%C3%B3w_ROM|tablicę wektorów]], ponieważ wektory wskazują adres procedury zmniejszony o jeden i jako takie służą do wykonania skoku przez RTS: | Nieco odmienna jest metoda wywoływania procedur dostępnych przez [[Tablice_wektor%C3%B3w_ROM|tablicę wektorów]], ponieważ wektory wskazują adres procedury zmniejszony o jeden i jako takie służą do wykonania skoku przez RTS: | ||
| <pre> | <pre> | ||
| - | SIO_S_SPECIAL_jump: | + | CIO_S_SPECIAL_jump: |
| lda PORTB | lda PORTB | ||
| pha | pha | ||
| Linia 129: | Linia 132: | ||
| rts | rts | ||
| - | ?call lda $E410+$0A+1 | + | ?call lda $E410+$0A+1 ;tablica handlera S: wektor SPECIAL |
| pha | pha | ||
| lda $E410+$0A | lda $E410+$0A | ||
| Linia 135: | Linia 138: | ||
| rts | rts | ||
| </pre> | </pre> | ||
| - | Ta metoda powinna być używana również do wywołania procedury PUTBT dostępnej w rejestrze ICPUTB bloku IOCB. | + | Ta metoda powinna być używana również do wywołania procedury PUTBT dostępnej w rejestrze ICPUTB bloku IOCB n.p. |
| + | <pre> | ||
| + | ;IN: X-IOCB#*16, A-data | ||
| + | ;OUT: Y-status, N-error flag | ||
| + | CIO_PUTBT_jump: | ||
| + | tay | ||
| + | lda PORTB | ||
| + | pha | ||
| + | ora #%00000001 | ||
| + | sta PORTB | ||
| + | |||
| + | jsr ?call | ||
| + | |||
| + | pla | ||
| + | sta PORTB | ||
| + | cpy #0 | ||
| + | rts | ||
| + | |||
| + | ?call lda ICPUTB+1,x | ||
| + | pha | ||
| + | lda ICPUTB,x ;$0346 | ||
| + | pha | ||
| + | tya | ||
| + | ldy #$92 ;FUNCTION NOT IMPLEMENTED | ||
| + | rts | ||
| + | </pre> | ||
| = Rejestry OS w RAM = | = Rejestry OS w RAM = | ||
| - | Rejestry $00..$7F oraz $2xx i $3xx są to rejestry zarezerwowane dla potrzeb systemu operacyjnego. | + | Rejestry $00..$7F oraz $2xx i $3xx są zarezerwowane dla potrzeb systemu operacyjnego. |
| = DLI = | = DLI = | ||
| Linia 150: | Linia 178: | ||
| sec | sec | ||
| - | scs | + | .byte $24 ;BIT $18 |
| irqint clc | irqint clc | ||
| Linia 156: | Linia 184: | ||
| ... | ... | ||
| </pre> | </pre> | ||
| - | Należy jednak pamiętać, że po wejściu do procedury obsługi przez wektor VDSLST ($200) nie ma gwarancji że ROM jest włączony. Jeśli więc w procedurze obsługi przerwania DLI chcemy użyć jakiejś procedury z ROM należy osobiście zadbać o poprawne skonfigurowanie pamięci, oraz odtworzenie jej przed wyjściem z przerwania n.p. tak: | + | Należy jednak pamiętać, że wtedy po wejściu do procedury obsługi przez wektor VDSLST ($200) nie ma gwarancji że ROM jest włączony. Jeśli więc w procedurze obsługi przerwania DLI chcemy użyć jakiejś procedury z ROM należy osobiście zadbać o poprawne skonfigurowanie pamięci, oraz odtworzenie jej przed wyjściem z przerwania n.p. tak: |
| <pre> | <pre> | ||
| custom_dli: | custom_dli: | ||
| Linia 185: | Linia 213: | ||
| rti | rti | ||
| </pre> | </pre> | ||
| - | <b>UWAGA!</b> Należy również mieć na uwadze, że wektor VDSLST powinien wskazywać na procedurę obsługi DLI zdefiniowaną przez użytkownika i znajdującą się poza obszarem w którym może pojawić się ROM (patrz "Restrykcje pamięciowe"). | + | Trzeba to mieć też na uwadze kiedy w procedurze DLI wykorzystuje się dane lub procedury leżące pod ROM-em i w analogiczny sposób zagwarantować odpowiednią konfigurację PORTB. |
| + | |||
| + | <b>UWAGA!</b> Wektor VDSLST powinien wskazywać na procedurę obsługi DLI zdefiniowaną przez użytkownika i znajdującą się poza obszarem w którym może pojawić się ROM (patrz "Restrykcje pamięciowe"). | ||
| = Restrykcje pamięciowe = | = Restrykcje pamięciowe = | ||
| - | Procedury handlera, "przelotek" czy procedur użytkownika powinny znajdować się w RAM poza obszarami w którymi istnieje ryzyko pojawienia się pamięci ROM: | + | Procedury handlera, "przelotek" czy procedur obsługi przerwań zdefiniowanych przez użytkownika (a także procedura inicjalizacji całego mechanizmu) powinny znajdować się w RAM poza obszarami w których istnieje ryzyko pojawienia się pamięci ROM, a takim ryzykiem obarczone są: |
| - | * $5000..$57FF - SELF-TEST | + | * $5000..$57FF - [[SELF TEST|SELF-TEST]], lub [[MapRAM]] |
| - | * $8000..$9FFF - cartridge | + | * $8000..$9FFF - [[Cartridge|cartridge]] |
| - | * $A000..$BFFF - cartridge, wbudowany BASIC, wbudowana gra (XEGS) | + | * $A000..$BFFF - [[Cartridge|cartridge]], wbudowany [[Atari BASIC]] (XL/XE), wbudowana gra ([[XEGS]]) |
| - | * $C000..$FFFF - OS ROM oraz ROM nowego urządzenia ($D800..$DFFF) | + | * $C000..$CFFF - [[XL OS|OS]] ROM |
| + | * $D000..$D7FF - obszar rejestrów hardware | ||
| + | * $D800..$DFFF - [[XL OS|OS]] ROM ([[Pakiet matematyczny|pakiet matematyczny]]) lub ROM [[Nowe urządzenia|nowego urządzenia]] | ||
| + | * $E000..$FFFF - [[XL OS|OS]] ROM | ||
| - | W przypadku gdy wykorzystywana jest pamięć dodatkowa (XE) również obszar $4000..$7FFF jest obszarem ryzykownym. | + | W przypadku gdy wykorzystywana jest pamięć dodatkowa ([[130XE|XE]]) również obszar $4000..$7FFF jest obszarem ryzykownym. |
| - | Jeśli programista może zagwarantować, że określony rodzaj pamięci nie będzie przełączany, wtedy oczywiście procedury obsługi przełączania pamięci mogą być w umieszczone w odnośnym obszarze (z oczywistych przyczyn obszar OS jest zawsze obszarem ryzykownym). | + | Jeśli programista może zagwarantować, że określony rodzaj pamięci nie będzie nigdy przełączany, wtedy oczywiście procedury obsługi przełączania pamięci mogą być umieszczone w odnośnym obszarze (z oczywistych przyczyn obszar rejestrów hardware ani OS ROM do takich nie należy). |
| = Trivia = | = Trivia = | ||
| Opisana tutaj sztuczka jest stosowana między innymi przez [[Turbo BASIC XL]], [[U-BASIC]] oraz [[SpartaDOS X]]. | Opisana tutaj sztuczka jest stosowana między innymi przez [[Turbo BASIC XL]], [[U-BASIC]] oraz [[SpartaDOS X]]. | ||
| + | |||
| + | = Linki = | ||
| + | |||
| + | * http://www.atari.org.pl/forum/viewtopic.php?id=7336 - dyskusja na forum AtariArea | ||
| + | * [[Mapa pamięci]] | ||
| [[Kategoria:Niezbędnik kodera]] | [[Kategoria:Niezbędnik kodera]] | ||
Aktualna wersja
Żeby swobodnie używać mechanizmów OS-a a przy tym mieć dostęp do całego RAM-u trzeba zadbać tylko o poprawne wykonanie procedur przerwań umieszczonych w ROM-ie w sytuacji kiedy ten jest wyłączony.
Spis treści |
Handler
Kod handlera przerwań powinien być umieszczony poza obszarem, w którym może się pojawić ROM (patrz "Restrykcje pamięciowe"):
nmiint sec
.byte $24 ;BIT $18 ($18 to opcode CLC niżej)
irqint clc
;wlaczenie OS ROM
inc PORTB ;$D301
pha
txa
pha
tsx
;odlozenie na stos danych dla powrotu z przerwania (RTI)
lda #>iret ;adres procedury iret
pha
lda #<iret
pha
lda $103,x ;skopiowanie wartosci rejestru stanu procesora
pha
;skok przez odpowiedni wektor przerwania
scc
jmp (NMIVEC) ;$FFFA
jmp (IRQVEC) ;$FFFE
iret pla
tax
pla
;wylaczenie OS ROM
dec PORTB ;$D301
rti
Inicjalizacja
Wszystko co jest potrzebne do uruchomienia mechanizmu to inicjalizacja wektorów NMIVEC i IRQVEC pod ROM-em:
sei
lda #%00000000
sta NMIEN ;$D40E
lda #%11111110
sta PORTB ;$D301
ldx #<nmiint
ldy #>nmiint
stx NMIVEC ;$FFFA
sty NMIVEC+1
ldx #<irqint
ldy #>irqint
stx IRQVEC ;$FFFE
sty IRQVEC+1
lda #%01000000
sta NMIEN ;$D40E
cli
Od tej pory można swobodnie wyłączać i włączać dowolny obszar ROM (przez zwykłą modyfikację rejestru PORTB) bez obawy o to, że komputer się zawiesi.
Działanie
W przypadku kiedy OS ROM jest włączony przerwanie obsługiwane jest przez standardowe procedury umieszczone w systemie operacyjnym (ponieważ wektory NMIVEC oraz IRQVEC znajdują się wtedy w obszarze ROM).
Kiedy OS ROM jest odłączony wektor wejścia w przerwanie pobierany jest z NMIVEC lub IRQVEC, które znajdują się w RAM i wykonywana jest procedura przerwania nmiint lub irqint zależnie od rodzaju zgłoszonego przerwania. W obydwu przypadkach ma ona za zadanie włączenie ROM-u, wykonanie procedury obsługi przerwania według wektora znajdującego się już w ROM, oraz przywrócenie konfiguracji pamięci po powrocie. Odbywa się to poprzez zapalenie najmłodszego bitu PORTB (włączenie OS ROM), odłożenie na stos adresu powrotu do procedury iret oraz zawartości rejestru stanu F procesora odłożonego na stos w sekwencji wywołania przerwania. Zduplikowanie tej wartości jest niezbędne dla poprawnego działania systemowych procedur obsługi przerwań (tylko wartość rejestru F odłożona na stosie zawiera poprawne wartości znaczników I i B), ponieważ testują one:
- czy przerwane zostało wykonanie przerwania IRQ (w przypadku obsługi przerwania NMI),
- czy przerwanie IRQ zostało zgłoszone przez układ I/O, czy może przerwanie zostało wywołane przez rozkaz BRK (w przypadku obsługi przerwania IRQ).
Po wykonaniu procedury z ROM sterowanie przekazywane jest do procedury iret, której jedynym zadaniem jest ponowne odtworzenie konfiguracji pamięci (odłączenie ROM).
Podczas obsługi przerwania IRQ może się zdarzyć, że nadejdzie nowe zgłoszenie IRQ. W tej sytuacji, po powrocie z procedury obsługi bieżącego przerwania a jeszcze przed wykonaniem procedury iret, obsłużone zostanie nowe przerwanie za pomocą systemowej procedury zawartej w ROM. Dzieje się tak z powodu duplikacji rejestru F odkładanego na stos w procedurze irqint, w którym znacznik I jest zgaszony. Dopiero po zakończeniu obsługi wszystkich zgłoszonych przerwań następuje wykonanie procedury iret przywracającej konfigurację PORTB.
Wywoływanie procedur OS
Trzeba pamiętać (co właściwie powinno być oczywiste), że gdy w programie chcemy wywołać dowolną systemową procedurę z ROM, a jest on aktualnie odłączony, to trzeba go sobie włączyć:
lda #%11111111
sta PORTB ;$D301
jsr JSIOINT ;$E459
Odwołania do procedur OS-a odbywają się przez tablice wektorów oraz tablicę skoków. Stanowią one oficjalne punkty wejścia do procedur systemu operacyjnego i gwarantują, że niezależnie od wersji oraz rodzaju systemu operacyjnego zainstalowanego w komputerze zawsze zostanie wywołana procedura żądana przez użytkownika.
Wyjątek stanowią procedury pakietu matematycznego który nie posiada tablicy skoków, przez co odpowiednie procedury niezależnie od wersji pakietu zainstalowanego w komputerze zawsze muszą znajdować się pod ustalonymi adresami.
Przelotki
Wygodnym sposobem realizowania skoków do procedur OS jest zdefiniowanie tzw. "przelotek", które zadbają o konfigurację pamięci i jej odtworzenie po powrocie z procedury.
UWAGA! Takie "przelotki" analogicznie, jak procedura handlera przerwań, powinny również znajdować się poza obszarem, w którym może pojawić się ROM (patrz "Restrykcje pamięciowe").
Wywołania przez systemową tablicę skoków:
JSIOINT_jump:
lda PORTB ;$D301
pha
ora #%00000001
sta PORTB ;$D301
jsr JSIOINT ;$E459
pla
sta PORTB ;$D301
rts
Nieco odmienna jest metoda wywoływania procedur dostępnych przez tablicę wektorów, ponieważ wektory wskazują adres procedury zmniejszony o jeden i jako takie służą do wykonania skoku przez RTS:
CIO_S_SPECIAL_jump:
lda PORTB
pha
ora #%00000001
sta PORTB
jsr ?call
pla
sta PORTB
rts
?call lda $E410+$0A+1 ;tablica handlera S: wektor SPECIAL
pha
lda $E410+$0A
pha
rts
Ta metoda powinna być używana również do wywołania procedury PUTBT dostępnej w rejestrze ICPUTB bloku IOCB n.p.
;IN: X-IOCB#*16, A-data
;OUT: Y-status, N-error flag
CIO_PUTBT_jump:
tay
lda PORTB
pha
ora #%00000001
sta PORTB
jsr ?call
pla
sta PORTB
cpy #0
rts
?call lda ICPUTB+1,x
pha
lda ICPUTB,x ;$0346
pha
tya
ldy #$92 ;FUNCTION NOT IMPLEMENTED
rts
Rejestry OS w RAM
Rejestry $00..$7F oraz $2xx i $3xx są zarezerwowane dla potrzeb systemu operacyjnego.
DLI
W przypadku gdy w programie używane jest przerwanie Display List, które zazwyczaj jest krytyczne czasowo, można zmodyfikować punkt wejścia do przerwania NMI tak, aby zagwarantować identyczne zależności czasowe jak w przypadku gdy przerwanie obsługiwane jest bezpośrednio przez procedurę systemu operacyjnego:
nmiint bit NMIST ;$D40F
spl
jmp (VDSLST) ;$0200
sec
.byte $24 ;BIT $18
irqint clc
...
Należy jednak pamiętać, że wtedy po wejściu do procedury obsługi przez wektor VDSLST ($200) nie ma gwarancji że ROM jest włączony. Jeśli więc w procedurze obsługi przerwania DLI chcemy użyć jakiejś procedury z ROM należy osobiście zadbać o poprawne skonfigurowanie pamięci, oraz odtworzenie jej przed wyjściem z przerwania n.p. tak:
custom_dli:
pha
lda PORTB
pha
ora #%00000001
sta PORTB
...
jsr OS_ROUTINE
...
pla
sta PORTB
pla
rti
lub też wykorzystać opisane wyżej "przelotki":
custom_dli:
pha
...
jsr OS_ROUTINE_jump
...
pla
rti
Trzeba to mieć też na uwadze kiedy w procedurze DLI wykorzystuje się dane lub procedury leżące pod ROM-em i w analogiczny sposób zagwarantować odpowiednią konfigurację PORTB.
UWAGA! Wektor VDSLST powinien wskazywać na procedurę obsługi DLI zdefiniowaną przez użytkownika i znajdującą się poza obszarem w którym może pojawić się ROM (patrz "Restrykcje pamięciowe").
Restrykcje pamięciowe
Procedury handlera, "przelotek" czy procedur obsługi przerwań zdefiniowanych przez użytkownika (a także procedura inicjalizacji całego mechanizmu) powinny znajdować się w RAM poza obszarami w których istnieje ryzyko pojawienia się pamięci ROM, a takim ryzykiem obarczone są:
- $5000..$57FF - SELF-TEST, lub MapRAM
- $8000..$9FFF - cartridge
- $A000..$BFFF - cartridge, wbudowany Atari BASIC (XL/XE), wbudowana gra (XEGS)
- $C000..$CFFF - OS ROM
- $D000..$D7FF - obszar rejestrów hardware
- $D800..$DFFF - OS ROM (pakiet matematyczny) lub ROM nowego urządzenia
- $E000..$FFFF - OS ROM
W przypadku gdy wykorzystywana jest pamięć dodatkowa (XE) również obszar $4000..$7FFF jest obszarem ryzykownym.
Jeśli programista może zagwarantować, że określony rodzaj pamięci nie będzie nigdy przełączany, wtedy oczywiście procedury obsługi przełączania pamięci mogą być umieszczone w odnośnym obszarze (z oczywistych przyczyn obszar rejestrów hardware ani OS ROM do takich nie należy).
Trivia
Opisana tutaj sztuczka jest stosowana między innymi przez Turbo BASIC XL, U-BASIC oraz SpartaDOS X.
Linki
- http://www.atari.org.pl/forum/viewtopic.php?id=7336 - dyskusja na forum AtariArea
- Mapa pamięci
