[stella] Death Derby, new build

Subject: [stella] Death Derby, new build
From: Glenn Saunders <cybpunks2@xxxxxxxxxxxxx>
Date: Sat, 06 Oct 2001 20:57:07 -0700

In this build a lot of the stuff is laid out in memory, the sprites et. al.


I actually have a car showing up, but I don't like the routines that handle the logic. Too much RAM and cycles.

I tried to use indirect addressing to set up pointers to the start of car sprite ROM in order to handle the rotations but I don't think I understand how to do this properly. I had to go back to hardcoding it to one car shape.

Please assist :)


Glenn Saunders - Producer - Cyberpunks Entertainment Personal homepage: http://www.geocities.com/Hollywood/1698 Cyberpunks Entertainment: http://cyberpunks.uni.cc

Attachment: DD_0005.bin
Description: Binary data

;Death Derby 2001
; By Glenn Saunders

;LINEAGE:

; How to Draw an Asymmetric Reflected Playfield
; by Roger Williams
; Reflected mode modifications by Glenn Saunders

; with a lot of help from Nick Bensema
; (this started out as his "How to Draw a Playfield")



;
	processor 6502
	include vcs.h

; CONSTANTS
RowHeight 	= 16
RowsPerScreen 	= 10	; 11+1 = 12 rows
SafeZone	= %10010000

    SEG.U vars
    org $80

Temp       	ds 1
CurrentScanLine ds 1
CurrentRowCounter    	ds 1
CurrentRow 	ds 1
PFColorRAM 	ds 1
PF1DataRAM	ds 11
PF2DataRAM	ds 11
PF1bDataRAM	ds 11
PF2bDataRAM	ds 11
RowScroller	ds 1

;sprite positiong
P0_X		ds 1
P0_Y		ds 1
P0_YC		ds 1

P1_X		ds 1
P1_Y		ds 1
P1_YC		ds 1

M0_X		ds 1
M0_Y		ds 1

M1_X		ds 1
M1_Y		ds 1



P0_CurrentFramePtr ds 2
P1_CurrentFramePtr ds 2
M0_CurrentFramePtr ds 2
M1_CurrentFramePtr ds 2

P0_CurrentRowCounter ds 1
P1_CurrentRowCounter ds 1
M0_CurrentRowCounter ds 1
M1_CurrentRowCounter ds 1


    SEG code
    org  $F000

;FrameCounter = $93 was going to try some color cycling


Start
	SEI  ; Disable interrupts, if there are any.
	CLD  ; Clear BCD math bit.
	LDX  #$FF
	TXS  ; Set stack to beginning.
	

	; CLEAR OUT RAM
	LDA #0
KeepZeroing
	STA 0,X
	DEX
	BNE KeepZeroing

SetColors
	LDA #0
	STA COLUBK  ; Background will be black.
	
	LDA #$34 ; set playfield color to deep red
	STA COLUPF
	
	LDA #PF_Reflect
	STA CTRLPF  ; set playfield to reflect

	LDA #$FF; set the cars to white for now
	STA COLUP0
	STA COLUP1
	
	
InitializeSprites
	LDA #30
	STA P0_X
	LDA #50
	STA P0_Y
	LDA #8; start out on the 8th row and decrement
	STA P0_CurrentRowCounter

	; I can't get this to work!!

	LDA #<CarRotation0
	STA P0_CurrentFramePtr
	LDA #>CarRotation0
	STA P0_CurrentFramePtr+1
	


	; I know there is a way to do this cleaner
	LDX #RowsPerScreen
InitializeTombstones; copy from ROM to RAM
	LDA PF1Data,X
	STA PF1DataRAM,X

	LDA PF2Data,X
	STA PF2DataRAM,X

	LDA PF1bData,X
	STA PF1bDataRAM,X

	LDA PF2bData,X
	STA PF2bDataRAM,X
	
	DEX
	BNE InitializeTombstones

	LDA PF1Data
	STA PF1DataRAM

	LDA PF2Data
	STA PF2DataRAM

	LDA PF1bData	
	STA PF1bDataRAM

	LDA PF2bData
	STA PF2bDataRAM


MainLoop
	JSR VBArea
	JSR DrawScreen
	JSR OverScan
	JMP MainLoop      ;Continue forever.




;SUB
ClearTombstones
	LDX RowScroller
KeepClearing 
	DEX
	STA <PF1DataRAM,X
	STA <PF2DataRAM,X
	STA <PF1bDataRAM,X
	STA <PF2bDataRAM,X
	BNE KeepClearing
	RTS  
	

;SUB
OverScan
	LDX #22


KillLines
	STA WSYNC
	DEX
	BNE KillLines
	RTS

;HORIZONTAL POSITIONING SUBROUTINE FROM MANUEL POLIK's GUNFIGHT	
;SUB (alternate beginning of below)
PosP1
            CLC 
            ADC #$08
;SUB
PosP0
            CMP #$A0
            BCC NH2
            SBC #$A0
NH2
            TAY
            LSR
            LSR
            LSR
            LSR
            STA Temp
            TYA
            AND #15
            CLC
            ADC Temp
            LDY Temp
            CMP #15
            BCC NH
            SBC #15
            INY
NH
            EOR #7
            ASL
            ASL
            ASL
            ASL
            STA HMP0,x
            INY                         ; Waste 5 cycles, 1 Byte
            STA WSYNC
            INY                         ; Waste 7(!) cycles, 1 Byte
            BIT 0                       ; Waste 3 cycles, 2 Byte
PosDelay    DEY
            BPL PosDelay
            STA RESP0,x
            RTS
;/HORIZONTAL POSITIONING SUBROUTINE	
	
;SUB
VBArea
        LDX #0
        LDA P0_X
        JSR PosP0

RestoreYCounters
	LDA P0_Y
	STA P0_YC

        
 	LDX  #0	   ;vertical blank
	LDA  #2
	STA  WSYNC
	STA  WSYNC
	
HMOVEDelay          
	DEX
        BNE HMOVEDelay
        STA  HMOVE           ; Do it on cycle 74!!!
	STA  WSYNC

	
	STA  VSYNC ;Begin vertical sync.
	STA  WSYNC ; First line of VSYNC
	STA  WSYNC ; Second line of VSYNC.

	LDA  #44   ;init timer for overscan
	STA  TIM64T

	STA  WSYNC ; Third line of VSYNC.
	STA  VSYNC ; (0)




VBLOOP	LDA INTIM
	BNE VBLOOP ; Whew!
	

	
	STA WSYNC


	STA VBLANK  ;End the VBLANK period with a zero.
	


	;STA PFColorRAM
	;
	LDA #200 
	STA CurrentScanLine
	LDA #RowHeight
	STA CurrentRowCounter

	;
	; The height of the screen is not an even multiple of 36
	; (the character height including blank.)  Here we waste
	; the extra lines.
	;
	; NB we may do away with this by adding 2 scans to each
	; char in the blank or fore and aft bigpix lines
	;

	LDA #0
	STA PF0
	STA PF1
	STA PF2; zero out playfield
	RTS

;SUB
DrawScreen
	LDX #23	; reserve 15 CurrentScanLines for the score
DrawScore
	STA WSYNC
	DEC CurrentScanLine
	DEX
	BNE DrawScore


	LDX #RowsPerScreen
	
TopBorder ; 2 lines
	LDA #$FF 
	
	STA PF0 ; draw a solid line
	STA PF1
	STA PF2
	DEC CurrentScanLine
	STA WSYNC

	LDY #SafeZone
	STY PF0 ; now PF0 is in the proper shape for the rest of the screen
	
	;A is still $FF
	STA PF1
	STA PF2
	;NO WSYNC necessary here because ScanGo will finish the line off

ScanLoop
	DEC CurrentRowCounter		;next screen pixel line
	BNE ScanGo

	LDA #RowHeight; if counter reaches zero, reset to 15
	STA CurrentRowCounter
	DEX			;next big pixel line
	BNE ScanGo
	;LDX #10
ScanGo
	STA WSYNC
	; Time to begin cycle counting

				;	0
	;STA.W HMOVE		;+4	4
	
	NOP 			;+2	2
	NOP			;+2	4
	
	;will probably have to do an HMOVE on every line to 
	;simplify logic.  HMOVE is only necessary for the missiles

	LDA <PF1DataRAM,X       ;+4	8
	STA PF1               	;+3  = *11*  < 29	;PF1 visible
	
	LDA <PF2DataRAM,X       ;+4	15
	STA PF2                 ;+3  = *19*  < 40	;PF2 visible

	nop			;+2	20
	nop			;+2	22
	nop			;+2	24
	nop			;+2	26
	nop			;+2	28
	nop			;+2 	30
	nop			;+2	32
	nop			;+2	34
	
	LDA <PF1bDataRAM,X	;+4	38

	;PF1 no longer visible, safe to rewrite
	STA PF1			;+3 = *41*


	LDA <PF2bDataRAM,X	;+3     44
	
	;PF2 rewrite must begin at exactly cycle 45!!, no more, no less
	STA PF2			;+3  = *47*  ; > 46 PF2 no longer visible



	DEC CurrentScanLine
	BNE ScanLoop2
	;
	LDA #2
	STA WSYNC  ;Finish CurrentScanLine 189.
	JMP DoBorder

ScanLoop2
	DEC CurrentRowCounter		;next screen pixel line
	BNE ScanGo2

	LDA #RowHeight; if counter reaches zero, reset to 15
	STA CurrentRowCounter
	DEX			;next big pixel line
	BNE ScanGo2
	

ScanGo2; do all the sprite routines here
	STA WSYNC
	TXS
	LDY #0
	STY PF1
	STY PF2

P0Loop

	DEC P0_YC		;count down to sprite line
	BNE ContinueOn ; skip sprite until P0_YC = zero


	; begin draw sprite
	DEC P0_CurrentRowCounter ; -1
	BEQ EndLoop ; draw sprite until PO_CurrentRowCounter = Zero

	;LDY #$FF
	LDX P0_CurrentRowCounter 
	
	LDA CarRotation0,X
	;LDA (P0_CurrentFramePtr,X)
	
	TAY

	INC P0_YC
	JMP ContinueOn


EndLoop
	LDA  #8
	STA P0_CurrentRowCounter ; reset to 8
	LDA #255
	STA P0_YC ; this will never wrap back around by screen end
		  ; which has the effect of cancelling out the sprite
		  ; for the rest of the screen

ContinueOn
	STY GRP0
	TSX
	DEC CurrentScanLine
	BNE ScanLoop

	



DoBorder
	LDA #$FF
	STA PF0
	STA PF1
	STA PF2
	STA WSYNC
	STA WSYNC
	
	
	STA VBLANK ; Make TIA output invisible,
	
	LDA #0
	STA PF0
	STA PF1
	STA PF2
	STA GRP0
	STA GRP1
	STA ENAM0
	STA ENAM1
	STA ENABL
	
	RTS; END DrawScreen






	org $FF00 ; *********************** GRAPHICS DATA
	; align with a page boundary

;THE GRAPHICS        

;FRAME POINTERS
;CarRotationPtrTable 
;	.byte #<CarRotation0 ,#>CarRotation0
;	.byte #<CarRotation1 ,#>CarRotation1
;	.byte #<CarRotation2 ,#>CarRotation2
;	.byte #<CarRotation3 ,#>CarRotation3
;	.byte #<CarRotation4 ,#>CarRotation4


CarRotation0   
  .byte %00000000; ........
  .byte %11101110; XXX.XXX.
  .byte %01100100; .XX..X..
  .byte %11011111; XX.XXXXX
  .byte %11011111; XX.XXXXX
  .byte %01100100; .XX..X..
  .byte %11101110; XXX.XXX.
  .byte %00000000; ........

CarRotation1   
  .byte %00000100; .....X..
  .byte %00011100; ...XXX..
  .byte %11000111; XX...XXX
  .byte %11111111; XXXXXXXX
  .byte %01011110; .X.XXXX.
  .byte %01100011; .XX...XX
  .byte %00110010; ..XX.X..
  .byte %00110000; ..XX....

CarRotation2
  .byte %00010000; ...X....
  .byte %00110110; ..XX.XX.
  .byte %00011110; ...XXXX.
  .byte %11011100; XX.XXX..
  .byte %11011011; XX.XX.XX
  .byte %01000010; .X....X.
  .byte %01111000; .XXXX...
  .byte %00011000; ...XX...

CarRotation3   
  .byte %00000000; ..X.XX..
  .byte %00000000; ..XXXX..
  .byte %00000000; .X.XXXXX
  .byte %00000000; ...XX.X.
  .byte %00000000; XX.XX.X.
  .byte %00000000; XXX.X...
  .byte %00000000; ..XXXX..
  .byte %00000000; ....XX..
 
CarRotation4
  .byte %00011000; ...XX...
  .byte %01011010; .X.XX.X.
  .byte %01111110; .XXXXXX.
  .byte %01011010; .X.XX.X.
  .byte %00011000; ...XX...
  .byte %01100110; .XX..XX.
  .byte %01111110; .XXXXXX.
  .byte %01011010; .X.XX.X.


;missiles are used as pseudoplayers
;data is encoded as width and pixel offsets.

;76543210
;XXXX    <- OFFSET (typically 0 through +8 pixels)
;    XX  <- NUSIZ data

;EXAMPLE:
;LDA (M0_ShapeFrame,X)
;STA HMM0
;LSL
;LSL
;STA NUSIZ0

Ped1_1;   OOOOWW__
   .byte %11110100 ; .XX.....
   .byte %11100000 ; ..X.....
   .byte %11011000 ; ...XXXX.
   .byte %11010100 ; ...XX...
   .byte %11111000 ; .XXXX...
   .byte %00000000 ; ........
   .byte %11010100 ; ...XX...
   .byte %11010100 ; ...XX...
   
Ped1_2;   OOOOWW__
   .byte %11010100 ; ...XX...
   .byte %11010100 ; ...XX...
   .byte %11010100 ; ...XX...
   .byte %11010100 ; ...XX...
   .byte %11010100 ; ...XX...
   .byte %00000000 ; ........
   .byte %11010100 ; ...XX...
   .byte %11010100 ; ...XX...

Ped1_3;   OOOOWW__
   .byte %11110100 ; .XX.....
   .byte %00000000 ; ..X.....
   .byte %11011100 ; ...XXXX.
   .byte %11100100 ; ..XX....
   .byte %11010100 ; ...XX...
   .byte %00000000 ; ........
   .byte %11010100 ; ...XX...
   .byte %11010100 ; ...XX...

Ped1_4;   OOOOWW__
   .byte %11011100 ; ...XXXX.
   .byte %11010000 ; ...X....
   .byte %11011100 ; ...XXXX.
   .byte %11010100 ; ...XX...
   .byte %00001100 ; XXXX....
   .byte %11101100 ; ..XXXX..
   .byte %11110100 ; .XX.....
   .byte %11110100 ; .XX.....



;               REFLECTED  PLAYFIELD            
;                                               
; PF0|   PF1  |  PF2   ||   PF2b |   PF1b |PF0b|
;4567|76543210|01234567||76543210|01234567|7654|


;SafeZone ;     7654----
;	.byte %10011001

PF1Data  ;D    76543210


	.byte %01111001
	.byte %01000101
	.byte %01000101
	.byte %01000101
	.byte %01111001
	.byte %00000000
	.byte %01111001
	.byte %01000101
	.byte %01000101
	.byte %01000101
	.byte %01111001

	
PF2Data  ;EA   01234567
	.byte %00101111
	.byte %10100000
	.byte %11100111
	.byte %00100000
	.byte %11101111
	.byte %00000000
	.byte %00101111
	.byte %00100000
	.byte %11100111
	.byte %00100000
	.byte %11101111	

PF2bData ;     76543210;<--- scanning order

	.byte %11011110
	.byte %00010001
	.byte %10011110
	.byte %01010001
	.byte %10011110
	.byte %00000000
	.byte %01000100
	.byte %01000100
	.byte %11000100
	.byte %01000100
	.byte %11011111

	
PF1bData;      01234567;<--- scanning order


	.byte %00111110
	.byte %00100000
	.byte %00111110
	.byte %00100010
	.byte %00100010
	.byte %00000000
	.byte %00100010
	.byte %00100010
	.byte %00111110
	.byte %00100010	
	.byte %00100010	

;add score graphics later	
	org $FFFC
        .word Start
        .word Start

Current Thread