RE: [stella] JoustPong: more exciting than ever!

Subject: RE: [stella] JoustPong: more exciting than ever!
From: "Paul Slocum" <paul-stella@xxxxxxxxxxxxxx>
Date: Tue, 24 Feb 2004 15:01:23 -0600
Here's a routine that can display it all without flicker. It needs some work, but the basic setup is there. There's probably enough time for a little more graphically, especially if the WSYNCs are removed. I kinda like the playfield like that, but you could try to make it solid. Or you could color the players. Or maybe make a colorful scrolling background using COLUBK? :o)

-paul
;---------------------------------------------------------------------------
;
; Joustpong Study
;
;---------------------------------------------------------------------------
; TAB = 3
;---------------------------------------------------------------------------

	processor 6502	
	include vcs.h	


;---------------------------------------------------------------------------
; Constants
;---------------------------------------------------------------------------

PHEIGHT equ 16 ; height of player graphics

;---------------------------------------------------------------------------
; RAM Variables 
;---------------------------------------------------------------------------
frame 		equ $80
temp 			equ $81
temp16L 		equ $82
temp16H 		equ $83

leftY 		equ $84
rightY		equ $85
pteryY		equ $86
ballY			equ $87

leftBuf		equ $88
rightBuf		equ $89

saveStack	equ $8A

pfLeftBuf	equ $8C
pfRightBuf	equ $8D

pfArrLeft	equ $90
pfArrRight	equ $a8

;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
	org $F000
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------

				
;---------------------------------------------------------------------------
; Start of Program
;---------------------------------------------------------------------------
; Clear memory, locate character graphics positions and such,
; initialize key memory values, start GameLoop.
;-------------------------------------------------------------
Start
	sei  	
	cld  		
	ldx #$FF
	txs  		
	lda #0
clear   
	sta 0,x
	dex
	bne clear	

;---------------------------------------------------------------------------
; Initialize variables / registers
;---------------------------------------------------------------------------
	stx GRP0
	stx GRP1
	stx PF0
	stx PF1
	stx PF2
	
	; Set background black
	lda #0
	sta COLUBK

	; Set playfield to white
	LDA #$0F
	STA COLUPF



;--------------------------------------------------------------------------
; GameLoop
;--------------------------------------------------------------------------
GameLoop
	jsr VSync 	;start vertical retrace

	inc frame	;count frame

	jsr VBlank    	; spare time during screen blank
	jsr Picture		; draw one screen
	jsr overscan	; do overscan

	jmp GameLoop    ;back to top



;--------------------------------------------------------------------------
; VSync
;--------------------------------------------------------------------------
VSync
	lda #2		;bit 1 needs to be 1 to start retrace
	sta VSYNC	;start retrace
	sta WSYNC 	;wait a few lines
	sta WSYNC 
	lda #44		;prepare timer to exit blank period (44)
	sta TIM64T	;turn it on
	sta WSYNC 	;wait one more
	sta VSYNC 	;done with retrace, write 0 to bit 1

	rts ; VSync



;--------------------------------------------------------------------------
; VBlank
;--------------------------------------------------------------------------
; Game Logic
;--------------------------------------------------------------------------
VBlank

	rts ; VBlank



;--------------------------------------------------------------------------
; Overscan
;--------------------------------------------------------------------------
; More Game Logic
;--------------------------------------------------------------------------
overscan

	sta WSYNC	

	lda #36		; Use the timer to make sure overscan takes (34)
	sta TIM64T	; 30 scan lines.  29 scan lines * 76 = 2204 / 64 = 34.4

endOS	
	lda INTIM	; We finished, but wait for timer
	bne endOS	; by looping till zero
	
	sta WSYNC	; End last scanline

	lda #$82
	sta VBLANK
	lda #$02
	sta VBLANK

	rts	; overscan



;--------------------------------------------------------------------------
; Draw TV Pictures
;--------------------------------------------------------------------------
;
;--------------------------------------------------------------------------
Picture

	; move players and stuff
	inc ballY

	inc leftY
	inc leftY

	dec rightY

	dec pteryY
	dec pteryY

	; generate random wall data for testing
	lda frame
	and #%11111
	bne noBuildPf
	ldx #22
	ldy ballY
pfLoop
	dey
	lda Start,y
	and #%00100000
	sta pfArrLeft,x
	dey
	lda Start,y
	and #%00100000
	sta pfArrRight,x
	dex
	bpl pfLoop
noBuildPf
		
	; setup PF
	lda #1
	sta CTRLPF
	lda #$AF
	sta COLUPF

	; position and setup players
	sta WSYNC
	sta RESM1
	ldx #7
posDelay
	dex
	bne posDelay
	nop
	nop
	sta RESBL
	sta RESP1
	ldx #3
posDelay2
	dex
	bne posDelay2
	sta RESP0
	nop
	sta RESM0
	lda #%00010000
	sta HMP0
	lda #%10000000
	sta HMM0

	sta WSYNC
	sta HMOVE
	lda #$88
	sta COLUP0
	lda #$28
	sta COLUP1
	lda #2
	sta NUSIZ0
	lda #5
	sta NUSIZ1

	; setup stack for PHP trick
	tsx
	stx saveStack
	ldx #ENABL-1
	txs 

pictureLoop
	lda INTIM	;check timer for end of VBLANK period
	bne pictureLoop	;loop until it reaches 0

	sta WSYNC
	lda #$80
	sta VBLANK  	;end screen blank

	ldx #96 ;#192
	jmp scanLoop
	;---------------------------------------------------------------------------


	;-------------------------------------
	; skip draw outside kernal routines

skipDrawLeft         ; 3 from BCC
	LDA #$00          ; 2 load for GRP0
	BEQ continueLeft  ; 3 Return... 

skipDrawRight        ; 3 from BCC
	LDA #$00          ; 2 load for GRP0
	BEQ continueRight ; 3 Return...

skipDrawPtery        ; 3 from BCC
	LDA #$00          ; 2 load for GRP0
	BEQ continuePtery ; 3 Return...

	; --------------- start of main loop
scanLoop:
	; skipDraw routine for left player (21 cycles + 3 for WSYNC)
	TXA                    ; 2 A-> Current scannline
	SBC leftY              ; 3 
	ADC #PHEIGHT           ; 2 calc if sprite is drawn
	sta WSYNC ;***
	BCC skipDrawLeft       ; 2/3 To skip or not to skip?
	TAY                    ; 2 not necessary when Y holds scannline
	LDA data1,Y            ; 4 Select shape
continueLeft:
	STA GRP0               ; 3 Execute Write here!
	sta leftBuf            ; 3 save for next line
	
	lda #0
	sta PF0

	; skipDraw routine for right player (21 cycles)
	TXA                    ; 2 A-> Current scannline
	SBC rightY             ; 3 
	ADC #PHEIGHT           ; 2 calc if sprite is drawn
	BCC skipDrawRight      ; 2/3 To skip or not to skip?
	TAY                    ; 2 not necessary when Y holds scannline
	LDA data2,Y            ; 4 Select shape
continueRight:
	STA GRP0               ; 3 Execute Write here!
	sta rightBuf           ; 3 save for next line

	txa
	lsr
	lsr
	tay

	; --------------- line 2
	sta WSYNC

	lda pfArrLeft,Y
	sta pfLeftBuf
	sta PF0

	; draw left player
	lda leftBuf
	sta GRP0

	; draw ball
	PLA
	CPX ballY
	PHP

	; draw right PF
	lda pfArrRight,Y
	sta PF0

	; draw right player
	lda rightBuf
	sta GRP0

	; skipDraw routine for ptery (18 cycles)
	TXA                    ; 2 A-> Current scannline
	SBC pteryY             ; 3 
	ADC #PHEIGHT           ; 2 calc if sprite is drawn
	BCC skipDrawPtery      ; 2/3 To skip or not to skip?
	TAY                    ; 2 not necessary when Y holds scannline
	LDA data3,Y            ; 4 Select shape
continuePtery:
	STA GRP1               ; 3 Execute Write here!

	dex 
	bne scanLoop
	; --------------- end of kernel

	; blank players
	stx GRP0
	stx GRP1
	stx PF0
	stx ENABL
	stx COLUBK

	; restore stack
	ldx saveStack
	txs

	rts	; Picture

data1
	byte %00111000
	byte %00010000
	byte %00010000
	byte %00010000
	byte %00010000
	byte %00010000
	byte %00110000
	byte %00010000
	byte 0,0,0,0,0,0,0,0

data2
	byte %01111100
	byte %01000000
	byte %00100000
	byte %00010000
	byte %00001000
	byte %00000100
	byte %01000100
	byte %00111000
	byte 0,0,0,0,0,0,0,0

data3
	byte %00111000
	byte %01000100
	byte %00000100
	byte %00011000
	byte %00000100
	byte %00000100
	byte %01000100
	byte %00111000
	byte 0,0,0,0,0,0,0,0


;---------------------------------------------------------------------------
; Program Startup
;---------------------------------------------------------------------------
	org $FFFC
	.word Start
	.word Start

Attachment: pongtest.bin
Description: Binary data

Current Thread