Halli hallo,
Ich bitte um eine kleine Code-Review
Ich bin jetzt nicht voll der ASM und C64 Hardware Profi, aber ein par Grundlagen kenne ich und habe früher viel mit ASM für x86 gearbeitet (Demo-Scene Kram).
Ich schreibe eine Routine die einfach einen Byte Array (Byte für Byte) in den SCREEN oder COLOR Speicher kopieren soll. Wahrscheinlich ist es nicht die schnellste Lösung, aber funktioniert schon mal:
* ZP_POINTER_1 zeigt auf den Anfang des Byte Array's
* ZP_POINTER_2 zeigt auf die richtige Position des SCREEN oder COLOR RAM's
* PARAM_1 ist die Breite einer Zeile in den Byte Array
* PARAM_2 ist die Anzahl der Zeilen
- ldx #00
- loopy
- ldy #00
- loopx
- lda (ZP_POINTER_1),y
- sta (ZP_POINTER_2),y
- iny
- cpy PARAM_1
- bne loopx
- inx
- cpx PARAM_2
- beq done
- ; update pointer 1
- lda ZP_POINTER_1
- clc
- adc PARAM_1
- bcc nocarry1
- inc ZP_POINTER_1+1
- nocarry1
- sta ZP_POINTER_1
- ; update pointer 2
- lda ZP_POINTER_2
- clc
- adc #40
- bcc nocarry2
- inc ZP_POINTER_2+1
- nocarry2
- sta ZP_POINTER_2
- ; copy next row
- jmp loopy
- ; copy done
- done
- rts
Dieser Code Snippet ist erstmal nicht so wichtig
So, wenn man den Gesamten Screen füllen will, braucht man 2000 Bytes für Zeichen und Farben was natürlich zu viel ist. Ich habe mir gedacht ich packe jetzt ein bisschen die Daten, und zwar einfach so das vor jedem Zeichen (Byte) erstmal ein Zähler (Byte) kommt wie viel mal muss man das nächste Zeichen wiederholen. Auch wenn man das Zeichen nur einmal zeichnen muss, kommt davor immer ein Zähler, in diesen Fall - eine 1.
Zum Beispiel:
11,22,22,33,33,33,44,44,44,44,55,55,55,55,55
... könnte man so zusammen schrumpfen:
01,11,02,22,03,33,04,44,05,55
In meinem Fall wurden die Daten für die Zeichen 25% kleiner, und für die Farben sogar 75%.
Natürlich musste ich jetzt meine Routine umbauen, und habe auch eine Lösung gefunden. Ich habe die Routine auch sehr viel optimiert, aber trotzdem denke ich da könnte man noch ein bisschen rum schrauben. Mir gefällt das ständige updaten des Pointers nicht so gut. Die Routine benutzt auch 3 extra Speicherplätze ($c000, $c002, $c004) um Daten temporär zu Speichern.
Ich wollte gerne eure Meinung hören, da ich, wie schon gesagt, kein Profi bin
- lda PARAM_2
- sta $c002 ; $c002 holds current row
- cprd_loopy
- lda PARAM_1
- sta $c000 ; $c000 holds current X pos in row
- cprd_loopx
- ldy #00
- lda (ZP_POINTER_1),y
- sta $c004 ; $c004 holds byte count to draw
- iny
- lda (ZP_POINTER_1),y ; ACC holds byte to draw
- ;draw byte in ACC for $c004 times and decrease current X pos in $c000
- ldy $c004
- cprd_loopb
- sta (ZP_POINTER_2),y
- dec $c000
- dey
- bne cprd_loopb
- ;update pointer 1
- lda ZP_POINTER_1
- clc
- adc #02
- bcc cprd_nocarry1
- inc ZP_POINTER_1+1
- cprd_nocarry1
- sta ZP_POINTER_1
- ;update pointer 2
- lda ZP_POINTER_2
- clc
- adc $c004
- bcc cprd_nocarry2
- inc ZP_POINTER_2+1
- cprd_nocarry2
- sta ZP_POINTER_2
- ;check if current pos in row in $c000 is the last one
- lda #00
- cmp $c000
- bne cprd_loopx
- ;update pointer 2
- lda ZP_POINTER_2
- clc
- adc #15 ;hardcoded! should be 40-PARAM_1
- bcc cprd_nocarry3
- inc ZP_POINTER_2+1
- cprd_nocarry3
- sta ZP_POINTER_2
- ;check if current row in $c002 is the last one
- dec $c002
- bne cprd_loopy
- ; copy done
- cprd_done
- rts
Vielen Dank!