processor 6502 include "vcs.h" include "macro.h" include "xmacro.h" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; We're going to set the player's coarse and fine position ; at the same time using a clever method. ; We divide the X coordinate by 15, in a loop that itself ; is 15 cycles long. When the loop exits, we are at ; the correct coarse position, and we set RESP0. ; The accumulator holds the remainder, which we convert ; into the fine position for the HMP0 register. ; This logic is in a subroutine called SetHorizPos. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SpriteHeight equ 8 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Variables segment seg.u Variables org $80 XPos .byte YPos .byte ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Code segment seg Code org $f000 Start CLEAN_START lda #5 sta YPos sta XPos NextFrame lsr SWCHB ; test Game Reset switch bcc Start ; reset? ; 1 + 3 lines of VSYNC VERTICAL_SYNC ; 35 lines of underscan ldx #35 LVBlank sta WSYNC dex bne LVBlank ; animate X and Y coordinates ; NOTE: when X is too close to the right side, ; we risk using an extra scanline inc XPos inc YPos ; the next two scanlines ; position the player horizontally lda XPos ; get X coordinate ldx #0 ; player 0 jsr SetHorizPos ; set coarse offset sta WSYNC ; sync w/ scanline sta HMOVE ; apply fine offsets ; 192 lines of frame ldx #192 ; X = 192 scanlines LVScan txa ; X -> A sec ; set carry for subtract sbc YPos ; local coordinate cmp #SpriteHeight ; in sprite? bcc InSprite ; yes, skip over next lda #0 ; not in sprite, load 0 InSprite tay ; local coord -> Y lda Frame0,y ; lookup color sta WSYNC ; sync w/ scanline sta GRP0 ; store bitmap lda ColorFrame0,y ; lookup color sta COLUP0 ; store color dex ; decrement X bne LVScan ; repeat until 192 lines ; 29 lines of overscan ldx #29 LVOver sta WSYNC dex bne LVOver ; total = 262 lines, go to next frame jmp NextFrame ; SetHorizPos routine ; A = X coordinate ; X = player number (0 or 1) SetHorizPos sta WSYNC ; start a new line sec ; set carry flag DivideLoop sbc #15 ; subtract 15 bcs DivideLoop ; branch until negative eor #7 ; calculate fine offset asl asl asl asl sta RESP0,x ; fix coarse position sta HMP0,x ; set fine offset rts ; return to caller ; Cat-head graphics data Frame0 .byte #0 ; zero padding, also clears register .byte #%00111100 .byte #%01000010 .byte #%11100111 .byte #%11111111 .byte #%10011001 .byte #%01111110 .byte #%11000011 .byte #%10000001 ; Cat-head color data ColorFrame0 .byte #0 ; unused (for now) .byte #$AE .byte #$AC .byte #$A8 .byte #$AC .byte #$8E .byte #$8E .byte #$98 .byte #$94 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Epilogue org $fffc .word Start ; reset vector .word Start ; BRK vector