Action!: Finescroll w VBLKD.

Poprzednie przykłady z „Poradnika programisty” brzydko się rwały przy przesuwaniu, zwłaszcza na prawdziwym Atari. Na podstawie różnych „odkryć i znalezisk” powstał poniższy przykład w Action! wykorzystujący Vertical Blank Interrupt. A tutaj analogiczny przykład, który robi to samo w zwykłej pętli i synchronizuje się z VBLANK interrupt za pomocą zegara systemowego.

int j=[0], k=[0]
byte hscrol=54276
card pointer pc
card tmp

include "H1:RUNTIME.ACT"

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
[$4C $E462] ;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 2 86 216 159 65 32 156]
 card dlist=560
 card vvblkd=$0224
 byte col0=708
 byte col1=709

 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
 nmien=$40
 do od
return

scroll() dodałem jako część opóźnioną procedury obsługi przerwania. Wg Tajemnic Atari powinno się ustawiać vvblkd po „cyknięciu” zegara, żeby się nie okazało, że nie starczy cykli procesora na ustawienie adresu naszej procedury obsługi przerwania. Tak też zrobiłem. Nie jestem przekonany czy to jest konieczne.

Reklamy

Finescroll.

Czasem moje eksperymenty przenoszą się na godziny późno-nocne 🙂 Tym razem przemyślenia w temacie „finescroll poziomy”. Synchronizacja nie powinna uciekać, bo przed przesunięciem łapiemy ramkę sprawdzając czy zegar „tyknął”, a dzieje się tak podczas VBLANK interrupt 50 razy na sekundę. W tym wpisie analogiczny przykład z VBI, przy okazji którego pojawił się pomysł uzupełnienia tej procedury o i=time while time=i do od.


include "H1:RUNTIME.ACT"

proc main()
 int i=[0], j=[0], k=[0]
 card dlist=560
 byte hscrol=54276
 card pointer pc
 card savmsc=88
 card tmp
 byte col0=708
 byte col1=709
 byte time=$14

 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 2 86 216 159 65 32 156]
;                  64 + 6 (GR.1) + 16 (hscrol on) = 86
 graphics(0)
 savmsc=40000
 dlist=ndl
 col0=14
 col1=14

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

 print("Action!")

 pc=dlist+28
 tmp=pc^+6
 do
  i=time while time=i do od
  hscrol=j
  j==+1
  if j=17 then
   j=0 pc^==-2 k==+1
   if k=14 then
    pc^=tmp k=0
   fi
  fi
od
return