multitasking prosty jak drut :), w n/w przykladzie na VBL'u przelaczane sa dwie "aplikacje", dzialanie kazdej polega na wpisywaniu do rejestru $d01a wartosci w petli nieskonczonej, pierwsza wpisuje wartosc $88, druga $26
...
start
lda #$88
sta $d01a
jmp start
...
efekt koncowy to mruganie ekranu
wbrew pozorom nie jest to zbyt wolne jak na mozliwosci 6502, przepisanie stosu (256bajtow), zwrocenie wartosci rejestrow A,X,Y, wartosci wskaznika stosu S zajmuje z 5200 cykli, w skali 20.000 ktore oferuje VBL nie jest zle, jednak 65816 wykonalby to samo w kilkudziesieciu cyklach
w momencie wywolania przerwania VBL, na stos odkladane sa 3 wartosci, stan CPU, oraz adres ostatniego wykonywanego rozkazu
n/w program na poczatku preparuje odpowiednio stosy, ustawiajac w nich odpowiednio adresy startowe kazdej z "aplikacji", zapamietujac poczatkowa wartosc wskaznika stosu, reszte zalatwia juz "przyroda"
kazda z "aplikacji" zaczyna sie od poczatku strony pamieci, 256b na stos, nastepnie rozkaz skoku pod wlasciwy adres startowy aplikacji (JMP INIT) i wlasciwy kod programu (START)
jesli tych aplikacji mialoby byc kilkadziesiat, wowczas opoznienie tez wynosiloby kilkadziesiat ramek, dlatego najlepszym zastosowaniem takiego multitaskingu bylaby mozliwosc przelanczania aplikacji, np. mamy zaladowanych kilka programow w pamieci (odpowiednio napisanych, kod relokowalny) odpowiednia kombinacja klawiszy przechodzimy to task managera, wybieramy inna aplikacje i dzialamy w niej, potem mozemy wrocic do poprzedniej i kontynuowac
oczywiscie czesc aplikacji wymagalaby dzialania w tle, ftp'e, zegar czasu (co 50 ramek wywolywac), msx player (wywolywac co 1 ramke), moznaby takie aplikacje podpiac pod koncowke przerwania VBL, ogolnie bylyby rozne typy aplikacji jak i rozne ich piorytety dzialania, z kolei
operacje IO bylyby krytyczne czasowo
sposob tworzenia aplikacji tez wymagalby zmian, na pewno zostalby wyodrebniony podzial na segmenty, segment stosu, danych, kodu i antica, oczywiscie kod relokowalny. Aplikacja bylaby przechowywana w pamieci dodatkowej, w momencie żądania jej wykonania przepisywana bylaby do pamieci podstawowej (program ANTIC'a nie wykona sie w dodatkowej) i tu byloby kontynuowane jej dzialanie (po podmianie stosu)
kod dla 65816 bylby szybszy jednak narzucalby ograniczenia co do ilosci zaladowanych aplikacji, nie przeznaczymy przeciez calych 64kb na stosy dla kazdej z aplikacji, przechowywanie aplikacji w pamieci dodatkowej jest bardziej uniwersalne i nie narzuca ograniczen dla organizacji pamieci podstawowej
ktos chetny na projekt takiego systemu ? i pisanie aplikacji do niego ?
org $2000
tasks equ 2
main
/*
Initialize TASK
copy current stack to TASK1.STACK and TASK2.STACK
*/
cld
tsx
ldy #0
cp
lda $0100,y
sta task1,y
sta task2,y
iny
bne cp
// init stacks
lda >task1.init
sta task1,x
lda <task1.init
sta task1-1,x
lda #$a4
sta task1-2,x
lda >task2.init
sta task2,x
lda <task2.init
sta task2-1,x
lda #$a4
sta task2-2,x
// init stack pointers
:3 dex
stx task_point
stx task_point+1
/*
Initialize NMI vector
*/
lda $14
_wai cmp $14
beq _wai
sei
lda #0
sta $d40e
sta $d400
mva #$fe $d301
mwa #nmi $fffa
mva #$40 $d40e
// LET'S GO
jmp task1.init
/*
NMI routine
*/
.proc nmi
bit $d40f
bpl vbl
dli rti
vbl
sta rA+1
stx rX+1
sty rY+1
sta $d40f
// OLD TASK
tsk ldy #0
lda task_stack,y
sta _dst+2
ldx #0
_src lda $0100,x
_dst sta $ff00,x
inx
bne _src
tsx
txa
sta task_point,y
lda rA+1
sta task_regA,y
lda rX+1
sta task_regX,y
lda rY+1
sta task_regY,y
// NEW TASK
iny
cpy #tasks
bne skip
ldy #0
skip
sty tsk+1
lda task_stack,y
sta src+2
ldx #0
src lda $ff00,x
sta $0100,x
inx
bne src
ldx task_point,y
txs
lda task_regA,y
sta rA+1
lda task_regX,y
sta rX+1
lda task_regY,y
sta rY+1
rA lda #
rX ldx #
rY ldy #
rti
.endp
/*
TASK NO.1
*/
align
.proc task1
stack
.ds 256
init
jmp start
start
lda #$88
sta $d01a
jmp start
.endp
/*
TASK NO.2
*/
align
.proc task2
stack
.ds 256
init jmp start
start
lda #$26
sta $d01a
jmp start
.endp
task_stack dta h( task1 , task2 )
task_point .ds tasks
task_regA .ds tasks
task_regX .ds tasks
task_regY .ds tasks
;---
run main
opt l-
icl 'align.asm'
icl 'xasm.asm'
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C