Finescroll w VBI + tęcza w DLI

Zabawy z przesuwaniem tekstu chyba nie będzie końca. Tym razem do przesuwu typu finescroll realizowanego w ramach VBLANK interrupt dodamy ruchomą tęczę w ramach procedury obsługi przerwania DLI.

int i=[0], j=[0], k=[0]
byte wsync=$D40A, vcount=$D40B
byte colt=$D017, indx=[0], hscrol=$D404
card pointer pc
card tmp
include "H1:DEFINES.ACT"

proc dli()
[pha txa pha tya pha]
indx==+1
for i=0 to 7 do
 wsync=1
 if indx>30 then indx=0 fi
 colt=vcount+indx
od
[pla tay pla tax pla rti]

proc scroll()
 hscrol=j
 j==+1
 if j=17 then
  j=0 pc^==-2 k==+1
  if k=14 then
   pc^=tmp k=0
  fi
 fi
[jmp xitvbv]

proc main()
int i card savmsc=88
byte clock=$14
byte nmien=$D40E
byte array ndl = [112 112 112 66 64 156 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 130 86 216 159 65 32 156]
card dlist=560
card vvblkd=$0224
byte col0=708
byte col1=709
card vdslist=$0200
graphics(0)
dlist=ndl
savmsc=40000
col0=14 col1=14

for i=1 to 23 do
 printf("line: %i%E", i)
od
print("action!")

pc=dlist+28
tmp=pc^+6
i=clock
while clock=i do od
nmien=0
vvblkd=scroll
vdslist=dli
nmien=$C0
do od
return

a w pliku DEFINES.ACT:

define rti="$40",
pha="$48", pla="$68", txa="$8A",
tax="$AA", tya="$98", tay="$A8",
jmp="$4C", php="$08", plp="$28",
xitvbv="$E462" 

Najwięcej czasu (ze dwa niespokojne tygodnie :)) zajęło mi dojście do tego, dlaczego w dli muszę zmieniać sprzętowy rejestr koloru, a nie jego cień :). Wynika to z faktu, że jeżeli zmienię rejestr cień, to wartości rejestrów cieni są przepisywane do rejestrów sprzętowych GTIA dopiero w systemowej procedurze przerwania VBLANK, czyli po wyświetleniu ramki do końca.  Skutek jest taki, że wszystkie linie ekranu malowane są ostatnim kolorem z pętli „wsync=1… colt=”  w dli. Po zakończeniu procedury dli() w rejestrze cieniu siedzi sobie tenże ostatni kolor z pętli, bo kolor zmieniony w rejestrze cieniu nie trafia od razu do GTIA, układ graficzny maluje sobie dalej kolorem przepisanym podczas poprzedniego VBLANK. Kończy ramkę, wywołuje przerwanie VBLANK, przepisuje rejestr sprzętowy ostatnią wartością  rejestru systemowego i wszystkie linie od pierwszej do tej, dla której dli jest ustawione maluje w tym samym kolorze.

Jeżeli ustawimy rejestr sprzętowy ($D017 zamiast $2C5) to przy wsync=1 nowy kolor jest przepisywany do GTIA w momencie przerwania poziomego, następna linia do końca jest malowana tym kolorem, tak osiem razy bo w tej linii trybowej mamy osiem linii w wierszu, kończy się malowanie ramki, w VBLANK system operacyjny przepisuje rejestry sprzętowe wartościami z rejestrów cieni, czyli maluje od pierwszej linii trybowej, do tej w której ustawione jest dli kolorami z cieni. Potem startuje dli, zmienia rejestr sprzętowy osiem razy maluje w innym kolorze itd, itd.

Muszę jeszcze tylko przetestować binarkę na prawdziwym Atari… (update: działa).

Ciekawe ile jeszcze takich fascynujących „odkryć” na mojej drodze :). Pewnie sporo.

3 uwagi do wpisu “Finescroll w VBI + tęcza w DLI

  1. Pingback: VBI finescroll + DLI rainbow (ASM) | greblus:~$ cat /dev/random > /dev/null 2>&1

  2. Pingback: VBL i VBI w MadPascal-u. |

  3. Pingback: VBI i DLI w MadPascal-u. |

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj /  Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj /  Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj /  Zmień )

Połączenie z %s