C64 posiada sprity o szerokosci 12 pixli trybu 15OS Atari i wysokosci 21 linii (4 kolory), ich kształt, kolory itp mozna zdefiniowac "jako gotowce" potem np. w rastrze podmienic adres do nich i rozmnozyc je w linii, na Atari ten numer nie przejdzie bo Atari tworzy duchy przepisujac je linia po linii z odpowiednich rejestrow, czyli ogólnie Atari - C64 to zupełnie inne podejścia do tematu duchów sprzętowych
duchy programowe na znakach, jedyne jakie zrobiłem to te w grze Dynablaster, ekran to tryb JGP Dariusza Żołny zwany też 4+ (tryb wymyślony przez Avalon), czyli dwa zestawy znaków zmieniane co wiersz
ogólnie udało się w 1 ramce bez buforowania zmieścić 4 ruchome obiekty 8x8 pixli rozdzielczości trybu 15 OS, maksymalnie w 1 ramce możnaby zmieścić 8 takich obiektów, schemat działania: obraz and maska_obiektu -> obraz or kształt_obiektu -> zapisz na obraz
dla trybu graficznego udało się zmieścić 8 obiektów o rozdzielczości 12x24 pixli w 1 ramce z 3-ma buforami i bez maski_obiektu czyli schemat prostszy: obraz or kształt_obiektu -> zapisz na obraz
(przykład załączony do mads-a)
podejście Vegi do tematu wygląda OK, nie ma tu żadnych wielkich tajemnic i tricków, dla 4 zestawów znaków będzie trzeba napisać odpowiednią procedure kopiująca odpowiednie znaki do bufora, potem bufor zmodyfikować odpowiednim kształtem ducha i w końcu przesłać zawartość bufora do odpowiednich znaków z zestawów znakowych. Tak to działa w Dynablaster, wszystkie operacje przepisania są rozpisane (rozpętlone). Ideałem byłoby gdyby nie było bufora przejściowego tylko całą operację udało się zmieścić w jednej rozpętlonej pętli.
Pozatym Jaskier swego czasu zdisasemblował silnik duchów programowych Avalonu (chyba z Lasermani) i jest to ogólnie dostępne, próbowałem to uruchomić ale zabrakło nerwów :) Oczywiście duchy Avalonu wykorzystują tryb 4+ (2 zestawy znakowe) więc tak czy siak dla 4 zestawów znakowych trzeba napisać swój silnik.
*--------------------------*
* SP by Marcin Lewandowski *
* based on SP by *
* Miroslaw Liminowicz *
*--------------------------*
opt 6
org $a800
* jsr init x=LSB(tab), y=MSB(tab)
* tab=
* 1.MSB(dane spriteow)
* 2.il.spriteow (max=21)
* 3.pierwszy wolny znak
* 4.lewa krawedz sceny
* 5.prawa krawedz sceny
* 6.wysokosc ekranu
* 7.szerokosc ekranu
* 8,9.pirwszy dlist
* 10,11.drugi dlist
* 12.MSB(pierwszy ekran)
* 13.MSB(drugi ekran)
* 14.MSB(pierwszy zestaw)
* 15.MSB(drugi zestaw)
* jsr proc wywolywac co jakis czas
* wedle uznania
* numzn= numer spritea w 4+
* xpos= polozenie X
* ypos= polozenie Y
* stat= statusy spriteow
* bit 0 zakrywanie przez ekran
* bit 6 zwierciadlo poziome
* bit 7 zwierciadlo pionowe
*--- strona 0
anascr equ $d6
aspr1 equ $d8
aspr2 equ $da
aznp1 equ $dc
aznp2 equ $de
aznp3 equ $e0
aznk1 equ $e2
aznk2 equ $e4
aznk3 equ $e6
posx equ $e8
posy equ $e9
invrs equ $ea
poczn equ $eb
przes equ $ec
numspr equ $ed
pr1 equ $ee
pr2 equ $ef
pr3 equ $f0
numl1 equ $f1
numl2 equ $f2
numl3 equ $f3
b1 equ $f4
b2 equ $f5
clock equ $f6
adrscr equ $f7
aktzes equ $f8
adrzes equ $f9
adrbuf equ $fa
*--- program
jmp proc
jmp init
numzn dta d' '
xpos dta d' '
ypos dta d' '
stat dta d' '
*--- init
init stx b1
sty b2
jsr chow
* parametry
ldy #1
lda (b1),y
tax
dex
stx zm21+1
iny
lda (b1),y
sta zm31+1
sta zm32+1
sta zm33+1
sta zm34+1
iny
iny
iny
lda (b1),y
sta zm51+1
sta zm52+1
iny
lda (b1),y
sta zm61+1
tax
inx
inx
stx zm62+1
inx
stx zm64+1
sec
sbc #3
sta zm63+1
ldx #0
ldy #0
i9 lda zmtab+1,x
beq i11
sta i10+2
lda zmtab,x
sta i10+1
lda (b1),y
i10 sta $ffff
iny
inx
inx
bne i9
i11 lda zmd+1
sta zmd1+1
lda zme+1
sta zme1+1
lda #0
sta bufor1+21
sta bufor2+21
sta clock
tax
* maski
i1 txa
sta b1
asl @
ora b1
and #$aa
sta b1
lsr @
ora b1
eor #255
sta msktab,x
inx
bne i1
* zwierciadla
i2 txa
ldy #3
i3 asl @
rol b1
asl @
ror odwr,x
lsr b1
ror odwr,x
dey
bpl i3
inx
bne i2
* adresy wzgl.fontow
i4 txa
ldy #0
sty b1
asl @
asl @
rol b1
asl @
rol b1
sta ladrzn,x
lda b1
sta hadrzn,x
inx
bpl i4
* adresy wzgl.ekranu
ldx #0
txa
sec
zm62 sbc #0
sta lscr
lda #$ff
sta hscr
clc
i5 lda lscr,x
zm6 adc #0
sta lscr+1,x
lda hscr,x
adc #0
sta hscr+1,x
inx
zm5 cpx #0
bcc i5
zmf lda #0
asl @
asl @
sta scena
adc #4
sta scena+1
adc #4
sta scena+2
zm4 lda #0
asl @
asl @
sta scena+3
adc #4
sta scena+4
adc #4
sta scena+5
jsr obraz
jmp odchow
*--- animator
proc jsr chow
stx numspr
lda #$2a
sta przes
lda #0
sta invrs
petla inc numspr
ldx numspr
zm2 cpx #0
bcc *+5
jmp exit
lda xpos,x
sta posx
lda ypos,x
sta posy
lda numzn,x
ldy #0
sty b1
asl @
rol b1
asl @
rol b1
asl @
rol b1
asl @
rol b1
sta aspr1
ora #8
sta aspr2
lda b1
zm1 adc #0
sta aspr1+1
sta aspr2+1
lda stat,x
asl @
tay
and #2
tax
lda atab2,x
sta zjmp2+1
lda atab2+1,x
sta zjmp2+2
tya
bcs *+5
jmp od5
bpl od3
* odwracanie
ldx #7
stx b1
ldy #0
od1 lda (aspr1),y
tax
lda odwr,x
ldx b1
sta buf2+8,x
lda (aspr2),y
tax
lda odwr,x
ldx b1
sta buf2,x
iny
dec b1
bpl od1
lda aspr1+1
adc #3
sta aspr1+1
lda aspr2+1
adc #4
sta aspr2+1
dey
od2 inc b1
lda (aspr1),y
tax
lda odwr,x
ldx b1
sta buf1+8,x
lda (aspr2),y
tax
lda odwr,x
ldx b1
sta buf1,x
dey
bpl od2
bmi od8
od3 ldy #0
lda (aspr1),y
tax
lda odwr,x
sta buf1+8,y
lda (aspr2),y
tax
lda odwr,x
sta buf1,y
iny
cpy #8
bcc od3+2
lda aspr1+1
adc #3
sta aspr1+1
lda aspr2+1
adc #4
sta aspr2+1
dey
od4 lda (aspr1),y
tax
lda odwr,x
sta buf2+8,y
lda (aspr2),y
tax
lda odwr,x
sta buf2,y
dey
bpl od4
bmi od8
od5 bpl od9
ldx #7
ldy #0
od6 lda (aspr1),y
sta buf2,x
lda (aspr2),y
sta buf2+8,x
iny
dex
bpl od6
lda aspr1+1
adc #4
sta aspr1+1
lda aspr2+1
adc #4
sta aspr2+1
dey
od7 inx
lda (aspr1),y
sta buf1,x
lda (aspr2),y
sta buf1+8,x
dey
bpl od7
od8 lda <buf1
sta aspr1
lda <buf1+8
sta aspr2
lda >buf1
sta aspr1+1
sta aspr2+1
* przetw.danych
od9 lda posx
and #3
tay
asl @
tax
lda atab1,x
sta zjmp1+1
lda atab1+1,x
sta zjmp1+2
lda maski,y
sta zmas1+1
eor #$ff
sta zmas2+1
lda #$ff
sta numl1
lda posy
lsr @
lsr @
lsr @
lsr @
tax
lda posx
lsr @
lsr @
clc
adc lscr,x
sta anascr
ldy numspr
sta (adrbuf),y
lda hscr,x
adc adrscr
sta anascr+1
tax
tya
clc
adc #21
tay
txa
sta (adrbuf),y
lda numspr
asl @
sta b1
asl @
adc b1
zm3 adc #0
sta poczn
jsr stznkk
jsr przep
lda posy
cmp #16
bcs zm51
ldy przes
zm31 lda #0
sta (adrbuf),y
iny
sta (adrbuf),y
iny
sta (adrbuf),y
iny
sty przes
jmp a1
zm51 lda #0
asl @
asl @
asl @
asl @
adc #16
ldx #6
cmp posy
beq a2
bcc a2
jsr wstaw
a1 clc
lda anascr
zm61 adc #0
sta anascr
bcc *+4
inc anascr+1
clc
lda poczn
adc #3
sta poczn
jsr stznkk
ldy #0
jsr przep2
zm52 lda #0
asl @
asl @
asl @
asl @
ldx #3
cmp posy
beq a2
bcc a2
jsr wstaw
jmp petla
a2 ldy przes
zm32 lda #0
sta (adrbuf),y
iny
dex
bne zm32+2
sty przes
jmp petla
exit jsr obraz
ldy #21
lda (adrbuf),y
beq i12
zm21 ldy #0
sty pr1
tya
asl @
sta pr2
asl @
adc pr2
adc #$2a
tax
lda adrbuf
sta i7+1
lda adrbuf+1
sta i7+2
i6 lda (adrbuf),y
sta b1
tya
clc
adc #21
tay
lda (adrbuf),y
sta b2
ldy #0
i7 lda $ffff,x
zm33 cmp #0
beq *+4
sta (b1),y
inx
iny
zm64 cpy #0
bcs i8
cpy #3
bne i7
tya
clc
zm63 adc #0
tay
bne i7
i8 txa
sbc #12
tax
dec pr1
ldy pr1
bpl i6
i12 jmp odchow
* przepisywanie danych
q1 jsr inc
bcc p2
przep3 ldy numl2
p2 lda (aznp1),y
sta (aznk1),y
lda (aznp2),y
sta (aznk2),y
lda (aznp3),y
sta (aznk3),y
iny
cpy #8
beq q1
cpy #16
bcc p2
rts
q3 lda aspr1
adc #$f7
sta aspr1
lda aspr1+1
adc #3
sta aspr1+1
lda aspr2
adc #$f8
sta aspr2
lda aspr2+1
adc #3
sta aspr2+1
bcc p4
q2 jsr inc
bcc q5
przep lda posy
and #15
sta numl3
ldy #0
cpy numl3
beq przep2
p1 lda (aznp1),y
sta (aznk1),y
lda (aznp2),y
sta (aznk2),y
lda (aznp3),y
sta (aznk3),y
iny
cpy #8
beq q2
q5 cpy numl3
bcc p1
przep2 sty numl2
inc numl1
ldy numl1
cpy #16
bcs przep3
cpy #8
beq q3
p4 lda (aspr2),y
sta pr2
lsr @
lda (aspr1),y
zjmp1 jmp $ffff
q4 jsr inc
bcc przep2
jmp5 ldx pr3
lda (aznp3),y
and msktab,x
ora pr3
sta (aznk3),y
ldx pr2
lda (aznp2),y
and msktab,x
ora pr2
sta (aznk2),y
ldx pr1
lda (aznp1),y
and msktab,x
ora pr1
sta (aznk1),y
iny
cpy #8
beq q4
cpy #16
bcc przep2
rts
jmp6 lda (aznp3),y
tax
lda pr3
and msktab,x
ora (aznp3),y
sta (aznk3),y
lda (aznp2),y
tax
lda pr2
and msktab,x
ora (aznp2),y
sta (aznk2),y
lda (aznp1),y
tax
lda pr1
and msktab,x
ora (aznp1),y
sta (aznk1),y
iny
cpy #8
beq q4
cpy #16
bcc przep2
rts
jmp1 ror @
ror pr2
ror @
ror pr2
jmp2 ror @
ror pr2
ror @
ror pr2
jmp3 ror @
ror pr2
ror @
ror pr2
jmp4 tax
zmas1 and #0
sta pr1
txa
ror @
zmas2 and #0
sta pr3
ldy numl2
zjmp2 jmp $ffff
inc lda aznp1
adc #$f7
sta aznp1
lda aznp1+1
adc #3
sta aznp1+1
clc
lda aznp2
adc #$f8
sta aznp2
lda aznp2+1
adc #3
sta aznp2+1
clc
lda aznp3
adc #$f8
sta aznp3
lda aznp3+1
adc #3
sta aznp3+1
clc
lda aznk1
adc #$f8
sta aznk1
lda aznk1+1
adc #3
sta aznk1+1
lda aznk2
adc #$f8
sta aznk2
lda aznk2+1
adc #3
sta aznk2+1
lda aznk3
adc #$f8
sta aznk3
lda aznk3+1
adc #3
sta aznk3+1
rts
* inne procedury
wstaw lda posx
ldx #$ff
a3 inx
cpx #6
beq a4
cmp scena,x
bcs a3
a4 lda msceny,x
ora invrs
asl @
asl @
asl @
asl @
sta invrs
ldy #0
ldx poczn
a5 lda (anascr),y
sty b1
ldy przes
asl invrs
php
bpl *+4
zm34 lda #0
sta (adrbuf),y
inc przes
ldy b1
txa
plp
bmi *+4
sta (anascr),y
inx
iny
cpy #3
bcc a5
rts
stznkk tax
lda hadrzn,x
ora adrzes
sta aznk1+1
lda hadrzn+1,x
ora adrzes
sta aznk2+1
lda hadrzn+2,x
ora adrzes
sta aznk3+1
lda ladrzn,x
sta aznk1
lda ladrzn+1,x
sta aznk2
lda ladrzn+2,x
sta aznk3
ldy #0
lda (anascr),y
tax
asl @
rol invrs
lda hadrzn,x
ora adrzes
sta aznp1+1
lda ladrzn,x
sta aznp1
iny
lda (anascr),y
tax
asl @
rol invrs
lda hadrzn,x
ora adrzes
sta aznp2+1
lda ladrzn,x
sta aznp2
iny
lda (anascr),y
tax
asl @
rol invrs
lda hadrzn,x
ora adrzes
sta aznp3+1
lda ladrzn,x
sta aznp3
rts
obraz lda $d40b
bpl obraz
zm7 ldx #0
zm8 ldy #0
lda clock
lsr @
bcc zma+2
zm9 ldx #0
zma ldy #0
stx $d402
stx $230
sty $d403
sty $231
zmc ldy #0
bcc zmb+2
zmb ldy #0
sty adrscr
zme ldy #0
zmd1 ldx #0
bcc zmd+4
zmd ldy #0
zme1 ldx #0
stx aktzes
sty adrzes
ldx <bufor1
ldy >bufor1
bcc *+6
ldx <bufor2
ldy >bufor2
stx adrbuf
sty adrbuf+1
inc clock
rts
chow ldx #$1e
lda anascr,x
sta przech,x
dex
bpl chow+2
rts
odchow ldx #$1e
lda przech,x
sta anascr,x
dex
bpl odchow+2
rts
*--- dane
scena dta d' '
msceny dta b(7),b(6),b(4),b(0)
dta b(1),b(3),b(7)
maski dta b($ff),b($3f),b(15),b(3)
zmtab dta a(zm1+1),a(zm2+1),a(zm3+1)
dta a(zmf+1),a(zm4+1),a(zm5+1)
dta a(zm6+1),a(zm7+1),a(zm8+1)
dta a(zm9+1),a(zma+1),a(zmb+1)
dta a(zmc+1),a(zmd+1),a(zme+1),a(0)
atab1 dta a(jmp4),a(jmp3)
dta a(jmp2),a(jmp1)
atab2 dta a(jmp5),a(jmp6)
buf1 org *+$10
msktab org *+$100
odwr org *+$100
ladrzn org *+$80
hadrzn org *+$80
bufor1 org *+$a8
lscr org *+$10
hscr org *+$10
przech org *+$28
buf2 org *+$10
bufor2 org *+$a8
*--- koniec
end
p.s.
65816 i jego 16 bit rejestry są bardziej odpowiednie dla spritów programowych, może Vega stworzysz w końcu gre dla tego CPU