Wstęp
CPU6502 nie ma możliwości bezpośredniego odwołania się pod konkretny adres dodatkowej pamięci (XMS) jak jest to w przypadku CPU65816. Potrafi maksymalnie zaadresować 64KB pamięci, dostęp do pamięci rozszerzonej realizowany jest przez przełączanie 16KB banków w obszarze $4000..$7FFF. Rejestr PORTB ($d301) jest odpowiedzialny za włączenie konkretnego banku pamięci w w/w obszar.
Założenia.
Aby program mógł działać w pamięci XMS będzie potrzebował kilka krótkich procedur i buforów umieszczonych poza obszarem $4000..$7FFF. Procedury te będą przełączały banki pamięci, dokonywały skoku.
Kompilator przestawia się w tryb pracy z dodatkowymi bankami pamięci (banked) po napotkaniu mnemonika BLK. Po napotkaniu tego mnemonika licznik banków zostaje zwiększony (defaulf=-1), a adres generowanego kodu ustawiany jest na $4000. Jeśli podczas kompilacji zostanie przekroczony adres $7FFF kompilacja zostaje przerwana i zasygnalizowany zostaje błąd przekroczenia dozwolonego obszaru. Aby uniknąć błędu przekroczenia dozwolonego obszaru należy ponownie umieścić mnemonik BLK w programie.
W trybie 'banked', podczas kompilacji wszelkie rozkazy skoków i adresowania będą sprawdzane czy nie odwołują się do obszaru o innym numerze banku. Odwołanie do obszaru o innym numerze banku będzie traktowane jako błąd i odpowiednio sygnalizowane.
Wyłączenie trybu 'banked' nastąpi po napotkaniu mnemonika ORG i adresu spoza zakresu $4000..$7FFF.
Skok do obszaru o innym numerze banku będzie możliwy tylko w trybie 'banked' przy pomocy dwóch mnemoników JML (jump long) oraz JSL (jump subroutine long). Jako że tylko CPU65816 posiada sprzętową obsługę JML i JSL, w przypadku 6502 będzie musiała zostać wykonana dodatkowa procedura. I tak napotkanie mnemonika JML lub JSL, każdorazowo spowoduje zastąpienie go następującym fragmentem kodu:
JML
jsr ___pushAXY
lda tablica_bankow ; odczytanie kodu banku obszaru z tablicy
ldx < $xxx ; wyliczony adres
ldy > $xxx
jmp ___jml
JSL
jsr ___pushAXY
lda tablica_bankow ; odczytanie kodu banku obszaru z tablicy
ldx < $xxx ; wyliczony adres
ldy > $xxx
jsr ___jsl
* --- jump long --- *
___jml stx ___jmp+1 ; modyfikacja adresu ___jmp
sty ___jmp+2
jsr ___pullAXY
___jmp jmp $ffff ; skok
* --- jump subroutine long --- *
___jsl pha ; zapamietanie rejestru regA
lda $d301 ; zapamietanie kodu poprzedniego banku
sta ___bank
pla
sta $d301 ; wlaczenie banku
stx ___jmp+1 ; modyfikacja adresu _JSR
sty ___jmp+2
jsr ___pullAXY ; odczytanie wartosci z rejestrow A,X,Y
___jmp jsr $ffff ; wywołanie procedury
pha ; powrót z procedury, zapamiętanie regA
lda #0 ; przywrócenie kodu poprzedniego banku
___bank equ *-1
sta $d301 ; włączenie poprzedniego banku
pla ; zwrócenie regA
rts ; kontynuowania programu w dodatkowym banku
* --- push A,X,Y --- *
_pushAXY equ *
sta ___regA ; zapamiętanie wartości rejestrów
stx ___regX
sty ___regY
rts
* --- pull A,X,Y --- *
___pullAXY equ * ; oddanie wartości rejestrów
lda #0
___regA equ *-1
ldx #0
___regX equ *-1
ldy #0
___regY equ *-1
rts
Jeśli posiadamy 16-bit CPU kod generowany przez kompilator może być pozbawiony tych procedur i zastąpiony konkretnym kodem JML, JSL.
I tak ogolnie przedstawia sie pomysl na nowy kompilator 6502, co Wy na to ?