Re: [stella] RPG Kernal

Subject: Re: [stella] RPG Kernal
From: Paul Slocum <paul-stella@xxxxxxxxxxxxxx>
Date: Fri, 18 Apr 2003 10:14:17 -0500

You should try the phosphorescent effect of the lastest z26win.

Cool, I didn't realize there was a new version.


1. You should reverse the use of X and Y here:

Done.


2. Rewrite the code above into:

Done. Nice trick.


3. Inside the kernel, why are you *always* using X for storing HMMx
and COLUPF?

I was moving stuff around a lot for a while. It was easier to move stuff around in the kernal.


4. Maybe using VDELPx for at least one player might help making your
timing a bit easier.

Since the timing works, I don't want to touch it. I was originally using VDELPx for both, but I decided to stop using it.


5. Kernel: sta $2d ???

Waste 3 cycles. I guess it'd be better to use NOOP.


6. Why no source code? ;-)

It's messy. I cleaned it up a little. The kernal cycle counts are not correct.


-Paul
;---------------------------------------------------------------------------
;
; 2600 RPG
;
;---------------------------------------------------------------------------

	processor 6502	
	include vcs.h	

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

;---------------------------------------------------------------------------
; RAM Variables 
;---------------------------------------------------------------------------

; Each levelData line is 5 bytes
; Other variables can be placed between the blocks
levelDataA	equ $80

frame 		equ $85
temp 			equ $86
temp2			equ $87

levelDataB	equ $88

linecolor	equ $8D
bkcolor		equ $8E
room			equ $8F

levelDataC	equ $90

levelDataD	equ $98

levelDataE	equ $A0

levelDataF	equ $A8

levelDataG	equ $B0

levelDataH	equ $B8

levelDataI	equ $C0

levelDataJ	equ $C8


grfxBuffer	equ $CD ; (20 bytes)




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

	; Character Font
	include rpgfont.h 


;---------------------------------------------------------------------------
; println
;---------------------------------------------------------------------------
; New version of David Cranes flicker text from Stellar Track/Basic Programming
;---------------------------------------------------------------------------


; grfxBuffer offsets
; x     x     x     x     x
;00 02 04 06 08 10 12 14 16 18
; A  B  C  D  E  F  G  H  I  J
;    x     x     x     x     x



;	align 256
println
;	ldx #1
;	stx frame

	ldy #9						;2

	lda (grfxBuffer + 18),y	;5
	tax

;	lda #$10

	lda frame
	and #1
	beq noShift

	lda (grfxBuffer + 16),y	;5
	tax

	lda #$80
	sta HMP0
	sta HMP1

	sta WSYNC
	sta HMOVE
	sta HMCLR
	jmp frameB

	bne frameA
noShift
	sta WSYNC
	sta HMCLR
	sta $2D

frameA ;@3
	stx GRP0						;3
	nop
	jmp enterA

loopA ;@21
	lda (grfxBuffer + 18),y	;5 @3
	sta GRP0						;3
enterA
	lda (grfxBuffer + 14),y	;5
	sta GRP1						;3

	sta HMCLR

	ldx.w linecolor				;3 @30

	lda (grfxBuffer + 10),y	;5
	stx COLUPF					;3
	
	sta GRP0						;3
	lda (grfxBuffer + 6),y	;5
	sta GRP1						;3 @49

	lda (grfxBuffer + 2),y	;5
	sta GRP0						;3
	lda bkcolor					;3 @59
	sta COLUPF					;3 @66
	dey							;2

	ldx #$80						;2
	stx HMP0						;3 
	stx HMP1						;3 @72

	nop
	nop
	sta HMOVE					;3 @3

	;--------------------------

	lda (grfxBuffer + 16),y	;5
	sta GRP0						;3
	lda (grfxBuffer + 12),y	;5
	sta.w GRP1					;3 @20

	nop							;2
	nop							;2

	ldx.w linecolor			;3 @30
	lda (grfxBuffer + 8),y	;5
	stx COLUPF					;3
	ldx #$80						;2
	sta GRP0						;3
	lda (grfxBuffer + 4),y	;5
	sta GRP1						;3 @49

	lda (grfxBuffer + 0),y	;5
	sta GRP0						;3
	lda bkcolor					;2 @59
	sta COLUPF					;3 @66
	sta HMCLR					;3 
	stx HMM0
	nop
	sta HMOVE					;3 @74
	sta $2D
	;-------------------------

	dey							;2
	bpl loopA					;2/3

quitA
	lda #0
	sta GRP0
	sta GRP1
	rts	


	;====================================
	;====================================
	;====================================

frameB ;@7
	lda (grfxBuffer + 12),y	;5
	sta GRP1						;3
	stx GRP0						;3
	nop
	nop
	;sta $2D
;	dec $2D						;5 delay
loopB ;@24
	ldx linecolor				;3 @27

	lda (grfxBuffer + 8),y	;5
	stx.w COLUPF				;3
	ldx #$80						;2
	sta GRP0						;3
	lda (grfxBuffer + 4),y	;5
	sta GRP1						;3 @46

	lda (grfxBuffer + 0),y	;5
	sta GRP0						;3
	lda bkcolor					;2 @56
	sta COLUPF					;3 @63
	stx HMCLR					;3 
	stx HMM0						;3
	nop							;2
	sta HMOVE					;3 @74

	;--------------------------
	sta HMCLR
	dey							;2 @0
	lda (grfxBuffer + 18),y	;5
	sta.w GRP0						;3
	lda (grfxBuffer + 14),y	;5
	sta GRP1						;3 @21

	nop
;	ldx #$80						;2
	stx HMP0					;4

	ldx linecolor			;3 @30
	lda (grfxBuffer + 10),y	;5
	stx COLUPF					;3
	sta GRP0						;3
	lda (grfxBuffer + 6),y	;5
	sta GRP1						;3 @51

	lda (grfxBuffer + 2),y	;5
	sta GRP0						;3
	ldx #$80							;2
	lda bkcolor					;2 @61
	sta COLUPF					;3 @66
	dey							;2

	bmi quitB					;2/3
	stx HMP1						;3 @69
	sta WSYNC					;3 @0
	sta HMOVE					;3 @3

	lda (grfxBuffer + 16),y	;5
	sta GRP0						;3
	lda (grfxBuffer + 12),y	;5
	sta GRP1						;3 @19

	nop
	jmp loopB
	bpl loopB					;2/3

quitB
	sta WSYNC
	jmp quitA


				
;---------------------------------------------------------------------------
; 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
;---------------------------------------------------------------------------

	;lda #255 ; Solid PF for debugging
	lda #%11001100
	sta PF0
	sta PF2
	lda #%00110011
	sta PF1

	; Set background color (remove later)
	lda #$C0
	sta bkcolor

	; Set players to grey
	lda #$08
	sta COLUP0
	sta COLUP1

;	lda #1
;	sta room

	jsr TextSetup

	jsr loadRoom

	;-----------------------------------------------------
	;the entire font is limited to one page, so we can hard code that page
	;value into the MSB position of our graphics buffer
	;-----------------------------------------------------
	ldx #23         ;graphics buffer is 24 bytes
	lda #>charData   ;load up the page value for the font
grOff
	sta grfxBuffer,x        ;stuff it, won't ever change
	dex             ;back up two bytes
	dex
	bpl grOff       ;and loop

	lda #0
	sta CTRLPF

;--------------------------------------------------------------------------
; GameLoop
;--------------------------------------------------------------------------
GameLoop
	jsr VSync 	;start vertical retrace
	jsr VBlank    	; spare time during screen blank
	jsr Picture		; draw one screen
	jsr overscan	; do overscan

	jmp GameLoop    ;back to top

;--------------------------------------
; TextSetup
;--------------------------------------
;use cycle counting to get the GRP registers configured and located
;in exactly the right spot
;--------------------------------------
TextSetup
	sta WSYNC       ;newline
	sta RESM1
	lda #$36        ;triple copy sprites, spaced wide
	sta NUSIZ0      ;for both player graphic registers
	lda #$32
	sta NUSIZ1
	lda #%01000000
	sta HMM0
	nop
	nop
;	nop
	sta temp
	sta $2D
	sta $2D
	sta RESP0
	lda #$F0
	sta RESP1
	sta HMP0
	lda #$E0
	sta HMP1
;	sta HMM1
	dec $2D
	dec $2D
	nop
	nop
	
	sta RESM0

	sta WSYNC       ;newline
	sta HMOVE       ;anchor them down
	rts

;--------------------------------------------------------------------------
; 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



;--------------------------------------------------------------------------
; loadRoom
;--------------------------------------------------------------------------
loadRoom
	ldx room
	lda levelBk,x
	sta bkcolor
	inx
	lda times10,x
	lsr
	tax

;	ldx #10
	
	ldy #4
CopyLoop
	dex 

	lda levelA,x
	sta levelDataA,y 
	lda levelB,x
	sta levelDataB,y 
	lda levelC,x
	sta levelDataC,y 
	lda levelD,x
	sta levelDataD,y 
	lda levelE,x
	sta levelDataE,y 

	lda levelF,x
	sta levelDataF,y 
	lda levelG,x
	sta levelDataG,y 
	lda levelH,x
	sta levelDataH,y 
	lda levelI,x
	sta levelDataI,y 
	lda levelJ,x
	sta levelDataJ,y 

	dey
	bpl CopyLoop
	rts


;--------------------------------------------------------------------------
; VBlank
;--------------------------------------------------------------------------
; Game Logic
;--------------------------------------------------------------------------
VBlank
	inc frame	;count frame
	bne sameRoom
	
	lda room
	eor #1
	sta room

sameRoom

	jsr loadRoom

;	jsr TextSetup

	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

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

	sta HMCLR

;---------------------------------------------------------------------------
	ldx #18
ScanLoop3:
	sta WSYNC
	dex
	bne ScanLoop3

	lda #$08
	sta COLUPF
	lda #255
	sta ENAM0
	sta PF1
	sta PF2
	sta PF0

	sta WSYNC
	sta WSYNC
	sta WSYNC
	lda bkcolor
	sta COLUPF
	sta COLUBK

	lda #0
	sta PF1
	sta PF0
	sta PF2
ScanLoop:
;	ldy #25
;	sty TIM8T
;	sta WSYNC
	tax

	lda levelDataA,x
	and #$0F
	tay
	lda charOffsets,y
	sta grfxBuffer+16
	tya
	eor levelDataA,x
	tay
	lda charOffsets,y
	sta grfxBuffer+18

	lda levelDataA+1,x
	and #$0F
	tay
	lda charOffsets,y
	sta grfxBuffer+12
	tya
	eor levelDataA+1,x
	tay
	lda charOffsets,y
	sta grfxBuffer+14

	lda levelDataA+2,x
	and #$0F
	tay
	lda charOffsets,y
	sta grfxBuffer+8
	tya
	eor levelDataA+2,x
	tay
	lda charOffsets,y
	sta grfxBuffer+10

	lda levelDataA+3,x
	and #$0F
	tay
	lda charOffsets,y
	sta grfxBuffer+4
	tya
	eor levelDataA+3,x
	tay
	lda charOffsets,y
	sta grfxBuffer+6

	lda levelDataA+4,x
	and #$0F
	tay
	lda charOffsets,y
	sta grfxBuffer+0
	tya
	eor levelDataA+4,x
	tay
	lda charOffsets,y
	sta grfxBuffer+2

	txa
	clc
	adc room
	tay
	lda pfData0,y
	sta PF0
	lda pfData1,y
	sta PF1
	lda pfData2,y
	sta PF2
	lda pfColor,y
	sta linecolor

	stx temp2
	
textTimer
;	ldy INTIM
;	bne textTimer

	;sta WSYNC

	jsr println
	lda temp2
	
	clc
	adc #$08
	cmp #$50
	beq quitScanLoop
	jmp ScanLoop
quitScanLoop


	sta WSYNC
	sta WSYNC
	lda #$08
	sta COLUPF
	lda #255
	sta PF0
	sta PF1
	sta PF2	
	sta WSYNC
	sta WSYNC
	sta WSYNC
	lda #0
	sta ENAM0
	sta COLUPF
	sta COLUBK

	ldx #26
ScanLoop2:
	sta WSYNC
	dex
	bne ScanLoop2

	lda #0
	sta COLUBK
	sta COLUPF

	rts	; Picture


	; Level Data

levelA
	byte $90,$00,$00,$00,$00
	byte $a9,$aa,$99,$a9,$9a
levelB
	byte $78,$70,$65,$00,$60
	byte $00,$00,$00,$00,$a9
levelC
	byte $00,$00,$00,$00,$09
	byte $a9,$90,$00,$00,$9a
levelD
	byte $05,$60,$00,$00,$00
	byte $9a,$a9,$90,$9a,$9a
levelE
	byte $00,$00,$50,$00,$11
	byte $11,$11,$1b,$11,$11

levelF
	byte $00,$60,$00,$01,$11
	byte $11,$11,$1b,$11,$11
levelG
	byte $05,$55,$00,$01,$11
	byte $99,$00,$00,$aa,$9a
levelH
	byte $05,$06,$50,$11,$11
	byte $9a,$99,$00,$09,$a9
levelI
	byte $50,$50,$11,$11,$11
	byte $aa,$90,$00,$09,$9a
levelJ
	byte $11,$11,$11,$11,$11
	byte $9a,$90,$00,$9a,$9a

times10
	byte 0,10,20,30,40,50,60,70,80,90,100
	byte 100,110,120,130,140,150,160,170,180,190,200
pfData0 ; right of center, backwards
	byte %00000000,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00000000,%11000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00000000,%11000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

	byte %00000000,%11000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00000000,%11000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %11000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %11110000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %11110000,%11000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
pfData1 ; right side, forwards, last two bits are far left
	byte %00000011,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00000011,%00111100,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00001100,%00111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00000000,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00111100,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

	byte %11111100,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %11111100,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %11111100,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %11111100,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %11111111,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
pfData2 ; left side, backwards
	byte %00000000,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00001111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00000000,%00001111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00000000,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00000000,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

	byte %00000000,%11111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00000000,%00000011,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %00000000,%00111111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %11000000,%00001111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
	byte %11111111,%00001111,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
pfColor
	byte $d0,$f0,$30,$40,$50,$60,$70,$80
	byte $02,$f0,$30,$40,$50,$60,$70,$80
	byte $d0,$f0,$30,$40,$50,$60,$70,$80
	byte $82,$f0,$30,$40,$50,$60,$70,$80
	byte $82,$80,$30,$40,$50,$60,$70,$80

	byte $82,$80,$30,$40,$50,$60,$70,$80
	byte $82,$f0,$30,$40,$50,$60,$70,$80
	byte $82,$f0,$30,$40,$50,$60,$70,$80
	byte $82,$f0,$30,$40,$50,$60,$70,$80
	byte $82,$f0,$30,$40,$50,$60,$70,$80
levelBk
	byte $C0
	byte $e0


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

Current Thread