Jump to content

SpiceWare

+AtariAge Subscriber
  • Content Count

    16,912
  • Joined

  • Last visited

  • Days Won

    10

Blog Comments posted by SpiceWare


  1. That's exactly right on * - HumanGfx.

     

     

    The DCP instruction is really DEC and CMP, we use it because it's a few cycles faster than using the "legal instructions". From 6502.org Tutorials: Compare Instructions

    The CMP, CPX, and CPY instructions are used for comparisons as their mnemonics suggest. The way they work is that they perform a subtraction. In fact,

        CMP NUM
    

    is very similar to:

        SEC
        SBC NUM
    

    Both affect the N, Z, and C flags in exactly the same way. However, unlike SBC, (a) the CMP subtraction is not affected by the D (decimal) flag, (b) the accumulator is not affected by a CMP, and © the V flag is not affected by a CMP. A useful property of CMP is that it performs an equality comparison and an unsigned comparison. After a CMP, the Z flag contains the equality comparison result and the C flag contains the unsigned comparison result, specifically:

    • If the Z flag is 0, then A <> NUM and BNE will branch
    • If the Z flag is 1, then A = NUM and BEQ will branch
    • If the C flag is 0, then A (unsigned) < NUM (unsigned) and BCC will branch
    • If the C flag is 1, then A (unsigned) >= NUM (unsigned) and BCS will branch

  2. And for the final part of the question: yes, HumanPtr is used to point to the line of graphics to be drawn now.

     

    The tricky part is it's too time consuming to adjust HumanPtr in the Kernel like we do HumanDraw, so we have to use the Y register select the proper line of graphics for each scanline. However Y won't be 0-9 while the sprite is being drawn, it'll be another range of 10 numbers in sequence, so we need to adjust the value of HumanPtr to compensate.

     

    In other words, we need HumanPtr + Y to be equal to HumanGfx + HUMAN_HEIGHT - 1 when we hit the very first scanline for "draw the sprite" (as denoted in the prior reply).

     

    Since Y is counting downward in the kernel, HumanPtr + Y will equal HumanGfx on the last "draw the sprite" scanline.

     

    Hope these three replies clear it up for you!


  3. Yes, HumanDraw is the Y position and then some. Remember that TIA is scanline based so we need a way to programmatically determine if the sprite is to be drawn over a number of consecutive scanlines. The DCP is a thrifty(fast) way to do that.

     

    Splitting the DCP to it's components, we're running this bit of code on every scanline to determine if the sprite is drawn:

      lda #10 ; the height of the sprite
      dec HumanDraw
      cmp HumanDraw
      bcs DrawSprite ; if 'C'arry is set, the sprite is on this scanline
      lda #0; sprite not on this scanline, so use 0 to blank it out
      jmp UpdateTIA ; the .byte $2c trick is equivalent to this
    DrawSprite:
      lda (HumanPtr),y ; fetch the shape for this particular scanline
    UpdateTIA:
      sta GRP0
    

    During the compare the Carry flag will be set if HumanDraw < 10. So for 10 lines, when HumanDraw has the value from 0 to 9, the sprite data will be loaded into A. All other times the 0 is loaded into A in order to blank out the sprite.

     

    To have the sprite start drawing on the 10th scanline, we set HumanDraw to 19. Due to the decrement BEFORE the compare, the code run on each scanline will check the following values of HumanDraw:

    • line 1 - is 18 < 10 - nope, blank the sprite
    • line 2 - is 17 < 10 - nope, blank the sprite
    • ...
    • line 9 - is 10 < 10 - nope, blank the sprite
    • line 10 - is 9 < 10 - yep, draw the sprite
    • line 11 - is 8 < 10 - yep, draw the sprite
    • ...
    • line 18 - is 1 < 10 - yep, draw the sprite
    • line 19 - is 0 < 10 - yep, draw the sprite
    • line 20 - is 255 < 10 - nope, blank the sprite*
    • line 21 - is 254 < 10 - nope, blank the sprite
    • ...
    * when dealing with unsigned 1 byte values, 0 - 1 = 255, or in Hex that'd be $00 - $01 = $ff.

  4. Been out of town, so just a quick response on HUMAN_HEIGHT. Will follow up on the rest later.

     

     

    I always compile with the -s option to have dasm generate a symbol file. Open up collect.sym from the zip and you'll find:

     

     

    HUMAN_HEIGHT             000a

    All the symbol values are in hex, so HUMAN_HEIGHT has a value of 10 in decimal.

     

    I also compile with the -l option to generate the listing. Open up collect.lst from the zip and you'll find:

     

     

        722  fa50    HumanGfx
        723  fa50        1c       .byte.b %00011100
        724  fa51        18       .byte.b %00011000
        725  fa52        18       .byte.b %00011000
        726  fa53        18       .byte.b %00011000
        727  fa54        5a       .byte.b %01011010
        728  fa55        5a       .byte.b %01011010
        729  fa56        3c       .byte.b %00111100
        730  fa57        00       .byte.b %00000000
        731  fa58        18       .byte.b %00011000
        732  fa59        18       .byte.b %00011000
        733  fa59        00 0a    HUMAN_HEIGHT = * - HumanGfx
        734  fa5a

    The * denotes the current program counter (location in ROM). It's used as a synonym for .. From dasm's instruction file dasm.txt:

    . -current program counter (as of the beginning of the instruction).

     

    * -synonym for ., when not confused as an operator.

    The listing is a little deceptive - the last byte value of 18 is located at fa59, so the * in the equation has a value of fa5a, not fa59 as the listing suggests.

     

    HUMAN_HEIGHT = * - HumanGfx
    HUMAN_HEIGHT = fa5a - fa50
    HUMAN_HEIGHT = 000a
    

    Basically I'm letting dasm calculate the size of the image. I do that because I usually start projects with placeholder graphics that are later replaced with images created by graphic artists such as Nathan Strum and David Vazquez. Do note those lists of projects they've contributed to should be larger - for instance Nathan did the graphics for Space Rocks, but that game's not yet in the database.


  5. The graphic shape for each digit is defined, in order, at DigitGfx (see second image in the blog entry). Each graphic image is 5 bytes high.

     

    To draw a specific digit, use the following equation to get memory location in ROM for the correct shape: DigitGfx + (digit * 5). To draw an 8 that'd be DigitGfx + (8*5) or DigitGfx + 40.

     

    Offset is the digit * 5 part of that equation - specifically it's the offset from DigitGfx.


  6. SEG.U VARS is used to specify an uninitialized segment with the name of VARS. The key thing about that, from dasm.txt (the instruction file for dasm), is:

     

    Unitialized segments produce no output and have no restrictions.

    That means whatever's after SEG.U does not end up in the ROM file. Here we're using it to allocate RAM usage.

      SEG.U VARS
      ORG $80 ; start of RAM
    Score: ds 2
    DigitOnes: ds 2
    DigitTens: ds 2
    ...
    

    Instead you could do this:

    Score = $80
    DigitOnes = $82
    DigitTens = $84
    ...
    
    but it becomes tedious (and error prone) to manually keep track of RAM usage yourself.

  7. macro.h is a file that gets included into your source code as though you'd typed it in yourself. It contains a number of pre-written routines that can be handy to use. An example would be the macro VERTICAL_SYNC. If you use it, then the following code will be dropped in your program wherever you typed in VERTICAL_SYNC:

     

     

                    LDA #$02            ; A = VSYNC enable
                    STA WSYNC           ; Finish current line
                    STA VSYNC           ; Start vertical sync
                    STA WSYNC           ; 1st line vertical sync
                    STA WSYNC           ; 2nd line vertical sync
                    LSR                 ; A = VSYNC disable
                    STA WSYNC           ; 3rd line vertical sync
                    STA VSYNC           ; Stop vertical sync 
    

    • Click on atari2600land in the top-right corner of the screen, just to the left of Sign Out
    • Click on Manage Ignore Prefs in the menu that drops down. It's the third option in the right hand column
    • Copy the text OmegaPrime and paste into the Member's Name box directly below Add a new user to my list
    • Click the 4 checkboxes to the right for Posts, Signature, Messages and Chats
    • Click on Save Changes.

    Easy peasy. I currently have 4 users in my list.

     

    While your games may not be "da bomb", I've always admired your tenacity.


  8. Fortunately, I have a PS3 that Amazon works with. For the time being.

     

    I used to watch Amazon Prime via my PS3, but lately I've been using Safari on my Mac mini DVR.

     

    The PS3's interface is nicer than using the web browser, but I got tired of the PS3 requiring an update anytime I wanted to watch something.


  9. The Apple TV supports the MFi controllers. I recently picked up a Horipad for my iPad, it works quite well. Layout's just like the PS3 controller, though the analog sticks aren't exactly the same as they can't be pushed down for the L3 and R3 buttons.

     

    It has a USB input for charging, it wasn't used for the pairing process which was just a normal Bluetooth pairing.

     

    Only thing I don't like about the Horipad is the glossy finish ends up looking dirty all the time. I wish it had a matte finish like the PS3 controllers.

     

     

    I doubt I'll be able to use the new Apple TV with my current set. While it predates HDMI I do have an HDMI adaptor but the device needs to output 1080i and the Apple TVs to date only support a progressive signal.


  10. I've been coding in assembly since the early '80s so it's hard to remember what wasn't familiar when I started. I normally use "bit x" when referencing the bits within a byte, where the value of x is 0-7 and arranged as 76543210(so if just bit 7 is on the value of the byte would be $80 or 128). Bit x notation seems a lot clearer to me, but Stella Programmer's Guide used the D notation so that's what I used for this code so it would match the documentation.

     

    Yep, that would be an error, they do happen. I probably copied/pasted the lines of code and forgot to fix the comment in the second line. It's probably wrong in steps 2-14 as well.

     

    Thanks!


  11. I dropped a note to Al about the restart suggestion. That might be dictated by how many people sign up for the tournament.

     

    Timer running out definitely needs something to happen. I initially had it explode the ship, but did not like how that worked out. I next looked into added an "end of game buzzer", but didn't have room where the sound effect tables are stored. With more time I could have shuffled things around to implement the buzzer, and plan to look into doing that if we make another tournament edition.

×
×
  • Create New...