Just Jeff Posted August 28, 2016 Author Share Posted August 28, 2016 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. Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted August 28, 2016 Share Posted August 28, 2016 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. Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted August 30, 2016 Author Share Posted August 30, 2016 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! Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted August 31, 2016 Author Share Posted August 31, 2016 For (indirect,X) you probably will never use it, so I'm not going to explain it. Fair enough Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted September 1, 2016 Author Share Posted September 1, 2016 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! BP2.bin BP2m.asm Quote Link to comment Share on other sites More sharing options...
tschak909 Posted September 1, 2016 Share Posted September 1, 2016 (edited) 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 September 1, 2016 by tschak909 2 Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted September 1, 2016 Author Share Posted September 1, 2016 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: Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted September 1, 2016 Author Share Posted September 1, 2016 There we go, I masked it at 4 and added an extra trip on the score loop to bring it up to 4 states. BP2n.asm BP2.bin Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted September 3, 2016 Author Share Posted September 3, 2016 (edited) 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 September 3, 2016 by BNE Jeff Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted September 3, 2016 Author Share Posted September 3, 2016 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? BP3c.asm BP3.bin Quote Link to comment Share on other sites More sharing options...
tschak909 Posted September 3, 2016 Share Posted September 3, 2016 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 Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted September 3, 2016 Author Share Posted September 3, 2016 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 BP3.bin Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted September 8, 2016 Author Share Posted September 8, 2016 (edited) 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. BP4.bin BP4a.asm Edited September 8, 2016 by BNE Jeff Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted February 12, 2017 Author Share Posted February 12, 2017 (edited) 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 February 12, 2017 by BNE Jeff Quote Link to comment Share on other sites More sharing options...
gauauu Posted February 13, 2017 Share Posted February 13, 2017 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) 1 Quote Link to comment Share on other sites More sharing options...
carlsson Posted February 13, 2017 Share Posted February 13, 2017 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? 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted February 13, 2017 Share Posted February 13, 2017 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. 2 Quote Link to comment Share on other sites More sharing options...
gauauu Posted February 13, 2017 Share Posted February 13, 2017 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 1 Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted February 14, 2017 Author Share Posted February 14, 2017 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! Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted February 19, 2017 Author Share Posted February 19, 2017 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 Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted February 25, 2017 Author Share Posted February 25, 2017 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 Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted February 25, 2017 Share Posted February 25, 2017 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: Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted February 25, 2017 Author Share Posted February 25, 2017 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? BP5m.asm Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted February 25, 2017 Share Posted February 25, 2017 Looking at the example with the specs for RTS, the high byte should be done first. Swap the > and < to fix that. Quote Link to comment Share on other sites More sharing options...
Just Jeff Posted February 25, 2017 Author Share Posted February 25, 2017 Ahh.. I see it now. It works.. Thanks! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.