Jump to content





step 8 - Select and Reset support

Posted by SpiceWare, in Collect 07 July 2014 · 1,617 views

For this update we're adding initial support for the Select and Reset buttons.  For this we're adding a new RAM variable called GameState to keep track of "Game Active" vs "Game Over".
    ; D7, 1=Game Active, 0=Game Over
GameState:      ds 1    ; stored in $A7
 
 
We're going to use D7 to denote the state as we can easily test D7 (as well as D6) by using the BIT command.  You can see this in the revised Vertical Blank routine were we test GameState to determine if UpdateTimer and ProcessJoystick should be skipped over:
VerticalBlank:
        jsr ProcessSwitches
        bit GameState
        bpl NotActive
        jsr UpdateTimer
        jsr ProcessJoystick
NotActive:        
        jsr PositionObjects
        jsr SetObjectColors
        jsr PrepScoreForDisplay
        rts             ; ReTurn from Subroutine
 
 
 
ProcessSwitches will check SWCHB to see if RESET is pressed.  If so, it'll start up a new game.  If not, it'll check if SELECT is pressed, and if so cancel an active game.
ProcessSwitches:
        lda SWCHB       ; load in the state of the switches
        lsr             ; D0 is now in C
        bcs NotReset    ; if D0 was on, the RESET switch was not held
        jsr InitPos     ; Prep for new game 
        lda #%10000000  
        sta GameState   ; set D7 on to signify Game Active      
        rts
        
NotReset:
        lsr             ; D1 is now in C
        bcs NotSelect
        lda #0
        sta GameState   ; clear D7 to signify Game Over
        
NotSelect:
        rts
 
 
In the next update ProcessSwitches will be expanded upon so that the Select routine will let you select a game variation (and if you check the source you'll see a new Arena layout is already in place for that).
 
In order to visually show you that the game is over, I've revised the Color routines to color cycle if the game is not active.
SetObjectColors:
        lda #$FF
        sta Temp2       ; default to color mask
        and ColorCycle  ; color cycle
        bit GameState
        bpl SOCgameover
        lda #0          ; if game is active, no color cycle
SOCgameover:
        sta Temp
        ldx #4          ; we're going to set 5 colors (0-4)
        ldy #4          ; default to the color entries in the table (0-4)
        lda SWCHB       ; read the state of the console switches
        and #%00001000  ; test state of D3, the TV Type switch
        bne SOCloop     ; if D3=1 then use color
        ldy #$0f
        sty Temp2       ; set B&W mask
        ldy #9          ; else use the b&w entries in the table (5-9)
SOCloop:        
        lda Colors,y    ; get the color or b&w value
        eor Temp        ; color cycle
        and Temp2       ; B&W mask
        sta COLUP0-1,x  ; and set it
        dey             ; decrease Y
        dex             ; decrease X 
        bne SOCloop     ; Branch Not Equal to Zero
        lda Colors,y    ; get the Arena color
        eor Temp        ; color cycle
        and Temp2       ; B&W mask
        sta ArenaColor  ; save in RAM for Kernal Usage
        
        rts             ; ReTurn from Subroutine
 
 
 
Color cycle example
Attached Image
 
B&W Color Cycle example:
Attached Image
 
ROM
Attached File  collect_20140707.bin (2KB)
downloads: 145
 
Source
Attached File  Collect_20140707.zip (43.97KB)
downloads: 152




Hi..  Is there any reason that D6 and D7 are easy to test with the BIT command?  Or are they all easy, but were just happen to be looking for 6 & 7 here?

 

Also, are you grouping particular routines in either overscan or vertical blank?  In other words, is there an advantage to placing certain logic in either one or the other, or are you maybe following some convention?

 

Thanks!

  • Report

Hi..  Is there any reason that D6 and D7 are easy to test with the BIT command?  Or are they all easy, but were just happen to be looking for 6 & 7 here?


From 6502 Opcodes:
 

The S and V flags are set to match bits 7 and 6 respectively in the value stored at the tested address.


So after the BIT command you'll use the branch commands BPL or BMI if you're checking the state of bit 7, and BVC or BVS for bit 6. Bits 0-5 do not get copied to a processor flag, so testing those bits is more involved.
  • Report

Also, are you grouping particular routines in either overscan or vertical blank?  In other words, is there an advantage to placing certain logic in either one or the other, or are you maybe following some convention?


Collect is such a simple game that it's highly probably that all the routines could run in just Overscan or Vertical Blank.  I use this loop:
  • Process User Inputs
  • Movement logic for things not controlled by a player
  • Prep for display (position all TIA objects, initialize values needed by Kernel, etc)
  • Kernel
  • Collision processing
I know that for a complex game not everything can be run in OverScan or Vertical Blank, and that OS has about half the time that VB does, so I start out with #5 in OS and #1-3 in VB.  Some of the routines may need to be shifted as processing time gets used up - in order to know which is running short on time I normally build in a way to capture time remaining:
DEBUG = 0 ; set to 1 for debug info in score and to flash screen if fireball



...


; in the Define RAM Usage section 
 if DEBUG = 1
VBtime ds 1
OStime ds 1
 endif



...



 if DEBUG = 1
        lda INTIM
        sta VBtime
 endif

Kernel:            
        sta WSYNC       ; Wait for SYNC (halts CPU until end of scanline)
        lda INTIM       ; 4  4 - check the Score+1
        bne Kernel      ; 2  6 - (3 7) Branch if its Not Equal to 0



...



 if DEBUG = 1
        lda INTIM
        sta OStime
 endif

OSwait:
        sta WSYNC   ; Wait for SYNC (halts CPU until end of scanline)
        lda INTIM   ; Check the Score+1
        bne OSwait  ; Branch if its Not Equal to 0
        rts         ; ReTurn from Subroutine
 
 
When possible I'll set up a way to display those values, but if it's not then the RAM variables can be checked via Stella's debugger.
  • Report

Interesting.  I'm surprised that the Stella debugger doesn't just display timer values by default.

 

I can get why D7 could be linked with plus and minus, but how D6 translates to an overflow is beyond me.  Sounds like something that just needs to be memorized, but not understood!

  • Report

Interesting.  I'm surprised that the Stella debugger doesn't just display timer values by default.


Stella does show the timer, it's on the I/O tab.  I just find it easier to see the value in real time, while I'm play testing on real hardware, rather than having to stop the program in Stella to see it.  This photo is from Part 6 of the Story of Stay Frosty, time remaining is displayed below the score & lives/level display:
blogentry-3056-0-55021800-1421003912.jpg
 
When I do that I'm actually display about 272 scanlines, but my C= 1084S monitor can handle that.

  • Report

I can get why D7 could be linked with plus and minus, but how D6 translates to an overflow is beyond me.  Sounds like something that just needs to be memorized, but not understood!

 

The Processor Status is stored in a single byte in the format of NV-BDIZC, so D6 is the overflow flag.  

 

In Stella you can see that representation used just below the Y register and above Zero Page RAM.  Stella uses case to display the state of the status flags: lower case = 0, upper case = 1.

 

  • Report

Oh OK..  So that timer number will stay relatively stable on the screen.  I imagined it just rolling through at 60 cycles.  Makes sense.  And the S flag is just another name for the N flag- didn't know that.  I enjoyed going to the magazine site.. I used to buy Compute's Gazette all the time in high school and type the Commodore 64 programs in.

  • Report

That test screen's fairly consistent with time.  With actual game play logic the timer values change practically every frame, but you can still read it well enough to know the values you're seeing.

 

Used to read Compute! and the Gazette as well.  If I recall correctly, in 81 my Vic 20 included a trial subscription to a magazine that had gone under, they replaced it with Compute! and I continued to subscribe to it for a long time.

  • Report

From 6502 Opcodes:
 

So after the BIT command you'll use the branch commands BPL or BMI if you're checking the state of bit 7, and BVC or BVS for bit 6. Bits 0-5 do not get copied to a processor flag, so testing those bits is more involved.

 

To further expand, in order to test those other bits, you would literally need to shift bits 0-5 left in order to test them with e.g ASL...

 

-Thom

  • Report
Yep - I use ASL then BCS/BCC for testing the joystick directions.

If you only need to test a single bit, it might be faster (depending upon which bit) to use AND then BEQ/BNE like this to test bit 3
 lda value
 and #%00001000
 bne BIT3ON  ; or beq BIT3OFF
  • Report

Search My Blog

Recent Entries

Recent Comments

Latest Visitors

1 user(s) viewing

0 members, 1 guests, 0 anonymous users