lunedì 9 luglio 2018

Sprites su C64

Un modifica del codice di MoveSprite.asm (qui su GitHub) che mostra due sprite. Il primo sprite
viene ubicato in una coordinata casuale con una routine random del SID. Il primo sprite si puo' muovere e quando tocca il secondo sprite il VIC sente la collisione ed il programma si arresta



Il codice ha una autoload in modo da non essere necessario digitare nessun comando SYS (che in ogni caso e' SYS 2304). Il codice dovrebbe essere sufficientemente commentato

Sviluppato con RelaunchC64 come IDE ed ACME come crosscompiler assembler. Lo sprite e' stato generato con http://www.spritemate.com/  che permette l'export sia in formato ACME che KickAssembler


-----------------------------------------------------------------------------

!cpu 6502
!to "move_2sprite.prg",cbm
; SYS 2034
;*=$0900

; LA DEFINIZIONE DELLE VARIABILI E' IN CODA AL CODICE

!macro start_at .address {
  * = $0801
  !byte $0c,$08,$00,$00,$9e
  !if .address >= 10000 { !byte 48 + ((.address / 10000) % 10) }
  !if .address >=  1000 { !byte 48 + ((.address /  1000) % 10) }
  !if .address >=   100 { !byte 48 + ((.address /   100) % 10) }
  !if .address >=    10 { !byte 48 + ((.address /    10) % 10) }
  !byte $30 + (.address % 10), $00, $00, $00
  * = .address
}

!macro sid_random{
; calcola un valore casuale usando il SID
; il byte random viene salvato nell'accumulatore
LDA #$FF
STA $D40E
STA $D40F
LDA  #$80
STA $D412
LDA $D41B
}

;------------------------------------------------------------------------------------
!macro new_position{  ; cambia la posizione dello sprite 0 in modo casuale

LDA #0 ;stick with x0-255
STA $D010   ; la coordinata X puo' essere maggiore di 255 e non puo' essere
            ; contenuta in un byte. La parte alta e' inserita nella locazione $D010
            ; in questo esempio la parte alta e' settata a zero per imposizione 

+sid_random
TAX
 
ricalcola
+sid_random
CMP #200 ; compara l'accumulatore con 200
BPL ricalcola
; qui c'e' il problema contrario rispetto a X
; la coordinata Y non puo' essere maggiore di 200 mentre un byte puo' essere 255
; quindi cicla nel calcolare numeri casuali fino a che non e' minore di 200

TAY 

STX $D000 ; che contengono la posizione dello sprite 0
STY $D001
}

;------------------------------------------------------------------------------------
+start_at $0900
JSR $E09A


JSR $E544  ; vai alla subroutine che cancella lo schermo 

LDA #13    ; 
STA $C202

LDA #$0D ;ad $7F8 c'e' il puntatore dello sprite 0
STA $7F8    

LDA #$0D ;ad $7F9 c'e' il puntatore dello sprite 1
STA $7F9    


LDA #3 ;abilita lo sprite 0, e' una bit mask
STA $D015   ;che serve ad abilitare tutti gli sprite
;abilitare sprite 0 ed 1 si inserisce 3 (11b)

LDA #02 ; in D027 c'e' il colore dello sprite 0
STA $D027   ; viene inserito il valore 2 ovvero rosso

; setta il colore dello sprite 1
LDA #03
STA $D028

LDX #0
LDA #0

;a $0340 c'e' la locazione di memoria dello sprite 0
;ogni sprite e' lungo 63 byte (piu' un byte non utilizzato)
;il codice successivo cicla per pulire l'area di memoria
CLEANUP0 STA $0340,X  
INX
CPX #63
BNE CLEANUP0

;ripulisce l'area dello sprite 1
LDX #0
CLEANUP1 STA $0340,X  
INX
CPX #63
BNE CLEANUP1



;dopo aver ripulito l'area di memoria la riempie con
;la matrice DATA
LDX #0
BUILD LDA DATA,X
STA $0340,X
INX
CPX #63
BNE BUILD

;position
+new_position

;setta le variabili dello sprite 1
LDX #100 ; 
LDY #100  ;  
STX $D002 ;
STY $D003


SCAN JSR $FF9F ;richiede al Kernal lo stato della tastiera
JSR $FFE4 ;richiede al Kernal il valore del default input
        
;sposta lo sprite a seconda dello stato tastiera
START CMP #87 ;W - up
BEQ UP

CMP #83 ;S - down
BEQ DOWN

CMP #65 ;A - left
BEQ LEFT

CMP #68 ;D - right
BEQ RIGHT

CMP $C202 ;end if enter clicked
BEQ END

; controlla se ci sono state collision
LDA $D01E ; byte di collisione hardware tra sprite 
CMP #0
BNE END

JMP SCAN

UP LDY $D001 ; carica la posizione Y dello sprite in Y
DEY       ; decrementa Y (il sistema di riferimento e' rovesciato)
STY $D001 ; ed aggiorna la posizione dello sprite
;+new_position
JMP SCAN

DOWN         LDY $D001
INY
STY $D001
JMP SCAN

LEFT         LDX $D000
DEX
STX $D000
CPX #255
BNE SCAN
LDA #0
STA  $D010
JMP SCAN

RIGHT         LDX $D000
INX
STX $D000
CPX #255
BNE SCAN
LDA #1
STA  $D010
JMP SCAN


;clean up at the end
END JSR $E544 ; pulisce lo schermo
LDA #0    ; disabilita lo sprite 0
STA $D015
RTS       ; ritorna al prompt

;define the sprite
DATA !byte $00,$00,$00,$00,$00,$00,$00,$00
!byte $00,$00,$00,$00,$00,$00,$00,$00
!byte $38,$00,$00,$fc,$00,$00,$f2,$00
!byte $01,$c3,$00,$01,$89,$80,$03,$80
!byte $c0,$03,$83,$c0,$03,$82,$00,$07
!byte $03,$00,$07,$01,$80,$00,$c0,$80
!byte $00,$79,$80,$00,$0f,$00,$00,$00
!byte $00,$00,$00,$00,$00,$00,$00,$08

Nessun commento:

Posta un commento

Dockerizza Flask

Un esempio semplice per inserire in un container Docker una applicazione Flask Partiamo da una semplice applicazione che ha un file app.py ...