Jump to content
IGNORED

Newbie Programming 2600


Scuttle130

Recommended Posts

How would I load a list of bytes that graphically represent a number and then store them in a place so that later, when I write data to the PF registers, it will display the correct number. Basically representing changeing digits for the score.

 

For example, "tens" is a list of 8 bytes that store the number 1. Then, I want to copy this list of bytes into the section of data that I am going use to display the entire Playfield Register with the number 1.

 

Does this even make sense?

Link to comment
Share on other sites

Using player objects for scoring:

You need to create a table of the bitmaps that you wish to display (in this case, the digits 0 to 9). Let's assume that addresses $FF00 to $FF57 contain the bitmaps of the digits (8 bytes per digit). For scoring, it is generally easier to use BCD format to hold the digits (where the upper 4 bits hold the "tens" digit and the lower 4 bits hold the "ones"). First you need to split the byte up into nybbles (that is, remove the 4 bits that the other digit uses)...that will give you a value of 0 to 9. For the lower 4 bits, this is accomplished simply by using the instruction AND #$0F. Then, you need to multiply that value by the number of bytes that each digit uses in the bitmap (in this case, we are using 8 bytes for each digit...so you can just ASL 3 times...effectively multiplying by 8). You would also need to add in the scanline number that you are displaying. This new value becomes an offset for the table. You can pass that value to the X or Y register by using TAX or TAY. Then, you can load in the byte value to display by using an instruction like LDA $TABLE,X ($TABLE bing equal to $FF00 in this example).

Using playfield graphics is similar to this, except that rather than using full bytes of data for each scanline of the digits, you would only use a few bits. In either case, the new value pulled from the data table is written to a hardware location that is responsible for displaying things on the screen.

 

It sounds really complicated...but it's a bit hard for me to describe. You might want to check out a scoring routine demo at The Dig.

Link to comment
Share on other sites

  • 5 months later...

No source code...but here's a trick to compact the score digit GFX...

 

 

By using a lookup table that holds the value of the memory page offset, you can compact the digit GFX bitmaps to use less memory...like this:

 

Digit1tab:

      .byte $06; |     XX |

Digit7tab:

      .byte $06; |     XX |(shared)

Digit4tab:

      .byte $06; |     XX |(shared)x3

Digit9tab:

      .byte $06; |     XX |(shared)x4

      .byte $06; |     XX |(shared)x4

Digit6tab:

      .byte $3E; |  XXXXX |(shared)x4

      .byte $26; |  X  XX |(shared)x3

Digit2tab:

      .byte $3E; |  XXXXX |(shared)x3

      .byte $20; |  X     |(shared)

Digit3tab:

      .byte $3E; |  XXXXX |(shared)x3

      .byte $06; |     XX |(shared)

Digit5tab:

      .byte $3E; |  XXXXX |(shared)x3

      .byte $06; |     XX |(shared)

      .byte $3E; |  XXXXX |(shared)

      .byte $20; |  X     |

Digit8tab:

      .byte $3E; |  XXXXX |(shared)

      .byte $26; |  X  XX |

      .byte $3E; |  XXXXX |

      .byte $26; |  X  XX |

Digit0tab:

      .byte $3E; |  XXXXX |(shared)

      .byte $26; |  X  XX |

      .byte $26; |  X  XX |

      .byte $26; |  X  XX |

      .byte $3E; |  XXXXX |

 

That defines the sprite GFX...in this case, each digit is using 5 lines each...many of the bytes shared with other digits. For a set of 10 bitmaps of 5 bytes each, that would normally take 50 bytes of graphics data. The above table is only 24 bytes. In order for the program to know which lines are for each digit, you create a lookup table that holds the addresses of each of those bitmaps:

 

DigitTab:

      .byte <Digit0tab

      .byte <Digit1tab

      .byte <Digit2tab

      .byte <Digit3tab

      .byte <Digit4tab

      .byte <Digit5tab

      .byte <Digit6tab

      .byte <Digit7tab

      .byte <Digit8tab

      .byte <Digit9tab

 

Then you set up a subroutine that will transfer those addresses to a temporary table of 12 bytes in ram memory (each digit will need 2 bytes)...

 

;subroutine

TransDigit:

      sty    Temp                   ;3 save Y for a second

      tay                           ;2 transfer the digit value to Y

      lda    DigitTab,y             ;4...and use it as an offset

      ldy    Temp                   ;3 restore Y

      sta    PrintTemp,x            ;5 save the low byte

      lda    #>Digit1tab            ;2 (i.e. page # of all digit gfx)

      sta    PrintTemp+1,x          ;5 save the high byte

      dex                           ;2 shift X 2 spots down

      dex                           ;2 

      rts                           ;6 

 

There's a sub that takes the 0-9 value sitting in the accumulator, and builds a table consisting of low/high bytes to be used later when sending the values to the GR registers (by using indirect,y addressing). And here is the main routine that calls it...

 

       ldx    #$0A                     ;2 initial offset for saving to ram

      ldy    #$02                     ;2 (3 score digits)

Convert_score:

      lda    Score,y                  ;4 load a digit...

      and    #$0F                     ;2 ...and strip off the upper nybble

      jsr    TransDigit               ;6 convert it to an address

      lda    Score,y                  ;4 load a digit...

      lsr                             ;2...and shift it low

      lsr                             ;2

      lsr                             ;2

      lsr                             ;2

      jsr    TransDigit               ;6 convert it to an address

      dey                             ;2

      bpl    Convert_score            ;2 branch until Y falls below zero

 

That grabs each ram byte of the score (3 bytes in ram)...shifts the nybbles to the proper position, and then JSR's to the routine that sets up the rom address of each bitmap (which uses a 13th Temp variable to hold the offset of the current score byte being worked with). Each byte of the score is done twice...once for the lower digit, and once for the upper digit. Then when the display is being created, you can use that temporary table (PrintTemp to PrintTemp+11) with indirect y instructions to grab the bitmap info on-the-fly and send it to the display. All the above code must be executed before TIA is turned on. Once the display is done making the digits on the screen, all of those temp variables in ram can be reused for anything else during that frame (nothing permanent, since they will all be used again on the next frame).

 

That's how it works with using sprites as score digits anyway. It's a bit different when using playfield GFX as score digits (When each variable value will need to be ORA's multiple times to create the playfield value).

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...