sternenhimmel.asm

Aus C64-Wiki
Zur Navigation springenZur Suche springen
Ergebnis
;###############################################################################
;# Programm:      animierter Sternenhimmel als Spritemultiplexer
;# Dateiname:     sternenhimmel.asm
;#
;# Assembler:     ACME
;# Assemblierung: acme -f cbm -o sternenhimmel.prg sternenhimmel.asm
;#
;# Start mit:     RUN
;#
;# Quelltext:     * Kleinschreibung (bis auf Kommentare)
;#                * nur Leerzeichen, keine Tabulatoren
;#                * Abstand: jeweils 20 Zeichen (Label --> Befehl --> Kommentar)
;#                * Zeilenlänge max. 80 Zeichen
;#
;# Beschreibung:  Das Beispielprogramm zeigt einen Sprite-Multiplexer 
;#                mit nur einem Sprite.
;#                * Farben, Geschwindigkeit und Abstände mittels Tabelle
;#                * horizontale Richtung (links oder rechts) auswählbar
;#
;###############################################################################

; ----- @Basic-Start@ -----

                    *=$0801             ; Basic-Startzeile "10 SYS2061" erzeugen
                    !word +             ; Zeiger auf nächste Basic-Zeile
                    !word 10            ; Basic Zeilennummer
                    !byte $9e           ; Basic-Token für SYS-Befehl
                    !text "2061"        ; Startadresse des Programms: 2061/$080D
                    !byte 0             ; Basic-Zeilenende
+                   !word 0             ; Basic-Programmende

; ----- @Hauptprogramm@ -----

start:              sei
                    jsr $e544           ; Bildschirm löschen
                                        
+                   ldy #$00            ; schwarzer Bildschirm
                    sty $d020
                    sty $d021
                    
                    iny
                    sty $dc0d           ; CIA-IRQ aus
                    sty $d01a           ; Rasterzeilen-IRQ zulassen
                    sty $d015           ; Sprite0 einschalten

                    ldy #spritedaten/64
                    sty $07f8           ; Zeiger für Spritedaten Sprite 0 setzen
                                        
                    lda #$1b
                    sta $d011           ; Bild ein, Rasterzeile Bit8=0
                    lda #50
                    sta $d012           ; Rasterzeilen-IRQ bei Zeile 50
                    
                    lda #<irq           ; IRQ-Vektor auf eigene Routine umbiegen
                    sta $0314
                    lda #>irq
                    sta $0315
                    
                    cli                 ; Interrupts freigeben
                    jmp *               ; Endlosschleife (warte auf Rasterz.-IRQ)

; ----- @IRQ-Routine@ -----

irq:                ldx #0
                    ldy #55
loop:               cpy $d012           ; warte auf Rasterzeile 55
                    bne loop
                    
                    sty $d001           ; Sprite0: Y-Koordinate
                    lda position, x
                    sta $d000           ; Sprite0: X-Koordinate aus Tabelle
                    
                    lda $d010
                    and #%11111110      ; Sprite0: Bit8 der X-Koordinate löschen
                    ora speicher,x      ;          und je nach Speicher setzen
                    sta $d010
                    
                    lda farben, x       ; Sprite0: Farbe aus Tabelle holen
                    sta $d027           ;          und festlegen
                    
                    lda position, x     ; Position = Position + Geschwindigkeit
opcode1:            adc speed, x
                    sta position, x
                    
                    lda speicher, x     ; Übertrag (C-Flag) im Speicher sichern,
opcode2:            adc #0              ; wenn X-Koordinate > 255
                    and #1
                    sta speicher, x
                    
                    iny                 ; 3 Rasterzeilen nach unten
                    iny
                    iny
                    
                    inx
                    cpx #64
                    bcc loop
                    
                    richtung = $00      ; $00 Sterne von links nach rechts (ADC)
                                        ; $80 Sterne von rechts nach links (SBC)
                                        
                    lda opcode1
                    ora #richtung
                    sta opcode1         ; ADC oder SBC-Opcode
                    lda opcode2
                    ora #richtung
                    sta opcode2         ; ADC oder SBC-Opcode
                    
                    inc $d019           ; VIC-Interrupt-Flag löschen
                    jmp $ea7e           ; Sprung an das Ende der alten IRQ

; ----- @Daten@ -----

position:           !byte $28,$3c,$50,$64, $78,$8c,$a0,$00, $14,$3c,$28,$b4
                    !byte $64,$78,$00,$14, $3c,$28,$b4,$64, $78,$00,$14,$3c
                    !byte $28,$b4,$64,$78, $00,$14,$3c,$28, $b4,$64,$78,$00
                    !byte $14,$3c,$28,$b4, $64,$78,$00,$14, $3c,$28,$b4,$64
                    !byte $78,$00,$14,$3c, $28,$b4,$64,$78, $00,$14,$3c,$28
                    !byte $b4,$64,$78,$00
                    
speed:              !for i, 1, 8 { !byte $01,$03,$05,$02,$04,$06,$07,$02 }
farben:             !for i, 1, 8 { !byte $0b,$0c,$0f,$0b,$0c,$0f,$01,$0b }
                                        
                    !align 63,0         ; fülle bis zum nächsten Spriteblock
                    
spritedaten:        !for i, 1, 7 { !byte $10,$00,$00,$00,$00,$00,$00,$00,$00 }
                    
speicher:           !fill 64,0