1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-06-10 21:29:33 +00:00
8bitworkshop/presets/vcs/examples/sethorizpos.a
2019-07-20 11:04:24 -04:00

141 lines
3.2 KiB
Plaintext

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