EricBall
-
Content Count
2,361 -
Joined
-
Last visited
Posts posted by EricBall
-
-
Yes, look up tables are your friend; although occasionally an approximation will work well enough while being both more time & space efficient. (e.g. max(x,y)+min(x,y)/2 as an approximation for sqrt(x*x+y*y) ) For something like a golf game you could do a 256 entry LUT for a quarter of a circle so your player wouldn't be restricted to a small set of angles.
I did a version of SpaceWar! for the 7800. Calculating the LUTs for gravity was a royal pain, but the end result was worth it.
-
1
-
-
Note: while the A8/5200 & 7800 use similar terms e.g. "display list", they are used in very different ways. See https://sites.google.com/site/atari7800wiki/atari-5200
The 7800 has a 25 entry LUT from a 256 color palette. Depending upon the graphics mode, a sprite may be 1 bpp (1 color + BG), 2 bpp (3 or 4 colors + BG) or 4bpp (12 colors + BG). In addition various strategies which take advantage of the way a TV processes the video signal may be used to create additional "artifact" colors. (e.g. Tower Toppler)
-
If you really want to roll your own, then you can take a queue from NES/SNES controllers and use shift registers. A single 8-bit register will get you 8 inputs, or you could use 2 in parallel for 16 inputs, or go whole hog and chain as a bunch serially so you can use a Sinistar 49-direction joystick and 32 buttons!

Yeah, but how many cycles would it take to read the joystick?
STX SWCHA # 4 set clock pin high LDA SWCHA # 4 read data pin ROL # 2 shift bit 7 to carry (ROR for player 2) STY SWCHA # 4 set clock pin low ROR JOY1 # 5 shift C into ZP register
So that's 19 cycles for one bit, or 158 cycles (and 104 bytes) for all 8 bits. (Adding 4 cycles to set up X & Y and 6 cycles to send the LATCH, but making the first ROL into a STA.) Actually, that's not too bad.
-
That is quite brilliant, as is using all 8 RIOT pins in both ports for a one player only game.
But your 2x3 matrix only gives 6 switches, right? So wouldn't that be the same as a Genesis controller stick and reading its 2 buttons? Up, down, left & right and diagonals and two buttons already there in the Genesis pad, or can your 2x3 matrix do joystick and 4 buttons like the original post requests?
Right, this enables no more than 4 directions and 2 buttons to be managed. Nothing more than the 4 directions and 2 buttons that some other solutions can supply (like the Genesis pad, for instance). For 2 more buttons, the 2 original Atari 7800 buttons can be used (with the corresponding circuitry).
Right, and in a 7800 (which has additional internal circuitry I'd forgotten about) it would be better for a 4-way + 2-button joystick to mimic the 7800 joystick rather than some 2x3 matrix. See http://atariage.com/forums/topic/212043-atari-7800-arcade-style-joysticks/#entry2774182 for a good summary of how the 7800 joystick works.
-
You would configure the 6 switches as a 2x3 matrix, with one side of the matrix connected to the RIOT pins so they can be used as outputs. See "A matrix in the real life" on the webpage. The other side is connected to the other pins. You then strobe each output pin and read the input pins. For the if/then you would use the AND or BIT operators to test whether the input pin is high or low and act appropriately.
-
With diodes, the ghosting problem can be reduced / eliminated : http://pcbheaven.com/wikipages/How_Key_Matrices_Works/
-
The Atari 2600/7800 joystick port has 9 pins
4 connected to the 6532 RIOT - used for joystick switches (note: these can be inputs or outputs)
2 "analog" inputs connected to the TIA - used for the paddle
1 "digital" input connected to the TIA - used for the joystick button
(Note: The 2600 and 7800 are identical from a joystick port perspective - the ports are connected RIOT & TIA.)
The analog inputs work on a charge / discharge system. During VBLANK the program sets the pins to charge mode, then the program counts the number of lines during the active screen it takes for the pins to discharge. So while these inputs could be used to detect multiple buttons using different resistance values, it requires some kernel time to do so. However, there could be calibration issues as I don't know if the resistance to number of lines is consistent for everyone.
A better alternative might be to use a variation of the keypad matrix (see http://atariage.com/2600/archives/schematics/Schematic_2600_Accessories_Low.html ). This uses the 4 RIOT pins in a row & column matrix. The big advantage of going this route is keypad support is already built into emulators. You might want / need to add some diodes (along with an intelligent mapping) like they do for a keyboard matrix to limit ghosting.
Or, if it's a one player game, use both joystick ports and just the RIOT pins.
-
The 5200 was released in November 1982, so depending upon the timing of when the interview happened and when the article was published, there's a chance Perry was referring to the 5200. But probably not.
The 7800 was an oddball - created by GCC in 1983-1984 as part of their post-lawsuit relationship with Atari. It's design mantra seemed to be for better graphics, 2600 compatibility and low cost. So that isn't it either/
My guess is the product wasn't anything more than a line item on a future possibilities list - a possible market to be explored and filled. (Especially if they received lots of interest based on the article.)
Given that I'm very close to that age, I can't imagine what kind of programs Perry might have been thinking about which are particularly distinct from what the younger than 45 group would be interested in.
-
1
-
-
Skeleton+ plays the "footstep" sound on both channels, but at different volumes to try to provide a direction indication. This was more critical in the original Skeleton which didn't have the direction indicator.
-
Someone (not AtariAge) had clear plastic cases for Skeleton+ once upon a time (like, around Philly Classic 5)
Packrat Video Games (although I don't know if they still have 'em): http://www.packratvg.com/pictures/sk2.jpg
-
Hrmm.. I'm notsure I should be trusting my memory on this... Let me look into it. (It may have been a CYA, like doing a SEI on a 2600 game.)Ok, I've reviewed the 7800 BIOS disassembly on http://www.atarihq.com/danb/files/7800bios.asm and while the BIOS locks INPTCTRL before changing to 2600 mode
LF831: LDA #$FD STA COLUPF JMP(LFFFC) ; And use the reset vector on the cart to startit doesn't for the 7800 mode.
LF7B9: LDX #$16 ; finally, back to something important STX INPTCTRL ; switch out bios and use reset vector TXS ; on cart to start the game. SED JMP(LFFFC)So it's necessary to store #$x7 to $0000-$001F before trying to update any TIA registers.
-
1
-
-
Ok, I updated the guide in the first post and gave INPTCTRL its own section after the various chips.
You probably want to note it is set & locked by the 7800 BIOS so cannot be changed by the game program (2600 or 7800).
-
INPTCTRL is a write-only register mapped to $0000-$001F implemented by an external circuit (U11 on http://atariage.com/7800/archives/schematics_ntsc/Schematic_7800_NTSC_Low.html ) It is normally set (and locked) by the 7800 BIOS, so it's invisible to the program.
-
Also not an issue, I have sprite data mapped to $3000, the display list references them. Is that what you mean?
Maybe... are you referring to the graphics data used by a normal direct sprite, or the list of LSBs which are added to CHARBASE to obtain the graphics data (indirect sprite). It's that list of LSBs which are in question (RAM vs ROM).
-
It's not the CHARBASE which is in question, but the character list pointed to by the display list entry.
-
1
-
-
A display list describes the sprites on a number of lines (typically 8 or 16). The pointer in the display list entry points to the last line of the sprite, with each previous line being on the next page in ROM. So if the sprite moves down a line, the pointer is adjusted to bottom line + 256. Then an entry in the next display list with a pointer = bottom line - 256 * (number of lines in zone - 1). "Holey DMA" is so you don't have to waste ROM space for the lines above and below the sprite.
Building (or updating) the display lists is a non-trivial thing to do efficiently. Just like the kernal of a 2600 game, there is value in ensuring all data structures in a 7800 game are arranged to make building display lists as efficiently as possible.
-
1
-
-
Indirect mode (aka character or tile mode) is specified by a 5 byte display list entry containing a 16 bit address pointer to the character / tile map in RAM (required?), the number of characters / tiles to display (i.e. bytes to fetch from the pointer) along with the horizontal position, the palette and the write mode flag. Each character / tile byte is used as the LSB for the address of the graphics data (which may be in ROM or RAM); the MSB coming from the CHARBASE register. Either 1 or 2 bytes of graphics data may be fetched per character / tile.
As per the second link, MARIA has a different set of timings for graphics data (ROM) versus non-graphics data (RAM) accesses. I don't know whether MARIA changes timings based upon what kind of data is being fetched or the address (like it does to the 6502 for RIOT/TIA accesses). In addition, the cycle count list shows character maps taking 3 cycles - the same as a graphics byte. So it might be possible to put the character map in ROM; but as Rybags noted that's only useful for static data. (Hmmm... for SpaceWar! 7800, I had planned on including a tile based star field in ROM, I can't remember whether I ever tested it.) I wouldn't be surprised if the character maps could be in ROM since that's how you'd likely do a tiled background.
-
Is he maybe using A mode some for frog/snake. How many colors are in the frog and snake? That would give 7 more colors although any transparency in them is probably limited to 160 res.
Transparency is always 160 res. MARIA only has two buffers of 160 x 5 bits of RAM to work with. (One buffer is updated by the display list while the other is being displayed.) The 320 modes are just a trick of the output stage.
-
1
-
-
I'm confused then. *Any* time I've tried to use that third color in 320B mode while using transparency it never shows up on the real thing. Is there something different you have to do (other than set the Write Mode and the DL header) in order for that third color to come out?Hi Bob,
I haven't tested this, but according to the spec MARIA uses the 2 LSBs to determine whether each 5 bit pixel should be written to line RAM. But since the 320 modes split each 5 bit pixel into two display pixels, transparency is a little less intuitive - particularly with 320B.
320B WM=1,RM=1,RM0=0 3 colors from 2 palettes + background & transparent, 2 bits / pixel D7 D6 D3 D2 0 0 0 0 BG + BG / transparent 0 0 0 1 BG + C1 / transparent 0 1 0 0 BG + C2 0 1 0 1 BG + C3 0 0 1 0 C1 + BG / transparent 0 0 1 1 C1 + C1 / transparent 0 1 1 0 C1 + C2 0 1 1 1 C1 + C3 1 0 0 0 C2 + BG 1 0 0 1 C2 + C1 1 1 0 0 C2 + C2 1 1 0 1 C2 + C3 1 0 1 0 C3 + BG 1 0 1 1 C3 + C1 1 1 1 0 C3 + C2 1 1 1 1 C3 + C3So with 320B you can only use C1 adjacent to C2 and C3 or it is transparent. However, it's also possible to use the background color as an additional color adjacent to C2 or C3.
However, the bigger problem with 320 modes is color artifacts.
-
2
-
-
https://sites.google.com/site/atari7800wiki/graphics-programming/display-lists
https://sites.google.com/site/atari7800wiki/graphics-programming/vertical-motion
http://www.atarimuseum.com/ahs_archives/archives/pdf/videogames/7800/gcc1702b_maria_specs.pdf
The display list is a sequence of display list entries which are either 4 or 5 bytes long, depending upon the 2nd byte. The end of the list is indicated by an entry where the 2nd byte is zero. (i.e. the display list end entry is 2 bytes).
-
1
-
-
If I'm not mistaken (and I have not seen or read otherwise), 320B mode limits you to two palettes, and if you use transparency, only two of the three colors within each palette. This means if you don't have time to change colors in a DLI, you're limited to 4 colors total in 320B mode.
I had to change palette colors numerous times in Moon Cresta and Scramble with a DLI because of this. 
See my post #14 which shows each of the color codings. 320B gives 3 color + background|transparent per sprite from 2 palettes (P0 and P4) or 7 colors (including background) per line.
The spec says there are at least 7 "fast" CPU cycles between the end of DMA on one line before the start of DMA on the next line. How many cycles the DLI gets before DMA starts depends on how many sprites/bytes were in the last display list, but if we assume there's enough cycles to do the IRQ and STA WSYNC before the end of the line, then you can easily change 1 color (i.e. background) before the line starts. And if you can restrict yourself to using 1 palette in that zone then there's plenty of time to change more colors.
-
1
-
-
Palettes are specified on a per sprite / tile list basis (and it doesn't "cost" anything). So with 160A you have 8 palettes of 3 colors to chose from. It is possible to change the colors in mid-screen, but there's limited CPU time to do so (min 7 fast CPU cycles per line). I suspect Froggie changes the background color from blue (water) to black (road) so it doesn't need to have a tiled background (which is very expensive in MARIA time).
-
The following tables map the graphics data bits to color indicies for the various modes (except 320D, which is 1bpp like 320A but the palette bits change the colors of the left & right sub-pixels - very strange). Note: the tables are in pixel color order rather than bit order to make it easier to understand.
160A WM=0,RM1=0 3 colors from 8 palettes + transparent / background, 2 bits / pixel D7 D6 0 0 BG / transparent 0 1 C1 1 0 C2 1 1 C3 160B WM=1,RM1=0 12 colors from 2 palettes + transparent / background, 4 bits / pixel D7 D6 D3 D2 0 0 0 0 BG / transparent 0 1 0 0 c1 1 0 0 0 c2 1 1 0 0 c3 0 0 0 1 BG / transparent 0 1 0 1 c5 1 0 0 1 c6 1 1 0 1 c7 0 0 1 0 BG / transparent 0 1 1 0 c9 1 0 1 0 c10 1 1 1 0 c11 0 0 1 1 BG / transparent 0 1 1 1 c13 1 0 1 1 c14 1 1 1 1 c15 320A WM=0,RM1=1,RM0=1 1 color from 8 palettes + background & transparent, 1 bits / pixel D7 D6 0 0 BG + BG / transparent 0 1 BG + C2 1 0 C2 + BG 1 1 C2 + C2 320B WM=1,RM=1,RM0=0 3 colors from 2 palettes + background & transparent, 2 bits / pixel D7 D6 D3 D2 0 0 0 0 BG + BG / transparent 0 0 0 1 BG + C1 / transparent 0 1 0 0 BG + C2 0 1 0 1 BG + C3 0 0 1 0 C1 + BG / transparent 0 0 1 1 C1 + C1 / transparent 0 1 1 0 C1 + C2 0 1 1 1 C1 + C3 1 0 0 0 C2 + BG 1 0 0 1 C2 + C1 1 1 0 0 C2 + C2 1 1 0 1 C2 + C3 1 0 1 0 C3 + BG 1 0 1 1 C3 + C1 1 1 1 0 C3 + C2 1 1 1 1 C3 + C3 320C WM=1,RM1=1,RM0=1 4 colors from 2 palettes + background & transparent, 2 bits / pixel D7 D6 D3 D2 0 0 0 0 BG + BG / transparent 0 0 0 1 BG + BG / transparent 0 0 1 0 BG + BG / transparent 0 0 1 1 BG + BG / transparent 0 1 0 0 BG + c2 0 1 0 1 BG + c6 0 1 1 0 BG + c10 0 1 1 1 BG + c14 1 0 0 0 c2 + BG 1 0 0 1 c6 + BG 1 0 1 0 c10 + BG 1 0 1 1 c14 + BG 1 1 0 0 c2 + c2 1 1 0 1 c6 + c6 1 1 1 0 c10 + c10 1 1 1 1 c14 + c14
This also shows why Kangaroo Mode (transparency) has an odd impact on 320B. For all the other modes transparent pixels go to background when KM=1, but with 320B this isn't the case.
-
2
-
-
320 modes are a "double res" version of the 160 modes. Although 2 pixels are displayed, positioning is still on the 160 pixel boundaries.
The actual colors are controlled by a combination of the write mode and the read mode. See gcc1702b_maria_specs or https://sites.google.com/site/atari7800wiki/graphics-modes and https://sites.google.com/site/atari7800wiki/graphics-modes/palette-sprite-bits for the gory details.
-
3
-

When exactly does the DLL / DL get read and processed?
in Atari 7800 Programming
Posted
In http://atariage.com/forums/blog/7/entry-3089-7800-cycle-counting/ I mention using (zp,x) being more efficient and say "I'll modify the rest of the sample code and post it." Of course, there's no follow-up post (on AA at least).
I remember trying to figure out the Robotron disassembly, but not getting very far. It's fundamentally a data structure & transform issue - how best to structure your data to make it efficient to transform into the 7800 display list structure.