Jump to content

supercat

Members
  • Content Count

    7,259
  • Joined

  • Last visited

Posts posted by supercat


  1. Clearly the 6507 stack mirror in zero page was an artifact of minimal address decoding, but I have to wonder if ENAMx/ENABL purposely used bit 1 to make the Z-flag/PHP missile trick in Combat possible.

     

    The TIA documentation I have explicitly states that as being the reason for the choice. Makes sense, though I think bit 0 or 7 would have been more helpful (to allow ROL or ROR). I'm more puzzled by the use of bit 3 for REFPx. It would seem bit 7 would have been the logical choice (store a direction there directly, or if one is in the mood to PHP, push the N flag).

     

    I wonder when it became clear that most games on the 2600 would not be 'freewheeling' the sprite horizontal positions? If a game tracks the horizontal positions of sprites, one could show scores using magnified sprites rather than the score-colored playfield. As it turns out, score mode can be handy for purposes other than showing two-player scores, so it's hardly a waste of silicon, but it's hardly essential.

     

    I think my biggest peeve in the TIA is probably the sharing of player/missile NUSIZx settings. Even in a game like Combat, it would have been nice to have an option for a triple plane to fire a single bullet. For that to work well, though, it might have been necessary for the code to track the plane/shot positions (since aesthetically a single shot should be fired from the center plane, not the left one). Still, it's curious that the NUSIZx feature was included at all since it considerably complicated the hardware and I know of nothing really similar in any arcade predecessors. Of course, without NUSIZx the 2600 would have died off a lot sooner, but I'm still curious what inspired it.


  2. A few questions for Mr. Decuir which I've not seen discussed elsewhere. First off, though, I should congratulate Mr. Decuir for his involvement in an absolute work of genius. But on to the questions:

     

    -1- What were the constraints and optimization goals for the circuit designers? Was it to minimize the number of transistors, transistors plus resistors, or what? To what extent were interconnects considered at the circuit design level? There seems to have been some consideration given in the playfield module, but was layout an issue anywhere else?

     

    -2- How did the sprite horizontal positioning circuitry evolve? In particular...

     

    - Were it not for the multiple sprite copies, having a common horizontal position counter and then position comparators for each latch would seem a lot easier than the present system; such a design would not readily permit the multiple-sprite-copy feature, however. Were slip counters used because they could allow the sprite-copy function, or because they seemed like such a cool idea to borrow from the PONG design, or were they expected to work out more nicely before it was discovered that all the HMOVE circuitry would be needed anyhow?

     

    - How did the multiple-sprite-copies concept enter the picture? I can't think of any arcade hardware which used a finite number of close sprite copies (some games did omit bits from comparison logic, but that would result in copies all across the screen, rather than only near the 'main' player).

     

    - Did anyone at Atari ever know the virtues of hitting HMOVE just before the start of horizontal blanking (all the HMOVE pulses will work as normal, but the next horizontal blank won't be extended by 8 pixels).

     

    - Was the decision to have HMxx latch D4-D7 really predicted upon 'ease of coding', or hardware layout considerations? In what anticipated scenario would it ease coding?

     

    -3- Are there any design decisions where you think you 'lucked out', and made something much more useful than anticipated? Are there any which you wish you had done differently?

     

    Thank you Mr. Decuir for producing such a brilliant piece of amazingly simple-yet-powerful hardware. I wish I could manage something even 1/10 as great.


  3. ...and no sound (no room for that either).

     

    Sound doesn't have to take a whole lot of space. Perhaps as few as four bytes. Possibly even three. If you add a "STA AUDV0" someplace each frame when the bottom four bits of the accumulator are zero but before you handle your ball bouncing logic, you can then use a read-modify-write instruction on AUDV0 to produce a click. If you use INC AUDV0, you'll produce a level-ten click (clearing the zero flag and not affecting any others). If you do "LSR AUDV0" you'll get a level-8 click and the carry flag will be set (if you're lucky, the two-byte LSR instruction will let you avoid an SEC). If you replace AUDV0 with AUDV1 everywhere, the LSR will clear the carry.

     

    Not that such clicks would be considered 'great sound effects' by any stretch, but they'd be cheap to code. If you could somewhere squeeze in storing 4 to AUDCx and AUDFx, the clicks would be replaced by high-frequency beeps (at a cost of another four bytes).


  4. Good point. Although if you use VSYNC or CXM0P instead of 0, and set the TIA_BASE_ADDRESS in your code to $40, DASM should handle it for you automatically, right?

     

    It would, though in X07 banking, if bank E is selected, hitting $40-$7F will switch to bank F; if bank F is selected, hitting $00-$3F will switch to bank E. This is part of what makes the Stella's Stocking menu possible (the display needs direct access to ten pages of data, and the wave generator needs direct access to nine). The simple DASM remedy is to change the SLEEP macro to use "NOP $80" instead of "NOP $00", since that never triggers a bank switch in any scheme I know of.


  5. ...when all invaders are shot from the left column, all other columns move over to eliminate it from the equasion by ROLing their corresponding bits higher).

     

    BTW, one of my peeves with Space Invaders for many years (long before I had any clue how the 2600 actually worked) that the last invader on a row produces no explosion. I wonder why the row is skipped, rather than drawn with blank invaders plus an explosion?


  6. I'm working on a game like Tapeworm for the Atari 2600, and I need a little help. Right now, when you eat a treat, the worm is supposed to grow by one pfblock, which it does, but it does it on its own time. What I want is for it to do it automatically. How would I achieve this?

     

    How are you keeping track of the worm segments? A tapeworm-style game is unlikely to get very hard unless the worm can get quite long, and the 2600 doesn't really have a whole lot of spare RAM.


  7. Any kind of Atari dev, even if it's a homebrew is pretty cool. Maybe not expensive, but cool nonetheless.

     

    Cool indeed, from a historical perspective. I would very much second the notion that the batteries should not be left in the cart. It may be worthwhile to try to preserve the labels of the batteries (either by removing the labels, or gutting the batteries and storing them separately from the cart) to allow comparisons if other similar carts turn up. At minimum, preserve or copy down any markings that look like a date codes, serial numbers, etc. The actual guts of the batteries are 100% worthless, though.


  8. Rigurours synchronous design means such things as no ripple techniques, no divided or gated clocks, no async latches or delays, etc. These are issues all valid disregarding fully static or dynamic cells.

     

    It's true that different parts of the TIA use different clocks, but I would regard the TIA more as a collection of synchronously-clocked subsystems than a bunch of asynchronous ripple logic. Synchronizers are generally used when subsystems driven by slow clocks feed signals to those driven by faster ones; there are a few interesting race conditions:

     

    -1- sprite motion pulses are derived from sysclk/4, and are or'ed with a gated version of sysclk. In normal use, the motion circuitry will never have the /4 and /1 clocks enabled simultaneously; if they are both enabled, the timing of every fourth motion pulse will be skewed enough to cause distortion in the displayed sprite.

     

    -2- at pixel 79, the playfield color mode will get switched a little early, with the interesting effect that despite the output synchronizer, pixel 79 will often end up showing the right color on one half and the wrong color on the other.

     

    In general, though, the TIA is pretty straightforward. I've never looked at ANTIC, GTIA, etc.


  9. If you are familiar with high-speed modern synchronous designs, then just forget everything you learnt. There is no ultra rigurous treatement of clocking. I understand that TIA (which is a few years earlier) uses almost every conceivable ripple/gated clock technique that would be considered "shock-horror" nowadays.

     

    Actually, I'd say the reverse is true, in a sense. Many devices today use fully static designs driven by a clock which has minimum high/low times and a maximum rate, but no other requirements. Some devices use an internal clock multiplier which will only operate within a certain range of speeds, but the device logic itself doesn't care whether it's clocked fifty times per second or fifty million times per second. If the clock stops for a second, or even a year, the device will remain in the state it had just after the last clock pulse, and will resume functioning as soon as clock pulses start arriving again. At any given moment, all bits are securely "held" by part of the circuit. The operation of such a device might be likened to bucket brigade in which nobody lets go of a bucket until the next person has grabbed it.

     

    Dynamic logic, by contrast, has far more rigorous timing requirements. If those requirements aren't met, things can malfunction very badly. A dynamic design might be likened to a line of people who are juggling objects among themselves. Each object that is passed will be released by the old holder before it is caught by the new one. If the new one isn't in proper position to catch the object, it will fall on the floor. Of course, actual people who are passing objects can adjust their timing if needed, but imagine a line of robots who were all wired to operate in tandem from the same control signals. If the timing on those signals isn't right, things will all come crashing down.

     

    That having been said, there are straightforward ways of implementing dynamic logic and tricky ways, and nearly all of the TIA's dynamic logic fits the straightforward pattern: two-phase non-overlapped clocking. Most of the circuit modules in the TIA receive two clock signals which run in the sequence (low low) (high low) (low low) (low high). When a clock is high, the chips connected to that clock will drive their outputs according to their inputs; when the clock is low, the output will 'float'. An output which is floating will hold its state for a few microseconds; the output must be re-driven (meaning the inputs must have the correct data to do so) before that time is up. Two-phase non-overlapping clocks are pretty straightforward provided two requirements are met:

     

    -1- The two clock phases must never be high simultaneously; their separation must be sufficient to allow all the devices controlled by one clock to switch off completely before any of the devices controlled by the other clock switch on.

     

    -2- Neither clock phase may be allowed to go for too long without being active.

     

    While the TIA contains two three-bit ripple counters, a divide-by-three for the CPU clock, and some two-phase clock generator circuits and miscellaneous latches, most of the chip is controlled via two-phase non-overlapping clocks.


  10. Nobody said they are "all too different". They are just not that identical in the "precision improvement" scale you were talking about. You don't agree, then tell Best Electronics to stop selling "bad" (according to your logic) crystals.

     

    IMHO, it is useful and interesting to know the precise definition of colorburst being 1000/1001 times 30 frames/sec * 525 lines/frame * 227.5 cycles/line. That doesn't mean someone who doesn't specify it to the ninth place is "wrong", but merely that it's useful knowing where numbers come from. I still think that 1000/1001 multiplier is 'odd'; I understand that it's useful to have a number of clocks per line pair that's a multiple of small numbers (455=5*7*13) but I'm not sure why they chose 455 and then threw in the 1000/1001 kludge, rather than simply picking a different multiple (e.g. 495=5*9*11, or 429=3*11*13, or 441=3*3*7*7)?


  11. Anyone have screenshots from the PROTOTYPE version of Actionauts? I need them for my page, and to the best of my knowledge Rob has not released the original rom. If the homebrew version looks the same I can use screenshots from that version I suppose, but I don't know if it does.

     

    Tempest

     

    The first few levels should be visually identical to the originals, except for the copyright notice at start.


  12. Btw, I don't think there is any undocumented register, or even bit, in GTIA or in any of the chipset at all. What you have is a couple of things not 100% fully documented, bugs like the one in Antic, and some tricks like Bryan's method for shifting GTIA modes.

     

    I would expect there to be lots of undocumented registers, but for them not to be memory mapped; most of them will typically work together to mimic the behavior of documented "registers" that don't actually exist in the documented form.

     

    I'm not familiar with the CTIA/GTIA, but to borrow some examples from the original TIA...

     

    -1- The documentation shows that each sprite has a divide-by-160 counter. The documentation does not show that each sprite actually has a cascaded divide-by-four and a divide-by-forty. Usually, the cascaded counters behave like a divide-by-160, but the synchronization logic gets tripped up if a sprite is reset within a small window of its normal trigger point.

     

    -2- The documentation states that there is a pulser circuit which adds and subtracts pulses. It does not mention that the subtraction of pulses is achieved by delaying the end of hblank, nor does it mention that there is a four-bit counter that counts once every four pixel clocks except that if it's sitting at zero it will remain there until the next HMOVE. The documentation also does not mention that each sprite has a latch which turns its pulser on and off, and that this latch may be 'jammed'.

     

    -3- The documentation does not describe the particular behavior of the shift registers used in the audio generation circuitry. Though it accurately describes what any particular AUDCx mode will do in isolation, the description is not sufficient to know what will happen if AUDCx is changed while a sound is playing.

     

    All of those behaviors are the result of incompletely-documented registers. I'm sure many more examples could be found for the TIA.


  13. I don't like mazes/catacombs in adventure games. To me, they're like speed bumps or busy work.

     

    I really like the mazes in Adventure. In some games like Zork and Crystal Caverns, the mazes are essentially a randomly-linked collection of rooms. There is no realistic way of trying to explore them short of making a map, and there is nothing remotely logical about the interconnections. In Adventure, by contrast, the mazes make sense at least on a local spacial level. Go east from one room and--with few exceptions--you will proceed into a room whose west end connects to it. As one first starts to play Adventure, one will find oneself wandering aimlessly, but the different parts of the maze are sufficiently visually distinct that one will soon learn to recognize "Ah, this is that really annoying passage that goes on forever until it reaches that stupid dead end." Few games have mazes that work so well.

     

    Adventure was groundbreaking, but it was also top 40. Easy-to-understand concepts for simple minds. I think most games should have intuitive controls and I love easy-to-understand concepts, but I also like games that may not be so easily understandable in the first 5 seconds of play if the new concept is fun.

     

    Your attitude seems to be a little condescending. I would expect appreciation for more advanced games that build on the concepts of Adventure is probably a result of your having experience with the simpler ones. Before people had any exposure to even simple games, there was no way they would have been able to have any fun with more complex ones.

     

    You're not just on a treasure hunt, you're exploring terrain that changes every time you play (in the form of zones).

     

    I recall liking E.T. back in the day, though I never owned it (friends did). I really don't care for the style of game where you need to be directly on top of a zone to see it, especially if repeated playing is of no particular use in determining where things are apt to be. I don't mean to imply that everything should be placed identically in every game, but that the placement of objects and zones should make some "sense", so that one who plays the game enough will be able to recognize certain patterns.

     

    BTW, what do you think of Superman? In some ways it's more advanced than Adventure (despite having come out first) but I would regard Adventure as the better game. Adventure's mazes make sense in a way that Superman's city map really doesn't.


  14. My 2600 module has a problem: the player one paddle does not work properly. By comparing the voltages at the pins with a working one, I saw the difference in voltage. A repair scematic would tell you what to look for at that point.

     

    For some applications, a high-impedance (at least a meg or so) audio amplifier can be a useful diagnostic device. When playing a paddle-based game, the paddle input should have a 60Hz saw wave whose volume will be controlled by the paddle. If something else is heard, that would suggest a problem.


  15. At their cores, successful "adventure" games rely on a convincing simplification of a believable reality. In a game like Adventure, the abstraction of reality is not only convincing, it is immersive and intuitive. In fact, that's really the defining achievement and lasting legacy of that particular game, and, I'd wager, the primary reason why it is so beloved.

     

    I know what you're talking about with Adventure. Not sure why it works so well, but it definitely does. Better than Superman, IMHO. All the mazes make sense 'locally' even if their interconnections won't fit on a 2d map. Going north then south, or east then west, will almost always take you back to the same place (I think there are some exceptions involving the bridge, but that's it). And the handling of the killer ducks is brilliant. If your character merely died, I don't think they'd be nearly as scary, but instead you get stuck.


  16. Personally, I think two buttons would have been better and less confusing for these two functions, rather than one context-sensitive button.

     

    For one function you use the red button on the controller. What button would you use for the other function? Using two controllers is not a friendly solution (HSW did that in the game before ET).

     

    BTW, the use of the button in the pit is indicated by the "levitate" icon.


  17. Makes a big difference. The cycle-window for a normal-behaving HMOVE is actually pretty small...only about 4 cycles IIRC.

     

    A write to HMOVE triggers a latch that does three things: (1) it sets a another latch which is cleared at the end of each scan line, and which will delay the start of the visible portion of the next scan line by eight pixels (effectively pushing all sprites right 8 pixels); (2) it turns on a pulsing circuit for each sprite; (3) it starts the position-compare counter if it's not already running.

     

    Every four pixel clocks (1.33 CPU cycles) each pulser circuit will compare its HMxx with (position-compare-counter xor 8 ) and shut off if they match. Then the position-compare counter will be incremented if it's non-zero or if HMOVE was just written. After those things are done, every sprite whose pulser is enabled will receive a motion pulse.

     

    Motion pulses received during the visible part of the frame will distort a sprite's image but not move it. Each pulse received during horizontal blanking will move a sprite one pixel leftward.

     

    If an HMOVE occurs on cycle 73 or 74, all of the motion pulses that result will occur during the blanking interval, but the latch responsible for blanking 8 pixels of the next line will not get set (thus, outputting 0-15 pulses will cause sprites to move 0-15 pixels left). If the HMOVE occurs before cycle 73, one or more of the pulses will occur during the displayed part of the frame and the sprite will not move as far left as expected. If an HMOVE occurs within a few cycles of its normal time, the system may manage to output all of the required motion clocks during the blanking interval. If the HMOVE occurs too late, some of the motion clocks will occur during the displayed part of the frame and thus not cause motion. The more motion clocks need to be sent, the earlier the HMOVE must begin.


  18. Many of the "unstable" opcodes have behavior which will be influenced by things like temperature, manufacturing lot, phase of the moon, and other factors. The behaviors are not consistent enough be be useful, but are far too consistent to be used for random number generation.

     

    Sometimes "unstable" behaviors can be caused by race conditions. There is at least one race condition on the TIA that is readily observable. Enable SCORE mode and turn on bit 7 of PF2. The right half of pixel #79 may be an odd color; the exact behavior seems to depend upon temperature and other weird factors. The problem in that case is that the color circuitry for COLUP0 is being disconnected from the color multiplexer at the same time as the color circuitry for the right half is being connected, and both actions are happening while the output from the multiplexer is being sampled. COLUPF isn't supposed to affect the color of that pixel, but sometimes it does.


  19. Yeah, I would like to see what a snapshot of 640*200 software mode looks like.

     

    To get 640x200 one would need to have 320-dot resolution on the chroma. The Atari 8-bit machines don't. Certain hues will cause the left half of the even pixels and the right half of odd pixels to be brighter than the right half of even pixels and the left half of odd pixels, but without the ability to split pixels I'm not quite sure how that would be useful.

     

    It might be possible for the Atari 2600 to create a kinda-sorta 320-dot high resolution effect when used on a black and white television set, but I'm not sure how useful that would be. A somewhat more interesting possibility would be to use color cycling to create a visible motion effect on black and white televisions. In a game like "Adventure", for example, one castle and its key could have increasing cycling hues while another had decreasing hues. On a black and white television, one would have stripes that would move rightward, while the other would have stripes that move left.


  20. According to an email I received from Mr. Robinett, Atari wanted a Superman game, but WR wasn't particularly interested in doing one, so Atari gave the code to someone else to turn it into Superman. I don't remember getting a sense of whether Mr. Robinett felt or expressed any gladness that he was off the hook for Superman, or unhappiness that the first release of his kernel would be in someone else's game.

     

    BTW, was Warren Robinett's "Basic Programming" cartridge the first release with David Crane's text kernel, or did Stellar Track come first? None of David Crane's own released games used the text kernel, though it appears in a Boggle prototype.


  21. Is is safe to switch banks when you are in the RAM (I am executing a subroutine in the internal RAM of the 2600)? It works in Stella, but I just want to make sure it will work on real hardware.

     

    You can do pretty much anything with a cart while executing from the internal RAM on the 2600. Indeed, on some carts there are things that can only be done safely when running from internal RAM.

×
×
  • Create New...