Od piątku leżę w szpitalnym łóżku (spokojnie, to tylko kolejne badania moich szwankujących mięśni) i pomimo tego, że sobotę i niedzielę spędziłem z dzieciakami w domu (przypomina mi się seria „Wielkie ucieczki” na TVN), trochę mi się nudzi. Dzisiaj mnie biopsnęli w nogę, więc może trochę pod wpływem anestetyków postanowiłem dokończyć mój ulubiony (ad nauseam) scroll poziomy w VBI i „rainbow effect” w DLI, tym razem w assemblerze i tym razem w lewo.
hscrol = 54276
sdmctl = $022F
dlist = 560
nmien = $D40E
vvblkd = $0224
xitvbv = $E462
scount = $8000
colt = $D017
indx = $8002
wsync = $D40A
vdslist = $0200
org $4000
init ldy #0
sty sdmctl ; wyłącz antic
lda <ndl ; ustaw adres tablicy ndl jako dliste
sta dlist
lda >ndl
sta dlist+1
lda #16
sta scount ; wyzeruj liczniki
sty chrno
sty indx
lda #64
sta 88
lda #156
sta 89
; vbi+dli
lda <scroll ; ustaw scroll w opóźnionym vblank interrupt
sta vvblkd
lda >scroll
sta vvblkd+1
lda <dli ; ustaw adres procedury dli
sta vdslist
lda >dli
sta vdslist+1
lda #42
sta sdmctl ; włącz antic
lda #$c0 ; włącz przerwania dli
sta nmien
; kolory i napisy
lda #0
sta 710
posxy #2, #5
putline #txt1
lda #50
sta 88
lda #155
sta 89
posxy #0, #0
putline #txt2
loop jmp loop
scroll ldy scount
dey
sty hscrol
beq @+
sty scount
jmp xitvbv
@ ldy chrno
iny
cpy #30
bne chmem
lda #25
ldx #0
stx chrno
sta ndl[28],x
lda #155
sta ndl[29],x
ldx #16
stx scount
jmp xitvbv
chmem
clc
sty chrno
ldx #0
lda ndl[28],x
adc #2
sta ndl[28],x
lda ndl[29],x
adc #0
sta ndl[29],x
ldy #15
sty hscrol
iny
sty scount
jmp xitvbv
dli pha
txa
pha
tya
pha
inc indx
ldx #7
@ lda #1
sta wsync
lda indx
cmp #30
beq @+
dex
cpx #0
beq ret
clc
adc vcount
sta colt
jmp @-
@ ldy #0
sty indx
jmp @-1
ret pla
tay
pla
tax
pla
rti
scount .by 0
chrno .by 0
.array ndl [33] .byte
112, 112, 112, 66, 64, 156, 2, 2, 2, 2, 6, 2, 2
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 130, 86, 30, 155
65, 32, 156
.enda
txt1 .by 'test finescroll!' $9b
txt2 .by 'mads compiler!' $9b
.link 'putline.obx'
.link 'posxy.obx'

Powyższy przykład przesuwa druga z linii w trybie Antic 6/GR. 1, ale sporo zabawy zajęło mi uzyskanie prawidłowego finescroll w Antic 2 / GR. 0. Z tego co udało mi się wyeksperymentować, w trybie GR. 0 jeden piksel potrzebuje pół cyklu koloru, skoro tych pikseli jest 8, do przesunięcia jednego znaku potrzeba 4 zmiany rejestru finescroll (1 cykl koloru = 1 finescroll). Analogicznie w trybie GR. 1 / Antic 6, jeden piksel potrzebuje jeden cykl koloru, znak ma 8 pikseli szerokości, więc mamy finescroll o 8 per znak.
Warto wspomnieć o jeszcze jednym zjawisku. W przykładach w Action! i assemblerze scroll działał prawidłowo, ale tylko w prawo i tylko o 16 punktów. Wydawało mi się to dziwne i długo nie dawało spokoju dlaczego tak się dzieje, że przy finescroll o 8 widać coś jakby szarpnięcie o jeden znak. Zjawisko brało się stąd, że zmieniałem adres pamięci w display liście i wychodziłem z procedury, a zmiana rejestru hscroll na odpowiadający nowemu położeniu znaków na ekranie, następowała dopiero przy następnym vblank interrupt (czyli hscroll był nadal 0, a ANTIC przez chwilę do następnego vbi wyświetlał znak przesunięty po zmianie adresu). Zmiana adresu pamięci i jednoczesne ustawienie hscroll przed jmp xitvbv usunęło problem i wszystko działa tak jak w książce…
Reasumując, Mads jest moim ulubionym cross-assemblerem i pewne jego cechy i funkcje bardzo mnie zachęcają do dalszych eksperymentów, jednak coraz większy widzę sens w programowaniu w Action! Przede wszystkim czytelność kodu jest o wiele większa i na pierdoły nie traci się wiele czasu (tutaj ten sam efekt w Action!). Ciekaw jestem jak sprawdzi się Action! + VBXE.
PS: putline i posxy pochodzą z LIBRARIES/stdio/lib mads. Możnaby jeszcze wyzerować pamięć obrazu, ale… X /C w SDX zrobi to za mnie ;).