Jump to content

Photo

WIP Battle Pong- Questions, Comments, Snide Remarks Welcome


67 replies to this topic

#26 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Sun Aug 28, 2016 1:02 PM


Affects Flags: S V Z C

MODE           SYNTAX       HEX LEN TIM
Immediate     ADC #$44      $69  2   2
Zero Page     ADC $44       $65  2   3
Zero Page,X   ADC $44,X     $75  2   4
Absolute      ADC $4400     $6D  3   4
Absolute,X    ADC $4400,X   $7D  3   4+
Absolute,Y    ADC $4400,Y   $79  3   4+
Indirect,X    ADC ($44,X)   $61  2   6
Indirect,Y    ADC ($44),Y   $71  2   5+


You'll notice there's a Zero Page,X but not a Zero Page,Y. dasm knows this, so it will use Absolute,Y instead. Likewise Indirect,X and Indirect,Y look different in the SYTNAX in order to help you remember that they work differently.  I don't think I've ever used Indirect,X
 

 

I think I get it though not sure on this one.  Is ($44,x) a 16 bit address and ($44),Y an indexed zero page address?

 

Also, funny you mentioned Draconian.  I got a Harmony Encore last week and last night I added Draconian to it and played it.



#27 Omegamatrix OFFLINE  

Omegamatrix

    Quadrunner

  • 6,098 posts
  • Location:Canada

Posted Sun Aug 28, 2016 2:06 PM

I think I get it though not sure on this one.  Is ($44,x) a 16 bit address and ($44),Y an indexed zero page address?

Both those instructions use a 16 bit address. This is why when you set up the pointer you have to store a high byte of the address and a low byte of the address.
 
The actual instruction only takes one byte for the operand, which is the ram location of the low address of the pointer.
 
 
Example:

    SEG.U RIOT_RAM
    ORG $80
       
colorPtr   ds 2      ; designates 2 bytes of ram ($80-$81) for a 16 bit address, which is stored little endian
                     ; zero page (zp) ram location $80 is the low byte of the address
                     ; zero page (zp) ram location $81 is the high byte of the address
 
    SEG CODE
    ORG $F000 

;..... 

    lda #<ColorP0     ; get low address
    sta colorPtr      ; store to zero page ram location $80
    lda #>ColorP0     ; get high address
    sta colorPtr+1    ; store to zero page ram location $80+1 = $81


;usage
    lda (colorPtr),Y  ; in Stella's debugger (or the list file) this will be $B1 $80 (just 2 bytes, not 3)
                      ; $B1 is the opcode for lda (indirect),Y ; $80 is the operand for lda (indirect),Y
                      ; - For lda (indirect),Y the operand is the zp ram location which holds the low address of our pointer.
                      ; - It is required that the high part of the address be stored in ram immediately after the low address,
                      ; which in this case would be zp ram location $81. This requirement allows lda (indirect),Y to only use
                      ; 2 bytes of code instead of 3.

For (indirect,X) you probably will never use it, so I'm not going to explain it.



#28 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Tue Aug 30, 2016 5:58 PM

 

Now for jumps:

It's branches could only move forward or backward half a page. Jumps can go anywhere in the current bank. The state table doesn't have to be close as you are using absolute indexed addressing to look up the values.

 

Ah..  OK.  Got it.  Thanks!



#29 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Tue Aug 30, 2016 6:06 PM

For (indirect,X) you probably will never use it, so I'm not going to explain it.

 

Fair enough :)



#30 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Wed Aug 31, 2016 6:49 PM

OK.. I made the score changes and to my surprise, implemented the state machine.  I think I have a pretty complete understanding of it now..

 

Thanks everyone for the help!

Attached Files

  • Attached File  BP2.bin   4KB   37 downloads
  • Attached File  BP2m.asm   44.94KB   33 downloads


#31 tschak909 OFFLINE  

tschak909

    Stargunner

  • 1,592 posts
  • Location:USA

Posted Wed Aug 31, 2016 8:01 PM

STATIC AND COLOR BARS IN A GAME?!? bwahahaha... I'm laughing my ass off, in a good way... that's one hell of a sense of humour in a game :) Hats off to you, man :)

 

-Thom

 

(in other words, Great job!)


Edited by tschak909, Wed Aug 31, 2016 8:01 PM.


#32 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Thu Sep 1, 2016 3:33 AM

Thanks!  Did you notice that the game keeps resetting?  The score always starts over from zero every time it comes up.  I didn't realize until after I posted.  I'm certain I need to change the JumboState mask:

FrameCount:
		inc FrameCounter
		lda FrameCounter
		cmp #255
		beq IncDisplay
		jmp EndIncDisplay
		
IncDisplay:
	inc JumboState
	lda JumboState
	and #%00001111
	sta JumboState
EndIncDisplay:



#33 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Thu Sep 1, 2016 3:52 AM

There we go, I masked it at 4 and added an extra trip on the score loop to bring it up to 4 states.

Attached Files



#34 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Sat Sep 3, 2016 6:03 AM

Now for another big one I've been ignoring... The coins.  I want the coins to disappear one at time when a player is running over them.  To accomplish this, I'm thinking of doing something like this:

 

1. The coins are stored in RAM using 12 bytes per player.  (There has got to be a better way to do this.) Each byte is a PF2 line.

2. Detect playfield collisions

3. Get x and y coordinates of player.

4. Apply a mask that corresponds to each stack. Currently, the coins in PF2 are the D5, D3, and D1 bits. So something like:


;------------------------------------------------------------------------------
; Decrement Coins
;----------------

; The stacks of coins are displayed using PF2 register. Three stacks of coins.
; Before the jsr, upon collision, the accumulator will have been loaded with either %00100000,
; 00001000, or 00000010 which correspond to one of the stacks.  

CoinCollision:			;  
	ldx #11			; The stacks of coins are potentially 12 high
	
CoinTest:
	and PillRAMGfx,x	; Check to see if there is a match on this line
	bpl RemoveCoin		; Branch if we've hit a coin
	dex
  	bne CoinTest		; Repeat if there was not match
	
RemoveCoin:
	eor #%11111111		; Change 00100000 to 11011111 for example
	and PillRAMGfx,x	; Remove a coin from the first stack for this example
	sta PillRAMGfx,x	; Then store it back from where it came.
	rts

Funny, while trying to show an example of the code I was going to write, I ended up writing the code.  I'll have to remember that technique. How does it look?


Edited by BNE Jeff, Sat Sep 3, 2016 6:18 AM.


#35 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Sat Sep 3, 2016 11:31 AM

Hmm..  It doesn't work yet.  I added the player/playfield collisions but the score loop was causing player/playfield collisions on every loop.  Also I didn't account for PF2 being reversed so I had to change the initial LDA.  I fixed those but I guess BPL also branches on zero?

SS9-3.jpg

Attached Files

  • Attached File  BP3c.asm   46.48KB   28 downloads
  • Attached File  BP3.bin   4KB   28 downloads


#36 tschak909 OFFLINE  

tschak909

    Stargunner

  • 1,592 posts
  • Location:USA

Posted Sat Sep 3, 2016 12:03 PM

BPL branches when the sign bit is clear after an operation. This means that since 0 doesn't flip the sign bit, it will still take the branch. It will fall through however, when the counter wraps around to $FF, since the sign bit is set.

 

-Thom



#37 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Sat Sep 3, 2016 2:58 PM

BPL branches when the sign bit is clear after an operation. This means that since 0 doesn't flip the sign bit, it will still take the branch. It will fall through however, when the counter wraps around to $FF, since the sign bit is set.

 

-Thom

 

Thanks..  I got rid of the BPL and used BEQ instead. Its a couple more steps but its working! (By which I mean, if player 0 touches the playfield anywhere, one stack of coins will disappear one at a time, but really fast.) 

;------------------------------------------------------------------------------
; Decrement Coins
;----------------

; The stacks of coins are displayed using PF2 register. Three stacks of coins.
; Before the jsr, the y register will have been loaded with either %00000100,
; %00010000, or %01000000 which correspond to one of the stacks.  

CoinCollision:			
	ldx #12			; The stacks of coins are potentially 12 high
	
CoinTest:
	tya			; y has to be transferred each time through
	dex			; go to next coin location
	beq EndCoinCheck	; End if we're at the bottom of the coin stack.
	and PillRAMGfx,x	; Check to see if there is a match on this line
	beq CoinTest		; If zero matches, go back up
	
RemoveCoin:
	eor #%11111111		; Change 00000100 to 111111011 for example
	and PillRAMGfx,x	; Remove a coin from the first stack for this example
	sta PillRAMGfx,x	; Then store it back from where it came.
	
EndCoinCheck
	rts

Attached Files

  • Attached File  BP3.bin   4KB   26 downloads


#38 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Thu Sep 8, 2016 4:47 PM

Greetings!

 

I've made some more progress..

 

The coins can now be collected by the players- at the cost of 24 bytes of RAM

 

Added some collision stuff and software control of ball speed.  You can really get the ball moving. (Or stopped if you time it right.)

 

To stabilize the screen, I set a timer inside the top wall and I only re-position the two players within it.  If you turn on debug colors (ALT+ comma)and move the players around the right side of the screen, you'll see the comb line bounce around, but not anything else.

SS 9-8.jpg

Attached Files

  • Attached File  BP4.bin   4KB   43 downloads
  • Attached File  BP4a.asm   50.27KB   36 downloads

Edited by BNE Jeff, Thu Sep 8, 2016 4:49 PM.


#39 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Sun Feb 12, 2017 3:10 PM

Hi!...

 

So I have a state machine question..  I have this state state machine:

    ldy    JumboState
    lda    JumboLo,Y
    sta    jumbo_JumpInd
    lda    JumboHi,Y
    sta    jumbo_JumpInd+1
    jmp.ind (jumbo_JumpInd)   ; indirect jump into code segment   

and...
        
JumboLo:
    .byte <ShowFireballsLogo
    .byte <TestPattern
    .byte <TwoScore
    .byte <TwoScore    
JumboHi:
    .byte >ShowFireballsLogo
    .byte >TestPattern
    .byte >TwoScore
    .byte >TwoScore  
 

It works great, but when I tried to call ShowFireballsLogo from elsewhere with a JSR, I realized I cannot because the routines end with a JMP since they were set up with the state machine using the above jmp.ind, they therefore do not have an RTS.

 

Does anybody have any tips on how to be able to call routines in a state machine but using a JSR?

 

Thanks!


Edited by BNE Jeff, Sun Feb 12, 2017 3:30 PM.


#40 gauauu OFFLINE  

gauauu

    Chopper Commander

  • 244 posts
  • Location:Illinois

Posted Sun Feb 12, 2017 9:56 PM

You can just push manually an address onto the stack (ie the address of where you want to return to) using PHA, then do your indirect jump like you're currently doing it.

 

When you hit the RTS at the end of your subroutine, it will pop an address off the stack and jump to it.  It doesn't matter how that address got there -- it doesn't care whether you actually did a JSR, or what, just as long as there's an address to pop off and jump to.

 

(To be technical, I think you have to push the address - 1, it doesn't return to the exact address that's on the stack)



#41 carlsson OFFLINE  

carlsson

    River Patroller

  • 4,086 posts
  • Location:Västerås, Sweden

Posted Mon Feb 13, 2017 5:29 AM

Couldn't you break out the code into a mostly pointless subroutine?

 

ShowFireballsLogo:

jsr ShowFireballsLogo1

[.. rest of code ..]

 

and in your other routine, call ShowFireballsLogo1 instead, which is designed to return with a RTS?



#42 RevEng ONLINE  

RevEng

    River Patroller

  • 4,456 posts
  • Bitnik
  • Location:Canada

Posted Mon Feb 13, 2017 7:05 AM

Does anybody have any tips on how to be able to call routines in a state machine but using a JSR?


Stick this bit of "state machine" code out of the regular program path, and JSR to it.

#43 gauauu OFFLINE  

gauauu

    Chopper Commander

  • 244 posts
  • Location:Illinois

Posted Mon Feb 13, 2017 10:43 AM

Stick this bit of "state machine" code out of the regular program path, and JSR to it.

 

This really is the easiest way to deal with it, despite what I said above :)



#44 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Mon Feb 13, 2017 8:08 PM

Thanks..

 

As I recall, I set up the state machine to avoid having to do a jumbled bunch of compares and JSRs so I don't think I can easily break it out into its own..  I definitely like the idea of using PHA- mainly because I've never used any stack instructions before.  I always wondered what the point of some of those instructions was so it will be a valuable learning experience.

ShowFireballsLogo currently does not have an RTS at the end of it, just a JMP- which I'll need to change.  And I guess I'll have to work in another PHA in the other location as well.

 

Thanks again for all the advice!



#45 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Sun Feb 19, 2017 3:22 PM

I spent a little time trying to wrap my head around this..  I need a 16 bit address- right? And I don't think DASM has any magic trick for it so would it be something like this?

StartSreenLo:
    .byte <MyReturnAddress
  
StartScreenHi:
    .byte >MyReturnAddress


    lda    StartScreenLo,Y
    pha
    lda    StartScreenHi,Y
    pha


#46 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Sat Feb 25, 2017 1:48 PM

Before I proceed, should this code work?:

lda <StartScreenReturn
pha
lda >StartScreenReturn
pha
jmp ShowFireballsLogo	

StartScreenReturn:

And my ShowFireballsLogo routine would end with an rts



#47 SpiceWare ONLINE  

SpiceWare

    Quadrunner

  • 10,960 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Sat Feb 25, 2017 1:58 PM

close - you left off the #, and the address is off by 1 due to how RTS works.
 

RTS pulls the top two bytes off the stack (low byte first) and transfers program control to that address+1.


 So subtract 1 from the address to compensate.

  lda #<(StartScreenReturn-1)
  pha
  lda #>(StartScreenReturn-1)
  pha
  jmp ShowFireballsLogo	

StartScreenReturn:


#48 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Sat Feb 25, 2017 4:05 PM

Thanks!

 

I read up on rts and made the change, but it never returns.  Looking the debugger, it puts $FACE in the stack and when it comes to the rts, it restarts the program completely.  I don't see that address ($FACE) in the debugger either.  Any ideas?

Attached Files

  • Attached File  BP5m.asm   55.75KB   16 downloads


#49 SpiceWare ONLINE  

SpiceWare

    Quadrunner

  • 10,960 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Sat Feb 25, 2017 4:25 PM

Looking at the example with the specs for RTS, the high byte should be done first. Swap the > and < to fix that.

#50 BNE Jeff ONLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 279 posts
  • Location:Virginia, USA

Posted Sat Feb 25, 2017 5:06 PM

Ahh..  I see it now.  It works.. Thanks!






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users