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 ;).