Jump to content

EricBall

Members
  • Content Count

    2,361
  • Joined

  • Last visited

Posts posted by EricBall


  1. There's no problem using a POKEY (or any other chip which drives the cartridge audio pin) and the TIA at the same time.

     

    The problem is updating the TIA at a high enough frequency to make any sampled audio worth it. Updating the TIA once per frame (60Hz) is trivial, but after that it gets considerably harder. You could use the DLL NMI to update it once per zone, i.e. every 8 lines = 1967Hz or every 16 lines = 983Hz, but you will have to adjust for 23 lines of VBLANK. Similarly, you could bang on WSYNC and update the TIA every line (15,734 Hz), but that will waste a lot of CPU time and you'll still have to handle VBLANK (unless you're only playing music).

     

    Note: 2 or 4 bit won't make any difference except for how much ROM space the samples use. You will also need to consider how much CPU the update routine will require.

     

    I'd recommend seeing if the native TIA waveforms can provide any of the sound effects and update the TIA once per frame.


  2. And as someone who has programmed for both the 2600 & 7800, I agree with Kosmic Stardust - start from scratch.

     

    Have a look at your A8 code - how much of it is concerned with setting up the ANTIC display lists? Throw that out; MARIA display lists are radically different from ANTIC display lists. Next, how much of the remaining code is designed to make the code you just threw out easier / better? Throw that out too, you'll need to redo that code to make the code to set up the MARIA display lists easier . Sound? Throw it out, you only have a TIA (2 channels & half the frequency resolution). Controllers? Throw it out - different controllers and digital instead of analog. Graphics data? Throw it out; MARIA does 4+ colors per pixel. Collision detection? Throw it out, the 7800 doesn't have collision detection registers.

     

    Now, take a look, how much code is left? Is any of it worth saving or are you better off starting off with a clean page (and maybe even using 7800 Basic).

     

    At one point I did a write-up on the 7800 versus the 5200 : https://sites.google.com/site/atari7800wiki/atari-5200 which might help you as a starting point.

    • Like 6

  3. Define "higher quality". The TIA (and POKEY for that matter) are simple LFSR based waveform generators. From a programming perspective there are three inputs for each of the two channels:

    AUDF, a 5 bit divisor of 2 * the horizontal retrace frequency

    AUDC, a 4 bit LFSR selector, which controls the AUDF frequency to waveform

    AUDV, is a 4 bit volume control of the waveform output

     

    The problem is these values are hard coded into the game ROM. So even if you added an extra bit into one of the registers, the games wouldn't be able to use it.

     

    What you could do is tap the output TIA audio output pins (12 & 13) and put them through a high quality amplifier / filter. This will also expose some "stereo" effects in some games.

     


  4. The 7800 GPU uses several data structures to generate graphics. The screen is first broken into zones which are 1-16 lines high. The graphics for each zone are generated based on a display list (which is very different from the A8 display list). The display list contains a series of entries which describe either a sprite or a series of characters (i.e. tiles).

     

    Each display list entry contains the following:

    1. horizontal position of the leftmost pixel (-96 to 159)

    2. 16 bit address of either a list of characters or the graphics data for the last row in the zone

    3. 3 palette bits

    4. number of bytes of graphics or characters

    5. an optional bit to change the bits per pixel

     

    For indirect (character/tile) mode, the characters are used as the LSB of the address of one or two bytes of graphics data for the last row in the zone.

     

    So on the 7800 scrolling the background or a sprite horizontally is relatively easy - just update the horizontal position of the appropriate display list entries. Vertical scrolling backgrounds are trickier as you need to fiddle with the height of the first and last zone and the CHARBASE register for the last zone. For sprites, vertical motion means adding the sprite to multiple zones and updating the MSB of the address. (See https://sites.google.com/site/atari7800wiki/graphics-programming/vertical-motion)


  5. The 7800 GPU uses several data structures to generate graphics. The screen is first broken into zones which are 1-16 lines high. The graphics for each zone are generated based on a display list (which is very different from the A8 display list). The display list contains a series of entries which describe either a sprite or a series of characters (i.e. tiles).

     

    So, to generate your 40x24 character screen (NTSC) you need the following (assuming a static background):

    1. 8x8 4 color character graphics, stored in 7800 order

    2. A 960 byte character map in raster order (character is the LSB of the character graphics)

    3. 24 display lists, each containing two 5 byte entries pointing to the left & right halves of the character map, followed by a 2 byte list terminator

    4. 28 display list list entries - 4 for the vertical overscan (13 lines each), 24 for each of the 8 line high zones

    The graphics can be in ROM, the rest needs to be in RAM (either copied from ROM or generated programatically).
    The real difficulty comes with the sprites. You first need to determine which zone(s) to add the display list entry to. Then you add the entry to the end of the display list(s), adjusting the MSB of the sprite graphics for any vertical offset.
    • Like 1

  6. iTunesArtwork

    The iOS game I have been working on, Slide Tilt Roll is nearly complete. But before I put the game on the App Store, I need some levels. Which means I need people to create levels.

    Interested? You need an iPhone, iPad or iPod Touch running iOS 9 or later (configured to send email) and a willingness to create levels gratis for my 100% free application.

    In order to install my app I need the UDID for your device. This can be obtained from iTunes by clicking on the Serial Number on the device Summary panel, then right clicking on the hex digit string, selecting copy, and sending it to me via PM. (If you don't have iTunes, you can get it by plugging into a computer and looking at the USB device information. Ask, and I'll provide instructions. Any other methods (websites, apps) are either outdated or extremely suspect.) After I get your UDID I will update my Apple Developer account device list and send you the link to download and install.

    Muchas gracias
    Merci beaucoup
    Vielen Dank

     

     


  7. Q1 & 2 - Building the display lists is one of the great challenges with the 7800. As usual, some tradeoffs have to be made between space (RAM) and speed (CPU cycles).

     

    Q1 - Yes, 6 bytes per display list is enough for a single 4 byte display list entry and the 2 byte end of list entry.

     

    Q2 - While not rebuilding the entire display list sounds more efficient, it is difficult to accomplish in practice. First, as sprites move vertically they need to be removed from one display list and added to another - which means the remaining entries in the display list would need to be rewritten anyway. (Unless you pad the display list with transparent sprites, which will rob your game of precious CPU cycles due to the additional MARIA DMA.) Second, the extra time and space required to determine whether the sprite needs to be updated and finding it in the list can easily negate the savings of not simply rebuilding the display list.

     

    Q3 - Yes, you can certainly use any space not used for sprites for code or other data - just don't let it spill onto the next page. However, I'd start with the assumption you're going to use the entire 2K / 4K block for sprite graphics until you run out of space on the holey DMA pages.


  8. Graphics on the 7800 is very different from the 2600, so you're going to need different tools. (Which might exist, who knows?)

     

    First, graphics data is laid out "upside down" with the last scanline on the lowest address and each scanline on a separate page. e.g. for a 2 byte x 16 line sprite
    $e000-$e001 bottom line
    $e100-$e101 2nd last line
    ...
    $ee00-$ee01 2nd line
    $ef00-$ef01 top line
    (Sprites are typically 16 or 8 lines high and will be on even 4K (16 line) or even 2K (8 line) address blocks.
    Second, while sprites on the 2600 are 1 bit per pixel, sprites on the 7800 may be 1, 2 (most common), or 4 bits per pixel depending upon the graphics "mode". The bits from the graphics data are combined with bits in the display list entry to determine if the pixel is transparent or the output color (from a 24 of 256 entry palette).

  9. Very interesting. Thank you for the explanation, guys.

     

    Therefore, since Ms. Pac-Man 320 already uses both palettes in 320B mode, I wonder if _with Kangaroo mode disabled_ it would be possible (theoretically) have the transparency and use the 320A mode for the ghosts eyes (some images below).

     

    Thanks for your kind attention.

     

    Marco

    WM RM1 RM0  mode details
     0  0   0   160A 4 color, 2 bits/pixel
     1  0   0   160B
     0  1   1   320A 2 color, 1 bit/pixel
     1  1   0   320B 4 color, 2 bits/pixel
     1  1   1   320C
     0  1   0   320D
    

    You can only change the write mode on the same line, so the only option is 320B -> 320D. Easier option is to simply have more sprites with the different eye positions.

    • Like 1

  10.  

    I also think the "why composite video?" issue should be addressed. Why take the digitial signals generated on the FPGA board and convert them to interlaced analog composite when you natively have RGB ? Just so you can reuse a cheapo SNES cable and connector? On top of that, they lug a composite tube monitor from Cali to New York as a display when a DVI to HDMI adaptor and a much lighter LCD TV would have sufficed.

     

    Composite is (relatively) easy and cheap. You can generate NTSC output with little more than a microcontroller and a resistor DAC for an output stage. HDMI OTOH is more difficult requiring dedicated silicon and licensing fees. However, VGA is just as cheap and easy as composite video and would be a logical intermediate step for HDMI.

    • Like 1

  11. There's no hardware mirroring or scaling of sprites on the 7800, so you'll need to create separate graphics for each. Yes, you could do it programmatically, but that would burn CPU time and some RAM. Better / easier to simply make multiple sprites. (Palette tricks, however, can be used.).

    • Like 1

  12. Games on the 2600 tend to be written around the display kernel. i.e. structuring game data to minimize the number of cycles required in the display kernel. Similarly, on the 7800 there is value in ensuring game data is structured so the display lists may be created as efficiently as possible. So look at your display list builder code and ask yourself "how can i make this faster?".

     

    I'd also order the code as:

    1. Wait for end of screen (via DLI)

    2. Reset end-of screen flag, read controllers, update sound registers (to minimize jitter)

    3. Build display lists (assuming everything can be done in one screen time you don't need to double buffer)

    4. Execute game & music logic

    5. Test MSTAT, if still in VLBANK then set debug indicator to green and goto 1. If not but end-of-screen flag is cleared set debug indicator to yellow and goto 1. Otherwise set debug indicator to red, goto 2 (but skip step 3)

    • Like 2

  13. 7800 sprites may be more than a single byte wide (and can have some interesting bit to pixel mappings). Therefore putting each row on a separate page means MARIA doesn't have to perform any multiplication to get the data for the next row.

     

    7800 sprites are also "upside down" - i.e. the lowest memory address contains the bottom row of the sprite.

    • Like 1

  14. The RAM memory map on the 7800 includes some important shadows which have to be worked around:

    ;	1800-203F	2K + 64 bytes
    ;	2040-20FF	192 bytes	0040-00FF ZP shadow
    ;	2100-213F	64 bytes
    ;	2140-21FF	192 bytes	0140-01FF SP shadow
    ;	2200-27FF	1.5K
    

    The DLL doesn't take up that much space (93 bytes for a 240 line screen with 8 line zones), but the display lists for each zone can take up considerable space (depending upon the game and how the display lists are allocated). In addition, if you have a character/tile (indirect sprite) list you will probably want that in a contiguous area in RAM.


  15. I'm sure you've figured this out already, but for a limited number of rotation positions, lookup tables are the way to go for direction to X,Y anything. Note: while using reflections can reduce the size of the tables, it is often outweighed by the extra code (which costs cycles & space).

     

    For SpaceWar! 7800 I used a lot of table lookups. Thrust was approximated as an acceleration in the direction of rotation, which was then added to the current velocity (which I think had a limiter on it). The gravity of the sun was another acceleration added to the velocity from a lookup based on the ship position. The velocity then gets added to the ship position every frame to produce movement. Everything is stored as signed fixed point values.

     

    Oh, a quick approximation for the length of the hypotenuse is max(abs(x),abs(y)) + min(abs(x),abs(y))/2.

     

    Remember you're making a game, not a physics simulation :-)

     

    • Like 1

  16. I'd recommend avoiding the issue by creating your own game rather than trying to recreate (port is only applicable if you have the original source code) a game. (Although you can certainly take inspiration from other games.)

     

    The reason I say this is because you will never be able to recreate the game perfectly and thus many will judge your work to be a failure - no matter what you've managed to achieve. And trying to match the gameplay is as difficult, if not more, than trying to recreate the graphics and sound.

     

    I am not trying to put down all of the wonderful ports & recreations which were done originally or by the homebrew community. But I'd much rather play a new game that Super Mario Bros on my 7800 when I can play the original on the real hardware or an emulator.


  17. At one point I did a quick comparison of the 5200 & 7800 graphics processing: https://sites.google.com/site/atari7800wiki/atari-5200

     

    I'd recommend you first learn & program the 7800 so you have a better understanding of its capabilities and weaknesses.

     

    And while having the source code will make porting much of the game logic easier, I think you will find the graphics are so dissimilar that anything dealing with graphic objects will need a major rewrite for efficiency.

    • Like 2

  18. Just finished reading. I guess I thought there would be more pluses and minuses, but it sounds like 7800 was definitely well behind capability-wise compared to the NES/SMS competition.

     

    From a pure capabilities perspective the 7800 has definite advantages over the NES & SMS - the number of sprites MARIA can generate (per line and total) is significantly above the NES & SMS. But in practice that raw sprite power is hamstrung by available CPU time. On the 7800 every tile & sprite reduces the amount of CPU available to game processing by a significant amount due to the shared bus & the need to build display lists rather than just updating simple tables.


  19. I'm going to give a try at a version that builds up the DLL along with the DLs, and see how far that gets me. RAM is pretty tight, and a dynamic scheme would give more flexibility as to how 7800basic programs could be structured visually. I'm hoping I can pull it off without the additional overhead making it cost more than my vanilla "wait for non-visible and update" routines.

     

    A truly dynamic (i.e. no wasted RAM) DL builder is certainly possible. What you would need to do is to order your sprites by Y or loop through the list of sprites, picking out those sprites for the zone. IIRC I looked at the latter at one point and found the cycles required to loop through the list of sprites for each zone was huge. Maybe build a second table with just Y and sprite index which could then be sorted . . . still sounds like a lot of CPU cycles.

×
×
  • Create New...