DT 85 15
From C64 Diskmag Wiki
Hallo liebe DT-Leser, _______________________ es ist mal wieder soweit, ein neues Pro- gramm erwartet Euch in der DT Ass-Ru- brik. Wie beim ersten Teil geht es auch heute noch einmal um das Thema Lauf- schrift. Nur unterscheidet sich die Technik, die ich diesmal verwendet habe, von der aus dem ersten Teil nicht uner- heblich. Heute will ich Euch mal zeigen, wie man eine Laufschrift in einem Sprite verarbeiten kann. Das Thema lautet somit "SPRITE-SCROLLER" "SPRITE-SCROLLER"
Die Technik, die dahinter steckt, ist eigentlich trivial, vorausgesetzt, man weiß, wie ein Sprite aufgebaut ist und wie man Sprites anzeigen und manipulie- ren kann. Eingefleischte Basicprogram- mierer werden hier keine Schwierigkeiten haben. Dieser Effekt lässt sich jedoch nur ra- tional in Maschinensprache realisieren, Basic ist dafür einfach zu langsam. Auch diesmal läuft die Laufschrift im IRQ ab. Es ist ratsam, sich das Programm vorher mal anzusehen, damit Ihr auch wisst, wo- von ich hier rede. ;)
Gut, die Laufschrift läuft in einem Sprite bzw. "durch" mehrere Sprites. Es ist also nicht so, dass jedes Sprite ei- nen Buchstaben darstellt und der Lauf- schrift-Text einfach durch diese durch- gerollt wird (das ist eine weitere Mög- lichkeit für eine Laufschrift). Hier be- nutzen wir einen normalen 1x1-Zeichen- satz, in diesem Fall den des C64, den ROM-Zeichensatz, den wir dann von rechts nach links durch 8 Sprites durchrollen lassen. Ein Sprite besteht aus 64 Bytes. Füllt man ein Sprite mit z.B. dem Wert 255, so geschieht das von links nach rechts (und
nicht wie im Hires-Modus von oben nach unten). Um nun z.B. den Buchstaben "A" (Wert $01) in ein Sprite zu übertragen, so geschieht dies folgendermaßen: Sprite liegt ab: $2000 Buchstabe A ab: $3000 (nur Beispiele) ldy #$00 ldx #$00 a1 lda $3000,y sta $2000,x inx inx inx iny
cpy #$08 bne a1 rts Hier seht Ihr, dass man jedes Byte des Buchstabens in jede dritte Speicherstel- le des Sprites schreiben muss, um den Buchstaben ordentlich im Sprite darzu- stellen. Im normalen Modus sind nur 8 Sprites erlaubt, also verwenden wir auch alle für die Laufschrift. In jedes Sprite passen jeweils 3 Buch- staben. Diese befinden sich im oberen Bereich der Sprites, den ersten 24 Bytes.
Sprite1 Sprite2 Sprite3 Sprite4 Sprite5 ABC DEF GHI JKL MNO Sprite6 Sprite7 Sprite8 PQR STU VWX Der Laufschrifttext würde dann hier so aussehen: ABCDEFGHIJKLMNOPQRSTUVWX Die Laufschrift kann somit nur aus max. 24 sichtbaren Zeichen bestehen. Der Text an sich kann so lang sein wie man ihn braucht. Dazu später mehr im Code.
Das Prinzip dahinter sollte jetzt ei- gentlich klar sein, zumindest wie die Zeichen in den Sprites erscheinen sol- len. Die Technik, die dahinter steckt, ist simpel: Die Zeichen bzw. die Bits der Zeichen werden mit dem Befehl ASL von rechts nach links einfach durch die Sprites ge- rollt. Dabei muss auf das Carry-Flag ge- achtet werden, damit die Bits auch or- dentlich transportiert werden. Dazu nun im Programm mehr, dabei werde ich jedoch nur im Kern des Programms etwas ausführ- licher:
*= $0810 lda #1 sta $d011 lda #0 sta $d020 sta $d021 lda #15 sta $0286 lda #$93 jsr $ffd2 lda #26 sta $d018 lda #$08 jsr $ffd2
> Bildschirmeinstellungen. ldy #$00 a1 lda screen,y sta $0400,y lda screen+256,y sta $0500,y lda screen+512,y sta $0600,y lda screen+768,y sta $0700,y iny bne a1 > Der Bildschirm wird mit den Daten aus > dem Label "Screen" gefüllt.
ldy #$00 lda #11 a2 sta $d800+(5*40)+9,y sta $d800+(6*40)+9,y sta $d800+(7*40)+9,y iny cpy #$16 bne a2 > Das "Digital Talk"-Logo wird auf dem > Bildschirm positioniert. ldy #$00 lda #$ff a3 sta $2ff8,y iny
cpy #$08 bne a3 > Der Zeichensatz für das Logo steht ab > $2800 (s.u.). Hier wird ein Zeichen > gefüllt und zwar das letzte Zeichen > des Zeichensatzes. sei lda #$33 sta $01 ldy #$00 a4 lda $d000,y sta $3000,y lda $d100,y sta $3100,y
lda $d200,y sta $3200,y lda $d300,y sta $3300,y lda #0 sta $2000,y sta $2100,y iny bne a4 lda #$37 sta $01 cli > Der ROM-Zeichensatz respektive ein > Teil davon wird nach $3000 kopiert. > Dieser wird für die Laufschrift
> benötigt. Die Sprites stehen ab $2000, > dieser Bereich wird mit #0 gefüllt. lda #$00 sta $57 sta $58 sta $5a sta $5b sta $5c > Speicherstellen und Zähler werden > freigemacht. lda #255 sta $d000+21
ldy #$00 ldx #128 a5 txa sta 2040,y lda #15 sta $d000+39,y inx iny cpy #$08 bne a5 ldx #87 stx $d000 ldx #87+(1*24) stx $d002 ldx #87+(2*24)
stx $d004 ldx #87+(3*24) stx $d006 ldx #87+(4*24) stx $d008 ldx #87+(5*24) stx $d00a ldx #87+(6*24) stx $d00c ldx #87+(7*24) stx $d00e > Bis hier werden die Sprites > eingeschaltet und auf dem Bildschirm > positioniert. Auch wird die Farbe auf > Hellgrau gesetzt ($0f = #15).
jsr irq jmp * > Der IRQ wird angesprungen, danach wird > mit JMP * das Programm quasi > angehalten. Alles, was man dann sieht, > läuft ausschließlich im IRQ ab. irq sei lda #$81 sta $d01a lda #$7f sta $dc0d lda #$00 sta $d012
ldx #<irq1 ldy #>irq1 stx $0314 sty $0315 cli lda #27 sta $d011 rts irq1 asl $d019 > Hier die bekannten Einstellungen für > den IRQ. Ich hoffe, da nichts mehr > erklären zu müssen. jsr sprmove
> Hier wird für die vertikale Bewegung > des Sprite-Scrollers eine kleine > Routine angesprungen, die für die > nette Hüpfbewegung des Scrollers > verantwortlich ist. Dieser Sprite- > Sinus wurde mir von dflame zur > Verfügung gestellt. Herzlichen Dank > nochmal!! :) irqq lda $58 bne irq2 ldy #$30 ldx #$00 stx $fa sty $fb
inc $58 lda #$00 sta $02 irq02 ldy $57 lda txt,y bne irq01 lda #$00 sta $57 jmp irq02 irq01 inc $57 asl rol $02 asl rol $02 asl rol $02
clc adc $fa sta $fa lda $02 adc $fb sta $fb ldy #$00 irq0 lda ($fa),y sta $02c0,y iny cpy #$08 bne irq0 > Jetzt gehts ins Eingemachte. Hier > werden die Zeichen berechnet und
> zwischengespeichert. Der Text der > Laufschrift steht ab Label "txt". > Von dort wird ein Zeichen gelesen und > danach berechnet, wo dieses Zeichen > sich in unserem zuvor kopierten ROM- > Zeichensatz befindet. Dafür muss man > den Wert des Zeichens * 8 nehmen und > den Wert zu $3000 rechnen ($fa/$fb). > Am Ende wird das aktuelle Zeichen nach > $02c0-$02c7 geschrieben. Dort kann es > dann gleich verändert werden. Diese > Zwischenspeicherung ist notwendig, > weil wir ja sonst nach jedem Zeichen > den ROM-Zeichensatz neu kopieren > müssten, weil jedes Zeichen durch den > ASL-Befehl gleich geleert wird.
> Der Wert in $5a wird übrigens von 0 > auf 1 gestellt, weil ja nicht nach > jedem Durchgang ein neues Zeichen > berechnet werden darf, sondern erst, > wenn alle 8 Bits eines Zeichens > abgearbeitet wurden. irq2 ldy #$00 ldx #$00 irq4 asl $02c0,x bcc irq3 lda #$01 clc adc 8642,y sta 8642,y irq3 iny
iny iny inx cpx #$08 bne irq4 > Nun werden die ersten 8 Bits des > aktuellen Zeichens per ASL-Befehl in > die Sprites übertragen. Genauer gesagt > in Sprite Nr. 8, das ganz rechts > steht. Dieses Sprite steht ab Adresse > 8640 (Hex $21c0, ich habe ausnahms- > weise mal mit dezimalen Adressen > gearbeitet). In Adresse 8642 beginnt > somit das erste Zeichen. Dort werden > die Bits einfach hinzuaddiert.
inc $5a lda $5a cmp #$08 bne irq5 lda #$00 sta $58 sta $5a > $5a dient als Zähler für die Anzahl > der Durchgänge für ein Zeichen. Steht > dieser auf 8, so wurden alle 8 Bits > des aktuellen Zeichens verarbeitet und > beim nächsten Durchgang wird das > nächste Zeichen aus dem Laufschrift- > text genommen.
> Was nun kommt (von Label "irq5" und > "irq27"), sollte klar sein. Jede > Stelle in den Sprites, von links nach > rechts gesehen, in die ein Zeichen > passt, wird per ASL-Befehl um ein Bit > nach links gerückt. Dabei wird jeweils > mit dem BCC-Befehl auf ein belegtes > Bit reagiert und dieses auf die Stelle > davor hinzuaddiert. Dies bewirkt am > Ende ein Durchrollen der jeweiligen > Bits und somit einen weichen Scroller. irq5 ldy #$00 ldx #$00 irq6 asl 8192,x
> 8192-8199 wird NUR nach links > geschoben. Hierbei ist es nicht > notwendig, auf die Bits zu achten, > weil hier der Scroller eh zu Ende ist > und die Bits einfach links > verschwinden können. asl 8193,x bcc irq7 lda #$01 clc adc 8192,x sta 8192,x irq7 asl 8194,x bcc irq8
lda #$01 clc adc 8193,x sta 8193,x irq8 asl 8256,x bcc irq9 lda #$01 clc adc 8194,x sta 8194,x irq9 asl 8257,x bcc irq10 lda #$01 clc
adc 8256,x sta 8256,x irq10 asl 8258,x bcc irq11 lda #$01 clc adc 8257,x sta 8257,x irq11 asl 8320,x bcc irq12 lda #$01 clc adc 8258,x sta 8258,x
irq12 asl 8321,x bcc irq13 lda #$01 clc adc 8320,x sta 8320,x irq13 asl 8322,x bcc irq14 lda #$01 clc adc 8321,x sta 8321,x irq14 asl 8384,x bcc irq15
lda #$01 clc adc 8322,x sta 8322,x irq15 asl 8385,x bcc irq16 lda #$01 clc adc 8384,x sta 8384,x irq16 asl 8386,x bcc irq17 lda #$01 clc
adc 8385,x sta 8385,x irq17 asl 8448,x bcc irq18 lda #$01 clc adc 8386,x sta 8386,x irq18 asl 8449,x bcc irq188 lda #$01 clc adc 8448,x sta 8448,x
irq188 asl 8450,x bcc irq19 lda #$01 clc adc 8449,x sta 8449,x irq19 asl 8512,x bcc irq20 lda #$01 clc adc 8450,x sta 8450,x irq20 asl 8513,x bcc irq21
lda #$01 clc adc 8512,x sta 8512,x irq21 asl 8514,x bcc irq22 lda #$01 clc adc 8513,x sta 8513,x irq22 asl 8576,x bcc irq23 lda #$01 clc
adc 8514,x sta 8514,x irq23 asl 8577,x bcc irq24 lda #$01 clc adc 8576,x sta 8576,x irq24 asl 8578,x bcc irq255 lda #$01 clc adc 8577,x sta 8577,x
irq255 asl 8640,x bcc irq25 lda #$01 clc adc 8578,x sta 8578,x irq25 asl 8641,x bcc irq26 lda #$01 clc adc 8640,x sta 8640,x irq26 asl 8642,x bcc irq27
lda #$01 clc adc 8641,x sta 8641,x irq27 inx inx inx iny cpy #$08 beq irqend jmp irq6 > Diese ganze Prozedur muss natürlich > 8 mal durchlaufen werden, für jedes
> Byte eines Zeichens, das aus 8 Bytes > besteht. irqend jmp $ea31 > Ende der Irq-Routine. <++++++++++++++++++++++++++++++++++++++> sprmove lda #$5c ldy #$00 ldx #$00 spr1 sta $d001,y iny iny inx
cpx #$08 bne spr1 spr2 ldx #$9f lda sinus,x cmp #$3c bne spr3 lda #$ff sta $d01b spr3 cmp #$80 bne spr4 lda #$00 sta $d01b spr4 lda sinus,x clc adc #$05 sta sprmove+1
inc spr2+1 rts > Dies ist die kleine Routine, die den > Scroller von oben nach unten "hüpfen" > lässt. Unter anderem sorgt diese > dafür, dass sich der Sprite-Scroller > abwechselnd hinter bzw. vor dem > Digital Talk-Logo befindet. Dies wird > in der Adresse $d01b kontrolliert. <--------------------------------------> txt .byte $03,$08,$09,$03,$0f,$20 .byte $0f,$06,$20,$03,$09,$16 .byte $09,$14,$01,$13,$20,$00
> Hier steht der kurze Laufschrifttext. > Dieser kann hier nur max. 255 Zeichen > lang sein. Man kann das Programm > jedoch so modifizieren, dass der Text > auch länger sein kann. Vielleicht eine > kleine Aufgabe für Euch??? ;-) sinus .byte $46,$45,$45,$44,$44,$43 .byte $42,$41,$40,$3f,$3e,$3d .byte $3d,$3c,$3c,$3c,$3c,$3d usw. > Hier stehen die Werte für die Sinus- > Routine. <-------------------------------------->
logo .byte $01,$02,$03,$04,$05,$06 .byte $03,$07,$08,$09,$0a,$03 .byte $0b,$00,$0c,$0d,$0e,$0f usw. > Hier stehen die Werte für das Logo. <--------------------------------------> screen .byte $ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$ff,$ff,$ff,$ff usw. > Hier stehen die Werte für den > Bildschirm. <-------------------------------------->
*= $2800 .byte $00,$00,$00,$00,$00,$00 .byte $00,$00,$00,$7f,$7f,$7f .byte $7f,$7f,$7d,$7c,$00,$00 usw. > Ab $2800 steht der Zeichensatz für das > Logo. Das war's dann soweit. Solltet Ihr Fragen, Wünsche oder Anre- gungen haben, dann schreibt doch einfach an die DT-Redaktion.
Auch hoffe ich, dass auch dieser Ass- Kurs ein wenig interessant für Euch war. Dann bis zum nächsten Mal... Euer XXXXXXXXXXXXXXXXXX CHICO/CIVITAS _