Un gioco scritto totalmente in assembler per il C64

Provo a realizzare un gioco per il Commodore 64 programmando direttamente tutto in linguaggio Assembler.

Se vuoi provarlo sul tuo emulatore C64 i programmi sono disponibili nei formati .d64 e per CBM .prg studio

Scarica qui il software in formato .d64.

Se ti interessa vedere i codici sorgenti in assembly, il progetto è liberamente scaricabile dal link in questa pagina nel formato per “CBM .prg Studio

Scarica qui i sorgenti per CBM .prg studio.

Per farlo funzionare servirà installare che un emulatore C64 per PC come ad esempio il VICE-the Versatile Commodore Emulator.

Questo progetto contiene numerosi spunti utili per imparare le tecniche di programmazione dell’epoca per realizzare videogiochi sul C64, tecniche che andrebbero spiegate singolarmente dedicando un articolo specifico per ogni singolo argomento.

Per questioni di tempo per ora posto i codici. Appena avrò la possibilità dedicherò la spiegazione ai singoli concetti.

Segue il codice in assembler.

; Programming by Alessandro Scola www.alessandroscola.com  info@alessandroscola.com
; Music by Wham
; SID Programming by Magnus Djurberg

; 10 SYS (34577)

*=$0801

        BYTE    $0E, $08, $0A, $00, $9E, $20, $28,  $33, $34, $35, $37, $37, $29, $00, $00, $00

*=$8711


        LDA #$FF 
        LDY #$15 
        STA $D019 ; azzera memoria interrup

        JSR $E544  ;CANCELLA SCHERMO

        LDA #1    
        STA $D020 ; colore parte esterna schermo bianca
        LDA #6   
        STA $D021 ; COLORE sfondo 

        ; stampa le scritte di testata
        LDY #1  ; con colore bianco
        LDX #0
LOOP_TESTATA_1
        LDA TESTATA_1,X
        STA $0400,X
        TYA
        STA $D800,X
        INX
        CPX #40
        BNE LOOP_TESTATA_1
       

        LDX #0
LOOP_TESTATA_2
        LDA TESTATA_2,X
        STA $0450,X
        TYA
        STA $D850,X
        INX
        CPX #40
        BNE LOOP_TESTATA_2

        LDX #0
LOOP_TESTATA_3
        LDA TESTATA_3,X
        STA $04A0,X
        TYA
        STA $D8A0,X
        INX
        CPX #40
        BNE LOOP_TESTATA_3
      
        ; init music
        lda #0
        tax
        tay
        jsr music_player
                  
        ;IMPOSTA VELOCITA DIFFERENTI PER I FIOCCHI
        ;IN PAGINA 0 DA $03 a step di 2 butes MEMORIZZO per ogni fiocco OGNI QUANTI FRAMES FAR SCENDERE IL FIOCCO DI 1 PX

        LDA #$03 ; 3 =  ogni 3 frame
        STA $4001  ; REGISTRO SET VELOCITA FIOCCO 1 (SPRITE 2)
        STA $4002  ; CONTATORE DECREMENTATO AD OGNI FRAME
  
        LDA #$02 
        STA $4003  ; REGISTRO SET VELOCITA FIOCCO 2 (SPRITE 3)
        STA $4004  ; CONTATORE DECREMENTATO AD OGNI FRAME
        
        LDA #$03 ; 3 =  ogni 3 frames
        STA $4005  ; REGISTRO SET VELOCITA FIOCCO 3 (SPRITE 4)
        STA $4006 ; CONTATORE DECREMENTATO AD OGNI FRAME

        LDA #$02 ; 2 =  ogni 2 frames
        STA $4007  ; REGISTRO SET VELOCITA FIOCCO 4 (SPRITE 5)
        STA $4008 ; CONTATORE DECREMENTATO AD OGNI FRAME

        LDA #$03 ; 3 =  ogni 3 frames
        STA $4009  ; REGISTRO SET VELOCITA FIOCCO 5 (SPRITE 6)
        STA $400A ; CONTATORE DECREMENTATO AD OGNI FRAME

        LDA #$02 ; 2 =  ogni 2 frames
        STA $400B  ; REGISTRO SET VELOCITA FIOCCO 6 (SPRITE 7)
        STA $400C ; CONTATORE DECREMENTATO AD OGNI FRAME

        ; CONTATORE FRAME PER MOVIMENTO GAMBE
        LDA #5  ; SPRITE GAMBE CHE CAMMINANO CAMBIANO OGNI 9+1=10 FRAMES
        STA $02  ; OGNI QUANTI FRAMES AGGIORNO GAMBE CHE CORORNO
        LDA #0
        STA $03  ; QUALE DEI 2 SPRITE GAMBE DX STO VISUALIZZANDO ? 0 OPPURE 1
        

        LDA #1  ;FLAG=1 POSIZIONE FIOCCO IN PRIMA META SCHERMO; FLAG=0 POSIZIONO IN SECONDA META
        STA $04 

        LDA #0
        STA PUNTEGGIO ; PUNTEGGIO
        JSR VISUALIZZA_PUNTEGGIO
       

Init   
        lda #$03
        sta $D01C ; sprite multicolor

        lda #$00
        sta $D01D ; Sprite 0 x-expand OFF
        sta $D017 ; Sprite 0 y-expand OFF

        lda #$FF
        sta $D015 ; abilita tutti e 8 gli sprites
        lda #09   ; marron
        sta $D025 ; ALL SPRITES MULTICOLOR 1
        lda #$00  ;nero
        sta $D026 ; ALL SPRITES MULTICOLOR 2

        ; SPRITE 0 corpo snowman
        lda #$D3  ; 211
        sta $07F8  ; pointer sprite 0 
        lda #$01   ; bianco
        sta $D027  ; sprite 0 color 
        lda #$A2   ; X
        sta $D000  ; sprite 0 X position
        lda #$DC   
        sta $D001  ; sprite 0 Y position 

        ; SPRITE 1 gambe snowman
        lda #$D5  ; D5 = 213  e  D6 = 214
        sta $07F9 ; pointer sprite 1 
        lda #$01  
        sta $D028 ; sprite 1 color 
        lda #$A2
        sta $D002 ; sprite 1 X position        
        lda #$F1   
        sta $D003 ; sprite 1 Y position
        
        
        ; SPRITE 2-3-4-5-6-7 fiocco di neve 1-2-3-4-5-6
        lda #$D9  ; 217
        sta $07FA ; pointer sprite 2
        STA $07FB ; pointer sprite 3
        STA $07FC ; pointer sprite 4
        STA $07FD ; pointer sprite 5
        STA $07FE ; pointer sprite 6
        STA $07FF ; pointer sprite 7
      
        ; imposta colore bianco per tutti i fiocchi
        lda #$01  ; colore bianco
        STA $D029 ; sprite 2 color 
        STA $D02A ; sprite 3 color 
        STA $D02B ; sprite 4 color 
        STA $D02C ; sprite 5 color 
        STA $D02D ; sprite 6 color 
        STA $D02E ; sprite 7 color 

        ; imposta posizione X per tutti i fiocchi (SOLO PER DEBUG)
        LDA #$20
        STA $D004 ; sprite 2 X position 
        LDA #$30
        STA $D006 ; sprite 3 X position 
        LDA #$40
        STA $D008 ; sprite 4 X position 
        LDA #$50
        STA $D00A ; sprite 5 X position 
        LDA #$60
        STA $D00C ; sprite 6 X position 
        LDA #$70
        STA $D00E ; sprite 7 X position  
 
        ; imposta posizione Y=0 per tutti i fiocchi
        LDA #244
        STA $D005 ; sprite 2 Y position 
        STA $D007 ; sprite 3 Y position 
        STA $D009 ; sprite 4 Y position 
        STA $D00B ; sprite 5 Y position 
        STA $D00D ; sprite 6 Y position 
        STA $D00F ; sprite 7 Y position 

        lda #0
        STA $D01B ; priorità SPRITES rispetto allo sfondo

;-------------------------------------------------         
        LDX #12
RIPOSIZ_FIOCCHI
        JSR RIPOSIZ_FIOCCO_X
        DEX
        DEX
        BNE RIPOSIZ_FIOCCHI                

        sei          ; turn off interrupts
        lda #$7f
        ldx #$01
        sta $dc0d    ; Turn off CIA 1 interrupts
        sta $dd0d    ; Turn off CIA 2 interrupts
        stx $d01a    ; Turn on raster interrupts

        lda #$1b
        ldx #$08
        ldy #$14
        sta $d011    ; Clear high bit of $d012, set text mode
        stx $d016    ; single-colour
        sty $d018    ; screen at $0400, charset at $2000

        lda #<int    ; low part of address of interrupt handler code
        ldx #>int    ; high part of address of interrupt handler code
        ldy #$80     ; line to trigger interrupt
        sta $0314    ; store in interrupt vector
        stx $0315
        sty $d012

        lda $dc0d    ; ACK CIA 1 interrupts
        lda $dd0d    ; ACK CIA 2 interrupts
        asl $d019    ; ACK VIC interrupts
        cli

;---------- INIZIO MAIN LOOP ---------------------------------------------------

loop
        jmp loop     ; LOOP INFINITO
;---------- FINE MAIN LOOP -----------------------------------------------------

;---------- INIZIO ROUTINE RASTER, ESEGUITA AD OGNI REFRESH SCHERMO-------------
int
        ;LDA #$7
        ;STA $D020            ; change border colour to yellow
      
                
        JSR AGGIORNA_FIOCCHI   
        JSR CHECK_JOYSTICK
        JSR CHECK_SPRITES_COLLISIONS
        
        ; FACCIO AVANZARE LA MUSICA
        JSR music_player + 3
           

        asl $d019    ; ACK interrupt (to re-enable it)
        pla
        tay
        pla
        tax
        pla
        RTI          ; return from interrupt


;---------- FINE ROUTINE RASTER, ESEGUITA AD OGNI REFRESH SCHERMO---------------
VISUALIZZA_PUNTEGGIO
        ; VISUALIZZA PUNTEGGIO SU SCHERMO:
                       
    
DISPLAY 
        LDY #5 ; SCREEN OFFSET
        LDX #0 ; SCORE BYTE INDEX
SLOOP
        LDA PUNTEGGIO,X
        PHA
        AND #$0F
        JSR PLOTDIGIT

        PLA
        LSR A
        LSR A
        LSR A
        LSR A
        JSR PLOTDIGIT
        
        INX
        CPX #3
        BNE SLOOP
        RTS
        
PLOTDIGIT
        CLC
        ADC #48     ; 0 = CODICE ASCII 48
        STA $04AC,Y
        DEY
        RTS
  
                
; --------------------------------------------------------------------------
AGGIORNA_FIOCCHI
        ; AGGIORNA LA POSIZIONE Y solo dei fiocchi che devono essere aggiornati in base a velocità 
        LDX #12    ; OFFSET DA SOMMARE A LOC 4000 PER OTTENERE CONTATORE VELOCITA SPRITE 
                   ; DA QUI DECREMENTO FINO A OFFSET=0 CHE CORRISPONDE A LOC 4001 = VELOCITA SPRITE 
@LOOP_FIOCCHI
        LDA $4000,X    ; QUANTI FRAMES SONO PASSATI? SE LOC=0 ALLORA AGGIORNO POSIZIONE Y FIOCCO
        SEC
        SBC #$01 
        STA $4000,X   ; RIMEMORIZZO CONTATORE DECREMENTATO PER LO SPRITE IN ESAME        SBC #$01 
        BNE @NON_AGGIORNO_FIOCCO_SINGOLO     
                
                         ; SE VELOCITA = 0 ALLORA AGGIORNO POSIZXIONE FIOCCO SINGOLO
        LDA $4000-1,X    ; riprIStino settaggio velocità
        STA $4000,X
        LDA $D003,X    ; LEGGO COORDINATA Y
        CLC
        ADC #$01     ; INCREMENTO POSIZIONE Y DEL FIOCCO
        STA $D003,X  ; SETTO COORDINATA Y
        LDA $D003,X 
        CMP #245     ; SPRITE APPENA FUORI DAL BORDO INFERIORE
        BNE @NON_AGGIORNO_FIOCCO_SINGOLO  
        JSR RIPOSIZ_FIOCCO_X       ; SE POSIZIONE Y=0 (FIOCCO USCITO DA SCHERMO IN BASSO) ALLORA RIPOSIZIONO IN X LO SPRITE CON UN NUMERO RANDOM
@NON_AGGIORNO_FIOCCO_SINGOLO            
        DEX
        DEX
        BNE @LOOP_FIOCCHI
        RTS

; --------------------------------------------------------------------------
RIPOSIZ_FIOCCO_X
        LDA #35       ; POSIZIONEO SPRITE CON Y=35 APPENA FUORI DAL BORDO IN ALTO
        STA $D003,X   ; AGGIORNO POSIZ Y 
        
        LDA $04
        BNE PRIMAMETASCHERMO
        
        ; RESET $04
        LDA #1
        STA $04    
               
SECONDAMETASCHERMO    
        ; CASO MSB=1 
        ; SETTO MSB=1 PER LO SPRITE GIUSTO

        CPX #12 ; SPRITE E' IL NUMERO 7 ?
        BNE 2_SP_6
        LDA $D010       
        ORA #%10000000  ; SETTO A 1 MSB SPRITE 7
        STA $D010
        JMP 2_FINITO
2_SP_6
        CPX #10 ; SPRITE E' IL NUMERO 6 ?
        BNE 2_SP_5
        LDA $D010       
        ORA #%01000000  ; SETTO A 1 M MSB SPRITE 6
        STA $D010
        JMP 2_FINITO
2_SP_5
        CPX #8 ; SPRITE E' IL NUMERO 5 ?
        BNE 2_SP_4
        LDA $D010       
        ORA #%00100000  ; SETTO A 1 M MSB SPRITE 5
        STA $D010
        JMP 2_FINITO
2_SP_4
        CPX #6 ; SPRITE E' IL NUMERO 4 ?
        BNE 2_SP_3
        LDA $D010       
        ORA #%00010000  ; SETTO A 1 M MSB SPRITE 4
        STA $D010
        JMP 2_FINITO
2_SP_3
        CPX #4 ; SPRITE E' IL NUMERO 3 ?
        BNE 2_SP_2
        LDA $D010       
        ORA #%00001000  ; SETTO A 1 M MSB SPRITE 3
        STA $D010
        JMP 2_FINITO
2_SP_2
        CPX #2 ; SPRITE E' IL NUMERO 2 ?
        BNE 2_FINITO
        LDA $D010       
        ORA #%00000100  ; SETTO A 1 M MSB SPRITE 2
        STA $D010
2_FINITO
        JMP LSB
 

PRIMAMETASCHERMO  

        ; CASO MSB=0 
        ; SETTO MSB=0 PER LO SPRITE GIUSTO

        CPX #12 ; SPRITE E' IL NUMERO 7 ?
        BNE 1_SP_6
        LDA $D010       
        AND #%01111111  ; AZZERO MSB SPRITE 7
        STA $D010
        JMP 1_FINITO
1_SP_6
        CPX #10 ; SPRITE E' IL NUMERO 6 ?
        BNE 1_SP_5
        LDA $D010       
        AND #%10111111  ; AZZERO MSB SPRITE 6
        STA $D010
        JMP 1_FINITO
1_SP_5
        CPX #8 ; SPRITE E' IL NUMERO 5 ?
        BNE 1_SP_4
        LDA $D010       
        AND #%11011111  ; AZZERO MSB SPRITE 5
        STA $D010
        JMP 1_FINITO
1_SP_4
        CPX #6 ; SPRITE E' IL NUMERO 4 ?
        BNE 1_SP_3
        LDA $D010       
        AND #%11101111  ; AZZERO MSB SPRITE 4
        STA $D010
        JMP 1_FINITO
1_SP_3
        CPX #4 ; SPRITE E' IL NUMERO 3 ?
        BNE 1_SP_2
        LDA $D010       
        AND #%11110111  ; AZZERO MSB SPRITE 3
        STA $D010
        JMP 1_FINITO
1_SP_2
        CPX #2 ; SPRITE E' IL NUMERO 2 ?
        BNE 1_FINITO
        LDA $D010       
        AND #%11111011  ; AZZERO MSB SPRITE 2
        STA $D010
1_FINITO      
         ; DECREMENTO FLAG X ALTERNARE PRIMA E SECONDA META SCHERMO
        LDA $04
        SEI 
        SBC #1
        STA $04

LSB        
        ; GENERAZIONE RANDOM COODINATA X
        txa
        pha
        LDA #0
        JSR $E09A
        LDA $64  ; valore restituito qui
          
           
        STA $D002,X ; AGGIORNO POSIZ X 
        pla     
        tax
        RTS
         
 ; --------------------------------------------------------------------------        
CHECK_JOYSTICK
        LDX $DC00            ; legge stato JOYSTICK
        CPX #$77             ; JOYSTICK a destra ?
        BNE NODESTRA
           
; ----------------------------------
;       JOYSTICK A DESTRA
; ----------------------------------

        LDA #$D3             ; 211
        STA $07F8            ; cambia immagine sprite (snowman a destra)
        
        ; ANIMAZIONE GAMBE:
        LDA $02
        BNE NON_AGGIORNA_GAMBE_DX ; SE $02<>0 E' NON ORA DI AGGIORNARE LO SPRITE GAMBE DX
        ; RISPRISTINA 02
        LDA #05
        STA $02

        ; CHE PRITE GAMBE DEVO VISUALIZZARE ?
        LDA $03
        BNE CAMBIO_GAMBE_DX_1  ; SE = 1 ANIMAZIONE GAMBE 1 
                        
        LDA #1 ; CAMBIO $03 
        STA $03
CAMBIO_GAMBE_DX_0

        LDA #$D5
        JMP AGGIORNA_PUNTAT_GAMBE_DX

CAMBIO_GAMBE_DX_1        
        LDA #0 ; CAMBIO $03 
        STA $03
        ; ANIMAZIONE GAMBE 1:
        LDA #$D6
        
AGGIORNA_PUNTAT_GAMBE_DX
        STA $07F9    ; cambia imamgine sprite (gambe snowman a destra) 
       
        JMP AGGIORNA_POSIZ_PUPAZZO_DX

NON_AGGIORNA_GAMBE_DX
        SEI
        SBC #01
        STA $02 ; DECREMENTO E AGGIORNO $02

AGGIORNA_POSIZ_PUPAZZO_DX
        LDA $D010
        AND #%00000001
        CMP #%00000001             ; flag  X > 255 ?
        BEQ DESTRA_SOPRA255
        INC $D000            ; COORDINATA X PUPAZZO
        INC $D002            ; COORDINATA X GAMBE PUPAZZO
        BEQ OLTRE255PRIMAVOLTA
        JMP FINEJOYSTICK

DESTRA_SOPRA255
        ; verifica se arrivato a bordo destro
        LDX $D000
        CPX #$41            ; massimo posizione destra
        beq FINEJOYSTICK_DX
        inc $D000            ; incrementa posizione X sprite 0
        inc $D002           ; incrementa posizione X sprite 1    
FINEJOYSTICK_DX
        RTS
                    

OLTRE255PRIMAVOLTA
        inc $D000
        inc $D002
        LDA $D010  
        ORA #%00000011
        STA $D010  ; ACCENDO I 2 BIT PIU A DESTRA DI MSB POSIZIONE X


        jmp FINEJOYSTICK

INCREMENTAX
        inc $D000
        inc $D002

NODESTRA      
        ldx $DC00 
        cpx #$7B             ; JOYSTICK a sinistra ?
        bne FINEJOYSTICK
; ----------------------------------
;       JOYSTICK A SINISTRA
; ----------------------------------
        lda #$D4             ; 212
        sta $07F8            ; cambia imamgine sprite (snowman a sinistra) 

                   
         ; ANIMAZIONE GAMBE:
        LDA $02
        BNE NON_AGGIORNA_GAMBE_SX ; SE $02<>0 E' NON ORA DI AGGIORNARE LO SPRITE GAMBE SX
        ; RISPRISTINA 02
        LDA #05
        STA $02

        ; CHE PRITE GAMBE DEVO VISUALIZZARE ?
        LDA $03
        BNE CAMBIO_GAMBE_SX_1  ; SE = 1 ANIMAZIONE GAMBE 1 
                        
        LDA #1 ; CAMBIO $03 
        STA $03
CAMBIO_GAMBE_SX_0

        LDA #$D7
        JMP AGGIORNA_PUNTAT_GAMBE_SX

CAMBIO_GAMBE_SX_1        
        LDA #0 ; CAMBIO $03 
        STA $03
        ; ANIMAZIONE GAMBE 1:
        LDA #$D8
        
AGGIORNA_PUNTAT_GAMBE_SX
        STA $07F9    ; cambia imamgine sprite (gambe snowman a destra) 
       
        JMP AGGIORNA_POSIZ_PUPAZZO_SX

NON_AGGIORNA_GAMBE_SX
        SEI
        SBC #01
        STA $02 ; DECREMENTO E AGGIORNO $02


AGGIORNA_POSIZ_PUPAZZO_SX
        LDA $D010
        AND #%00000011
        CMP #%00000011       ; X > 255 ?
        beq SINISTRA_SOPRA255
           
        ; verifica se arrivato a bordo sinistro
        ldx $D000
        cpx #$18               ; minima posizione a sinistra  
        beq FINEJOYSTICK       ; non vado più a sinistra di così
        jmp DECREMENTAX  


SINISTRA_SOPRA255
        ; verifica se ero già arrivato a X = 255
        ldx $D000  ; POSIZIONE X PUPAZZO 
        cpx #$00
        bne DECREMENTAX
        LDA $D010
        AND #%11111100 ; AZZERO ULTIMI 2 BIT DI MSB POSIZ X
        STA $D010
        lda #$FF
        sta $D000
        sta $D002     
        jmp FINEJOYSTICK       
DECREMENTAX     
        dec $D000            ; decrementa posizione X sprite 0
        dec $D002           ; decrementa posizione X sprite 1

FINEJOYSTICK
        RTS
; --------------------------------------------------------------------------
CHECK_SPRITES_COLLISIONS
        LDA $D01E        
        TAY ; LO MEMORIZZO PER DOPO PERCHE DOPO AVER LETTO $D01E ESSO SI RESETTA!
        BNE YES_COLLISIONS
        RTS
YES_COLLISIONS
        ; collisione con IL CORPO DEL PUPAZZO ?
        AND #%00000001
        CLC
        LSR A
        BCC NO_COLLISIONE_PUPAZZO
        
        INC $D020         ; cambia colore sfondoschermo (solo c debug)           
        
        ; CON QUALE FIOCCO ?  
        TYA
        AND #%11111100 
        
        LSR A ; Shift Right One Bit
        LSR A ; Shift Right One Bit
        
        ; FIOCCO SPRITE 2 ?
        CLC
        LSR A
        BCC FIOCCO_SP2_NO
        JSR INCREMENTA_PUNTEGGIO
        ; RIPOSIZIONO APPENA FUORI DAL BORDO INFERIORE
        LDX #244
        STX $D005
FIOCCO_SP2_NO        
        ; FIOCCO SPRITE 3 ?
        CLC
        LSR A
        BCC FIOCCO_SP3_NO
        JSR INCREMENTA_PUNTEGGIO
        ; RIPOSIZIONO APPENA FUORI DAL BORDO INFERIORE
        LDX #244
        STX $D007
FIOCCO_SP3_NO        
        ; FIOCCO SPRITE 4 ?
        CLC
        LSR A
        BCC FIOCCO_SP4_NO
        JSR INCREMENTA_PUNTEGGIO
        ; RIPOSIZIONO APPENA FUORI DAL BORDO INFERIORE
        LDX #244
        STX $D009
FIOCCO_SP4_NO        
        ; FIOCCO SPRITE 5 ?
        CLC
        LSR A
        BCC FIOCCO_SP5_NO
        JSR INCREMENTA_PUNTEGGIO
        ; RIPOSIZIONO APPENA FUORI DAL BORDO INFERIORE
        LDX #244
        STX $D00B
FIOCCO_SP5_NO        
        ; FIOCCO SPRITE 6 ?
        CLC
        LSR A
        BCC FIOCCO_SP6_NO  
        JSR INCREMENTA_PUNTEGGIO
        ; RIPOSIZIONO APPENA FUORI DAL BORDO INFERIORE
        LDX #244
        STX $D00D
FIOCCO_SP6_NO        
        ; FIOCCO SPRITE 7 ?
        CLC
        LSR A
        BCC FIOCCO_SP7_NO
        JSR INCREMENTA_PUNTEGGIO
        ; RIPOSIZIONO APPENA FUORI DAL BORDO INFERIORE
        LDX #244
        STX $D00F
FIOCCO_SP7_NO
        

        JSR VISUALIZZA_PUNTEGGIO       


NO_COLLISIONE_PUPAZZO
        RTS

INCREMENTA_PUNTEGGIO        
        ; INCREMENTO PUNTEGGIO E LO STAMPO
        ; incrementa punteggio
        SED ;DECIMAL MODE ON
        CLC 
        LDA PUNTEGGIO
        ADC #1
        STA PUNTEGGIO
        LDA PUNTEGGIO+1
        ADC #0
        STA PUNTEGGIO+2
        CLD  ; DECIMAL MODE OFF
        RTS


*=$1000
music_player
incbin "Last_Christmas.sid", $7e   ; music code and data. Load range: $1000-$34AD


*=$34C0 ; 64 x 211 = $34C0
incbin "snowman.spt",1,2,true
*=$3540 ; 64 x 213 = $3504
incbin "snowman-legs.spt",1,4,true
*=$3640 ; 64 x 217 = $3640
incbin "snowflake.spt",1,1,true



TESTATA_1 text '   snowman by alessandro scola  2022    '
TESTATA_2 text '   music: last christmas by wham        '
TESTATA_3 text 'punteggio:                              '

PUNTEGGIO
        BYTE 0,0,0