|
Subject: [stella] Help (Timing problems?) From: Wade Brown <wbrown@xxxxxxxxxxxxx> Date: Mon, 30 Jul 2001 00:37:18 -0400 |
;
; Kernel.asm
; Wade Brown
; Much Code From Freeway (thanks Mr. Crane!)
;
; Use -f3 flag with DASM 2.12
; screenx = (Cycles from WSYNC to Resp0 * 3)-63
processor 6502
include vcs.h
;include macros.asm
;-----------------------------------------------
; Equates
;-----------------------------------------------
; bits
D0 EQU 1
D1 EQU 2
D2 EQU 4
D3 EQU 8
D4 EQU 16
D5 EQU 32
D6 EQU 64
D7 EQU 128
NUM_COLORS EQU 1
T64_VBLANK EQU 44 ; are these values correct?
T64_OSCAN EQU 34 ;
;
; WAIT_TIMER
;
mac wait_timer
.1 LDA INTIM ;Wait for the proper scan line
BNE .1
endm
;-----------------------------------------------
; Ram Segment (128 bytes)
;-----------------------------------------------
SEG.U vars
org $80
GameNumber DS 1 ;Current game variation being played (0-7)
FrameCounter DS 1 ;Inc'd every video frame
Polynomial DS 1 ;Random number polynomial
SelectDelay DS 1 ;Timer for select autorepeat
SaverColor DS 1 ;$00 for normal, Random for screen saver
LumMask DS 1 ;$FF for color, $0F for B&W and $07 for saver
ZColors DS 2 ;Adjusted colors (Score, Sprite)
; The order of the 4 pointers below is important!
ScoreShape01Ptr DS 2 ;Pointer to left score first digit
ScoreShape11Ptr DS 2 ;Pointer to right score first digit
ScoreShape02Ptr DS 2 ;Pointer to left score second digit
ScoreShape12Ptr DS 2 ;Pointer to right score second digit
;
; vars from here to $FF zero'ed out on reset (load address of First Variable, i.e SaverTimer)
;
SaverTimer DS 1 ;If > 127 then in screen saver mode
ScanLine DS 1
SpriteColorPtr DS 8
Scores DS 2 ;Player scores, (BCD) p1,p2
FrameCounterHi DS 1 ;Inc'd every 256 frames
EscortXY DS 2
PatByte DS 1
PatPtr DS 1
EscortPtr DS 1
TempX1 DS 1
; Keep these four in order
Player1X DS 1 ; x pix value
Player1Y DS 1 ; Scanline (0-192)
Player2X DS 1
Player2Y DS 1
; don't change order of following 2 vars
Player1Coll DS 1 ; VCS Collision Flags
Player2Coll DS 1 ; VCS Collision Flags
;-----------------------------------------------
; Code
;-----------------------------------------------
SEG code
org $1000
ResetEntry
; I believe Andrew Davie wrote the mem clear code. Thanks!
SEI
CLD
LDX #0
TXS
PHA ; BEST WAY TO GET SP=$FF, X=0
TXA
.Clear
PHA
DEX
BNE .Clear
JSR ResetGameVars
;-----------------------------------------------
; Main Loop Start
;-----------------------------------------------
MainLoop
LDA #0
LDY #$82 ;Enable video blank flags
STY WSYNC ; full scan line for vsync
STY VSYNC ;Enable vertical sync signal
STY WSYNC ;Wait 3 scan lines
STY WSYNC
STY WSYNC
STA VSYNC ;Disable vertical sync signal (A=0)
LDA #T64_VBLANK ; total number of cycles for 37 scan-line VBLANK period
STA TIM64T ;Set the timer for start of screen
;-----------------------------------------------
; VBlank Starts (37 scanlines, 2812 cycles)
; Note: Is the cycle count (scanlines * 76) correct?
;-----------------------------------------------
LDX #2-1 ; NumColors-1
.GetColors
LDA BaseColors,X ;Get the colors
EOR SaverColor ;Screen saver
AND LumMask ;B&W mask
STA ZColors,X ;Save the adjusted colors
DEX
BPL .GetColors
LDX #0
LDA #40 ;X position for score digit #1
JSR SetMotionRegsX ;Position digit #1
LDA #48 ;X position for score digit #2
INX ;X = 01
JSR SetMotionRegsX ;Position digit #2
LDA #$04 ;Two copies wide 04
STA NUSIZ0 ;Two pairs of score digits
STA NUSIZ1
LDA ZColors ;Color of the score
STA COLUP0 ;Save the score color
STA COLUP1
;-----------------------------------------------
; Wait for End of VBlank
;-----------------------------------------------
wait_timer
; Set motion registers
; note: do not set any motion registers for 24 machine cycles!
STA WSYNC
STA HMOVE
;-----------------------------------------------
;Enable video (a=0)
;-----------------------------------------------
STA VBLANK
STA CXCLR ;Clear collision registers
;-----------------------------------------------
; Display the scores (8 scan lines)
;-----------------------------------------------
LDY #8-1
.DrawScore
STA WSYNC ;3 Wait for sync
LDA (ScoreShape01Ptr),Y ;5 Get the shape for player #0's score
STA GRP0 ;3
LDA (ScoreShape02Ptr),Y ;5
STA GRP1 ;3
JSR Waste18 ;18 kill 18 cycles
NOP ; kill another cycle for proper display
LDA (ScoreShape11Ptr),Y ;5 Get the shape for player #1's score
STA GRP0 ;3
LDA (ScoreShape12Ptr),Y ;5
STA GRP1 ;3
DEY ;2
BPL .DrawScore ;3
INY ;2 y = 0 ; Clear Scores for next scanline...
STY GRP0 ;3
STY GRP1 ;3
STY NUSIZ0 ;3
STY HMCLR
;-----------------------------------------------
; set player pos (2 scan lines)
;-----------------------------------------------
LDA Player1X
LDX #0
JSR SetMotionRegsX ; 1 scan line here
LDA ZColors+1 ; Color of player1
STA COLUP0 ; Save the color
STA WSYNC ;3 ; 2nd here...
STA HMOVE ;3
;-----------------------------------------------
; Draw Loop
;-----------------------------------------------
LDA #10 ; init ScanLine to 10
STA ScanLine
DrawBegin
LDA ScanLine
SEC
SBC Player1Y ; A= ScanLine - P1InitXY+1
TAX ; x= sprite index
AND #$F8 ; force from 0-7
BEQ DrawSprite
DrawNoSprite
LDA #00
JMP DrawPlayer
DrawSprite
LDA Sprite,X
DrawPlayer
STA WSYNC
STA GRP0
INC ScanLine
LDA ScanLine
EOR #191 ; stop at line 191
BNE DrawBegin
;-----------------------------------------------
; Screen Finished, disable video and set the oscan timer
;-----------------------------------------------
LDA #2
STA WSYNC ;Finish this scanline.
STA VBLANK ; video OFF (important)
LDA #T64_OSCAN ; total number of cycles for 30 scan-line OverScan period
STA TIM64T ;Set the timer for start of screen
;-----------------------------------------------
; OVERSCAN Starts (30 scanlines, 2280 cycles)
; Note: Crane (in Freeway) uses a lower timer value then recommended by stella.doc; find out why...
;-----------------------------------------------
; Update Score Pointers
LDA FrameCounter ;Player 1 or 2 (Update 30 FPS)
AND #1
TAX ;0/1
ASL
TAY ;0/2
LDA Scores,X ;Get the score (BCD)
AND #$F0 ;Mask it
LSR ;$00,$08,$10,$18,$20
STA ScoreShape01Ptr,Y ;Insert a space (Or digit)
LDA Scores,X ;Get the BCD number again
AND #$0F ;0-9
ASL ;Mul by 8
ASL
ASL ;$00,$08,$10,$18,$20
STA ScoreShape02Ptr,Y ;Save the second digit
;-----------------------------------------------
; Check Joysticks
;-----------------------------------------------
LDA SWCHA
CMP #$FF
BEQ NoJoy
LDY #0 ;Joystick is pressed
STY SaverTimer
ASL
BCC JoyRight
ChkJoyLeft
ASL
BCC JoyLeft
ChkJoyDown
ASL
BCC JoyDown
ASL
BCC JoyUp
JMP NoJoy
JoyRight
INC Player1X
JMP ChkJoyLeft
JoyLeft
DEC Player1X
JMP ChkJoyDown
JoyDown
INC Player1Y
JMP NoJoy
JoyUp
DEC Player1Y
NoJoy
; only bounds checking the X pos currently
LDA Player1X
CMP XMaskLeft
BEQ PastLeft
CMP XMaskRight
BNE InRange
LDA #149 ; restrict X to right edge
JMP InRange
PastLeft
LDA #0 ; restrict X to left edge
InRange
STA Player1
;-----------------------------------------------
; Inc the frame counters and timers
;-----------------------------------------------
INC FrameCounter ;Inc the frame counter
BNE NoRollSv ;255 frames?
INC FrameCounterHi ;High byte of the frame counter
INC SaverTimer ;Inc the screen saver timer
BNE NoRollSv ;Zero?
SEC ;Keep the high byte set
ROR SaverTimer ;= $80
NoRollSv
LDY #$FF ;Assume normal color
LDA SWCHB ;B&W set?
AND #$08
BNE Color
LDY #$0F ;Force b&w
Color
TYA ;Place in A
LDY #0 ;Assume screen saver not active
BIT SaverTimer ;Screen saver active?
BPL NoSaver8
AND #$F7 ;Halve the brightness
LDY SaverTimer ;Get the timer value for the random colors
NoSaver8
STY SaverColor ;Save the random saver scrambler
ASL SaverColor ;0,2,4 etc...
STA LumMask ;$FF,$0F,$07
;-----------------------------------------------
; console switches check
;-----------------------------------------------
DoConsole
JSR ReadConsoleSwitches ;Read the console
BMI ChkSelect ;Reset pressed?
LDX #SaverTimer ; Reset the game (Set X to address of First Variable to clear)
JMP ResetEntry
ChkSelect
LDY #0 ;Was select pressed? (Init Y)
BCS SaveSelDelay ;Nope (Clear select delay)
LDA SelectDelay ;Select the next game
BEQ NotHeld
DEC SelectDelay
BPL NotSelTime
NotHeld
INC GameNumber ;Inc the game selected
; select pressed. Y=0
STY Scores+1 ; set player2 score to zeros
JSR ResetGameVars
LDA GameNumber ;Make sure the game number is 0-7
AND #7
STA GameNumber ; save game number and timer
STA SaverTimer
TAY ;
INY ; increment giving 1-8 (Low Order Digit of BCD score)
STY Scores ; $01-$08 0/1-8
LDY #30 ; load the select delay for auto-repeat
SaveSelDelay
STY SelectDelay ;30/60 delay (1/2 second or 0)
NotSelTime
;-----------------------------------------------
; wait for rest of overscan period
;-----------------------------------------------
wait_timer
JMP MainLoop
;-----------------------------------------------
; Main Loop End
;-----------------------------------------------
;---------------------------------------------------------
;
; Sub-Routines
;
;---------------------------------------------------------
; ResetGameVars
; Out: A=GameNumber (0-7)
; X=FF
ResetGameVars SUBROUTINE
LDA #0 ;Reset the frame counter
STA FrameCounter
LDX #8-1
LDA #>FontPage
LDY SpriteColors
.SetVidPtr
STA ScoreShape01Ptr,X ;Init the high byte for video pointers
STY SpriteColorPtr,X
DEX
STY SpriteColorPtr,X
DEX
BPL .SetVidPtr
LDX #03
; set x,y positions of both players
.PlayPtrTop
LDA P1InitXY,X
STA Player1X,X
DEX
BPL .PlayPtrTop
INX ; X=0
TXA
INX ; X=1
.VolClrTop
STA AUDV0,X ;Reset the volume of the audio chip
DEX
BPL .VolClrTop
; Load Tables here
; LDA GameNumber ; Might need this to init tables based on the game number
RTS
;
;ReadConsoleSwitches
;
; Read the console switches from the 6532 RIOT chip
; Bits are... $01 Reset, $02 Select, $08 Color
; $40 Difficulty Left, $80 Difficulty Right
; Out:
; Carry = Select
; Negative = Reset
;
ReadConsoleSwitches SUBROUTINE
LDA SWCHB ;Read the switches
LSR ;Shift the reset switch
ROR ;Rotate reset to negative flag
RTS ;and Carry has select
;
;CalcXRegs
; Given a requested X coord in A,
; return in A and Y and Horizonal offset and the cycle delay
;
CalcXRegs SUBROUTINE
CLC
ADC #46
TAY
AND #$0F ;Mask the 4 bit offset
STA TempX1 ;Save temp
TYA ;Get value again
LSR ;Isolate the upper 4 bits
LSR
LSR
LSR
TAY ;Save as a WSYNC Delay
CLC
ADC TempX1 ;Mod 15
CMP #15
BMI NoExcess ; (2/3)
;BLT NoExcess
SBC #15 ;Remove one step
INY ;5 more cycles
NoExcess
EOR #7 ; Negate horizontal offset
ASL ; (2) Move to upper 4 bits (Hardware)
Waste18
ASL ;(2) Call to waste 18 cycles
ASL ;(2)
Waste14
ASL ;(2) Call to waste 14 cycles
Waste12
RTS ;(6) Call to waste 12 cycles
;SetMotionRegsX
; Set the horizontal motion registers
; In: x coordinate in A
; offset from HMPO in x (0=p0, 1=p1)
;
SetMotionRegsX SUBROUTINE
STA WSYNC ;Sync to video
TAY ; x co-ord in Y
LDA HorzTable,Y
STA HMP0,X ;Save the horizontal motion register
AND #$0F
TAY
.delay
DEY ;Wait for cycle delay (5 cycles per)
BPL .delay
STA RESP0,X ;Hit the register for course adjustment
RTS
;-----------------------------------------------
; We have some padding here, put it to use...
;-----------------------------------------------
XMaskLeft
.byte $F0
XMaskRight
.byte $96
;-----------------------------------------------
; Numeric font (0-9) (88 bytes total)
;-----------------------------------------------
FontPage ALIGN 256
.byte %00111100
.byte %01100110
.byte %01100110
.byte %01100110
.byte %01100110
.byte %01100110
.byte %01100110
.byte %00111100
.byte %00111100
.byte %00011000
.byte %00011000
.byte %00011000
.byte %00011000
.byte %00011000
.byte %00111000
.byte %00011000
.byte %01111110
.byte %01100000
.byte %01100000
.byte %00111100
.byte %00000110
.byte %00000110
.byte %01000110
.byte %00111100
.byte %00111100
.byte %01000110
.byte %00000110
.byte %00001100
.byte %00001100
.byte %00000110
.byte %01000110
.byte %00111100
.byte %00001100
.byte %00001100
.byte %00001100
.byte %01111110
.byte %01001100
.byte %00101100
.byte %00011100
.byte %00001100
.byte %01111100
.byte %01000110
.byte %00000110
.byte %00000110
.byte %01111100
.byte %01100000
.byte %01100000
.byte %01111110
.byte %00111100
.byte %01100110
.byte %01100110
.byte %01100110
.byte %01111100
.byte %01100000
.byte %01100010
.byte %00111100
.byte %00011000
.byte %00011000
.byte %00011000
.byte %00011000
.byte %00001100
.byte %00000110
.byte %01000010
.byte %01111110
.byte %00111100
.byte %01100110
.byte %01100110
.byte %00111100
.byte %00111100
.byte %01100110
.byte %01100110
.byte %00111100
.byte %00111100
.byte %01000110
.byte %00000110
.byte %00111110
.byte %01100110
.byte %01100110
.byte %01100110
.byte %00111100
Sprite
.byte %00011000
.byte %01011010
.byte %11111111
.byte %11011011
.byte %11011011
.byte %11111111
.byte %01011010
.byte %00011000
FontEnd
;-----------------------------------------------
; Constant Segment
; 166 bytes left in this page
;-----------------------------------------------
SEG consts
ORG FontEnd
HorzTable ALIGN 256; this must not cross a page boundary (158 Bytes)
.byte $00,$F0,$E0,$D0,$C0,$B0,$A0,$90
.byte $71,$61,$51,$41,$31,$21,$11,$01,$F1,$E1,$D1,$C1,$B1,$A1,$91
.byte $72,$62,$52,$42,$32,$22,$12,$02,$F2,$E2,$D2,$C2,$B2,$A2,$92
.byte $73,$63,$53,$43,$33,$23,$13,$03,$F3,$E3,$D3,$C3,$B3,$A3,$93
.byte $74,$64,$54,$44,$34,$24,$14,$04,$F4,$E4,$D4,$C4,$B4,$A4,$94
.byte $75,$65,$55,$45,$35,$25,$15,$05,$F5,$E5,$D5,$C5,$B5,$A5,$95
.byte $76,$66,$56,$46,$36,$26,$16,$06,$F6,$E6,$D6,$C6,$B6,$A6,$96
.byte $77,$67,$57,$47,$37,$27,$17,$07,$F7,$E7,$D7,$C7,$B7,$A7,$97
.byte $78,$68,$58,$48,$38,$28,$18,$08,$F8,$E8,$D8,$C8,$B8,$A8,$98
.byte $79,$69,$59,$49,$39,$29,$19,$09,$F9,$E9,$D9,$C9,$B9,$A9,$99
.byte $7A,$6A,$5A,$4A,$3A,$2A,$1A,$0A,$FA,$EA,$DA,$CA,$BA,$AA,$9A
; 8 bytes follow
BaseColors HEX 4A ; SCORE
HEX 88 ; SPRITE
SpriteColors
HEX 88 ; LINE_ODD_COLOR
HEX 90 ; LINE_EVEN_COLOR
P1InitXY .byte 149
.byte 50
P2InitXY .byte 60
.byte 88
; only 1 byte left in page
EscortPattern ALIGN 256 ; 1st byte = frame count, 2nd byte: bit 7 x direction (1 negative), bits 4-6 x offset
HEX 0F ; ditto for y: bit 3 y direction (1 negative), bits 0-2 y offset
HEX A1 ; -x, -2 offset +y, 1 offset
HEX 07
HEX 2A
;
; Reset vector. Note we have two free bytes after in the rom, if we pad to 2k
;
org $1FFC
.word ResetEntry
;
; Difficulty switch flags, for padding
;
DiffSwitchTbl HEX 4080 ;Left,Right difficulty flags
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [stella] 2600 inbuilt, Glenn Saunders | Thread | Re: [stella] Help (Timing problems?, Erik Mooney |
| Re: [stella] Timing blues..., Christopher Rydberg | Date | Re: [stella] Timing blues..., Christopher Rydberg |
| Month |