Jump to content

SeaGtGruff

Members
  • Posts

    5,591
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by SeaGtGruff

  1. If you modify your maze just a bit, you can have just 27 bytes of data for each playfield register, with 8 scan lines left over at the bottom for displaying a score bar, timer bar, or something like that. Attached is a mockup of what the modified maze would look like, plus a blank form that you can use for designing additional mazes. Edit: The silver lines represent the boundaries of the maze building blocks as it were, and the black lines represent the boundaries of the playfield registers, to help you with coding the data bytes.
  2. I don't think all of the mazes would be possible on the 2600, because some of them have too high of a horizontal resolution. Those screens would need to be redesigned for the 2600.
  3. Actually, three games were done, and the third contest was apparently going to be held but then was cancelled after Tramiel bought Atari-- so the final three prizes were never awarded (the crown for WaterWorld, the philosopher's stone for AirWorld, and the sword for the Grand Finale contest). All of the prizes (except for the EarthWorld talisman, which had already been awarded) were on display at the FireWorld contest, so they were all in Atari's possession at that time, therefore the Franklin Mint didn't have them anymore.
  4. Yes, except the current checkerboard pattern has blocks that are 4 color clocks wide, and I was thinking of a checkerboard where each block is just 1 color clock wide. If a stationary sprite can't be drawn on top of the scrolling text, it would be more convenient to draw the checkerboard immediately below the scrolling text.
  5. That's interesting. What about 0-2-0-2? I wonder if drawing a sprite on top of the playfield-- say, a checkerboard pattern or something-- would help identify the exact amount of scrolling that's taking place on each frame? It would probably be best to have the playfield and sprite be the same hue, but with different luminance values so you can still tell them apart. It would still be great to have a 1-pixel scroll, but if it can't be done exactly, or not consistently on different models, then a 2-pixel scroll (if consistent on different models) should probably be enough to give a smoother scroll.
  6. In the MOVs and JPGs it looks like the "1" kernel scrolls more than 1 pixel (as others have noted), such that there's very little difference between the "1" and "2" frames. Just a thought, but I'm wondering how it would look if you try a 3-frame scroll-- 0, 2, 3, 0, 2, 3-- since there's so little change between 1 and 2 anyway? It might not be as smooth, but it also might not look like there's a slight "pause" from when the 1-2 frames are displayed (since they're so similar in position which might make it look like a single frame being displayed twice as long as the others)? Edit: Or better yet, 0-1-3-0-1-3. Or a 2-frame scroll, 0-2-0-2-0-2.
  7. I actually started to reply a couple of times, but my responses started getting way too complicated, so I never finished them. I'll see if I can answer simply. Generally speaking, you can write to the playfield and sprite graphics registers (as well as their color registers) in any order, as long as you write the desired values to them sometime before the TIA needs to draw them. But the 2600 has no video memory per se, just the registers for the graphics and colors, so anything you write to those registers will be displayed over and over again on the subsequent scan lines until you write new values to them. In your case, you're using a mirrored playfield, which means you can write to the three playfield graphics registers once per line, and even leave them alone for several scan lines for the portions of the playfield that stay the same for several scan lines. In other words, if you design your loops correctly, you don't need 192 bytes of data for each playfield register, just the data for the unique lines. The following example is pseudo-code written in a hypothetical BASIC (not batari Basic) to illustrate what I mean: rem * suppose the first playfield row is 8 lines tall read PF0data, PF1data, PF2data PF0 = PF0data PF1 = PF1data PF2 = PF2data for x = 1 to 8 WSYNC = 0 : rem * strobe WSYNC so the playfield is drawn the same for 8 lines next x rem * suppose the next playfield row is 16 lines tall read PF0data, PF1data, PF2data PF0 = PF0data PF1 = PF1data PF2 = PF2data for x = 1 to 16 WSYNC = 0 : rem * strobe WSYNC so the playfield is drawn the same for 16 lines next x rem * etc. On the other hand, you'll want to draw the player-missile sprites anywhere, so the loop(s) will need to include code for that, too-- in which case, if ROM isn't an issue, you might as well just have 192 bytes of playfield data for each line, since it will be simpler to include the code for the player-missile graphics and colors. If you need to load and store too much data per line, such that you can't do it all during the HBLANK period, you'll need to count cycles and determine where on the scan line each instruction is getting executed, then if you need to you can rearrange some of the instructions. For instance, the TIA needs to draw PF0 first, so you'll want to load PF0's data and store it sometime before HBLANK ends, but you can write to PF1 a little bit after HBLANK ends, and you can write to PF2 a little bit after that, so if you need to you could write to PF0, then write to GRP0, then write to GRP1, then write to PF1, then write to PF2, or something like that, as long as each register gets written to by the time the TIA needs to draw from that register. The joystick registers are part of the RIOT chip-- SWCHA, or location $0280. You'll need to use SWACNT ($0281) to set the desired bits of SWCHA to the input mode-- if you want to read both joysticks, just set SWACNT to 0-- then you can read SWCHA at least once per screen to get the joysticks' values. There are two basic philosophies here-- one is to read SWCHA once per screen and store its value in RAM for future reference, and the other is to just read SWCHA as many times as needed per screen (you'll need to bit-mask the value to check each of the directions, hence the need to either store its value or reread it as needed). The upper nibble of SWCHA is the left joystick, and the lower nibble is the right joystick: D7 = left joystick pushed right D6 = left joystick pushed left D5 = left joystick pushed down D4 = left joystick pushed up D3 = right joystick pushed right D2 = right joystick pushed left D1 = right joystick pushed down D0 = right joystick pushed up If a given bit contains a 1, it means the joystick is *not* being pushed in that direction; but if the bit is 0, then the joystick *is* being pushed in that direction. Thus, if SWCHA contains 255 (all 8 bits set to 1), it means neither joystick is being pushed in any of the directions. But if, for example, SWCHA contains the value %10100000, then the left joystick is being pushed to the right and down simultaneously, whereas the right joystick isn't being pushed. The joystick buttons, on the other hand, are read from the TIA at INPT4 (address $0C, left joystick's button) and INPT5 (address $0D, right joystick's button).
  8. Regarding the mockup you posted, it looks more or less doable, but you'll need to adjust it a bit. The playfield has a horizontal resolution of 40 pixels, so your vertical walls and vertical halls need to add up to 40. When I count the number of wall columns I get 18, and when I count the number of hall columns I get 17, so in general the formula would be 18x + 17y = z, where x is the width of a wall column, y is the width of a hall column, and z is the width of the entire screen, which in this case is 40: 18x + 17y = 40 You'll want x to be 1, so 18 + 17y = 40 17y = 22 That means the halls will be 1 pixel wide, with 5 pixels left over that you could distribute among the halls (i.e., some halls could be 2 pixels wide). Or you could decrease the number of walls and halls so that all of the halls can be 2 pixels wide: 1x + 2y = 40 In this case x is the number of walls and y is the number of halls. Since there will always be 1 more wall than there are halls, this can be rewritten as 1(n + 1) + 2n = 40 where n is the number of halls, so n + 1 + 2n = 40 3n + 1 = 40 3n = 39 n = 13 So if you have 13 vertical halls, and 14 vertical walls, you could have the halls be twice as wide as the walls. Otherwise, if you want to get the maximum number of halls, they'd all be 1 pixel wide-- except for the central hall, which would be 2 pixels wide-- as follows: 1n + 1(n -1) + 1 = 40 2n = 40 n = 20 So the maximum would be 20 walls and 19 halls.
  9. Your code is setting the playfield color register multiple times, whereas I assume you meant to use the playfield graphics registers-- PF0, PF1, and PF2. As Rybags mentioned, you need to update the playfield graphics registers whenever you want them to change. In rare cases you might be able to set them once, but that's only if they're going to keep the same graphics for the entire height of the screen-- such as if you want to draw only vertical walls on the screen from top to bottom, with no openings in the walls and no horizontal walls. The "best case scenario" is where you're going to use either a reflected or repeated playfield and the screen will be split into a certain number of vertical zones-- similar to the screens in Atari 2600 Adventure or Atari 2600 Superman-- such that you can update the playfield graphics once every so many scan lines. The "worst case scenario" is where you want the left and right halves of the playfield to be completely different (an "asymmetrical" playfield), because that means you'll need to update each playfield graphics register twice on each line, and the updates will have to be properly timed or the display won't come out the way you want.
  10. The following is taken from a spreadsheet I made to simulate part of the TIA's processing. The HSC (horizontal sync counter) bits are shown in reverse order (i.e., low-to-high) so they're in the same order shown on the schematic. I'm starting with HSC 101001, which is the next-to-last value before the HSC resets itself. HSC = 101001 | END = 0 | SHB = o | RHB = 0 | /HB = 1 | BLANK = 0 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 0 HSC = 010100 | END = 1 | SHB = o | RHB = 0 | /HB = 1 | BLANK = 0 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 0 HSC = 000000 | END = 0 | SHB = 1 | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 0 HSC = 100000 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 0 HSC = 110000 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 0 HSC = 111000 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 0 HSC = 111100 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 1 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 0 HSC = 111110 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 1 | SYN = 0 | RCB = 0 | CB = 0 HSC = 011111 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 1 | SYN = 0 | RCB = 0 | CB = 0 HSC = 101111 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 1 | SYN = 0 | RCB = 0 | CB = 0 HSC = 110111 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 1 | HS = 1 | SYN = 0 | RCB = 0 | CB = 0 HSC = 111011 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 1 HSC = 111101 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 1 HSC = 011110 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 1 HSC = 001111 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 1 | CB = 1 HSC = 100111 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 0 HSC = 110011 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 0 HSC = 111001 | END = 0 | SHB = o | RHB = 0 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 0 HSC = 011100 | END = 0 | SHB = o | RHB = 1 | /HB = 0 | BLANK = 1 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 0 HSC = 101110 | END = 0 | SHB = o | RHB = 0 | /HB = 1 | BLANK = 0 | SHS = 0 | RHS = 0 | HS = 0 | SYN = o | RCB = 0 | CB = 0 etc. I didn't include the LRHB signal above, since you're interested in a "normal HBLANKing" line, but it would occur on the next horizontal count. Note that the BLANK signal is actually delayed by half of a color clock so that it changes from low to high, or vice versa, when the pixel clock (CLKP) goes from low to high. I've used "o" for "off," because-- if I've understood the schematic correctly (which might not be the case)-- the SHB and SYN signals are either "off" or otherwise. In the case of the SHB signal, when it isn't "off" it's high, so you can think of SHB as being 0 wherever I've shown it as "off." But in the case of the SYN signal, when it isn't "off" it's low, so I guess that means you can think of SYN as being 1 wherever I've shown it as "off." I admit that that portion of the schematic is a bit of a mystery to me, because I'm not sure how to interpret it. I didn't include the /VB signal above. To summarize: BLANK is high for 17 counts (68 clocks), but its transitions are delayed by half a clock so they're in sync with the pixel clock (the high-low periods of CLK and CLKP are inverted from each other). SYN is low (active) for 4 counts (16 clocks), beginning about 5 counts (19.5 clocks) after BLANK goes high. CB is high for 4 counts (16 clocks), beginning as soon as SYN is turned off. BLANK remains high for about 4 counts (16.5 clocks) after CB is turned off. But I can't swear that the above is 100% accurate, since my spreadsheet doesn't simulate any propagation delays.
  11. There's a big difference between data bytes and registers. If a register doesn't use a particular bit, that bit isn't just ignored by the register-- it doesn't exist. In other words, the TIA color registers contain only 7 bits. So you can use any ignored bits for other things in the data, but that doesn't mean there are extra bits in the registers that can be used for storage. Anyway, the TIA registers are either read-only or write-only, so even if the ignored bits did exist in the registers themselves, you wouldn't be able to store anything in them and then read them back. PS-- SWCHB is a 6532/RIOT register, not a TIA register, which is why the unused bits are available for storage-- the SWCHB register has 8 bits, and you can read from it or write to it depending on how you've set the control bits.
  12. Or you could shift the byte right, moving the lowest bit into the carry flag, and branch to one routine or another depending on whether carry is set. That way the color data can be used as-is for color purposes, but you can still use the lowest bit for some other on/off variable. In fact, I think that might be how batari Basic tests the lowest bit when you use it as a bit variable-- by shifting the byte right and then checking the carry flag.
  13. I'm not sure how well strobing RSYNC night work with video, since it will alter the scan line length and probably scramble the picture-- if not on all TVs, then certainly on some. However, as it happens the other day I was thinking about a different potential use for RSYNC-- namely, changing the TIA's base audio frequency. I haven't tried it yet, but in theory if you strobe RSYNC after X cycles, you should be able to raise the base audio frequency and get a different set of notes. In other words: X = 76 cycles, base audio frequency = 31399.78 Hz X = 75 cycles, base audio frequency = 31818.44 Hz X = 74 cycles, base audio frequency = 32248.42 Hz etc. These are NTSC values; for PAL/SECAM they would be lower. In general, the base audio frequency equals 3579575 Hz (or 3546894 Hz for PAL/SECAM) divided by the number of color clocks per line, then multiply by 2. But in practice it's a little more complicated than that, since the audio clocks are generated twice per scan line at specific points on the scan line, so if you shorten the scan lines you'll get pulse waves that have differing duty cycles. The TIA has two audio clocks-- phase 1 and phase 2-- but the phase 2 audio clock is when changes occur, similar to the way that the phase 2 horizontal clock is when changes occur in drawing the playfield pixels. The phase 2 audio clocks normally occur every 28 or 29 horizontal counts-- or twice every 57 horizontal counts (where 1 horizontal count equals 4 color clocks)-- which is as close to a 50% duty cycle as possible with the TIA (since 57 isn't evenly divisible by 2). So if you shorten the scan lines, the phase 2 audio clocks will occur every 28/28 counts (a perfect 50% duty cycle), or every 28/27 counts, or every 28/26 counts, etc. But I'm not sure if that's right, because RSYNC would be strobed at the CPU rate (multiples of 3 color clocks), whereas the count rate is different, so I guess the last count on each line could correspond to fewer than 4 color clocks. If you strobe RSYNC often enough, you'll end up with only one phase 2 audio clock per line, but each line will be only half as long (or less) as normal, so you'll still get a higher base audio frequency. Anyway, in theory it should be possible to determine which notes will be most in-tune for any given value of X, then create a kernel for a music player that strobes RSYNC every X cycles depending on which note is to be played, such that every note is as close to being in-tune as possible. But this wouldn't help with game music, since strobing RSYNC will presumably ruin the video, so you'd probably want to blank the video-- i.e., this might be useful for playing music without any picture. Obviously, it would be more useful for game-development purposes to use the Harmony's DPC+ music features-- but it might still be interesting to see what could be done with this idea. Note that since the base audio frequency would be the same for both audio channels, this idea would work best for monophonic music, although both channels could be used as long as the notes to be played on each channel were in-tune for the given X. I'll see if I can write a program to test this idea. My plan would be to set AUDC0 and AUDF0 to specific values and leave them there, then let the user increase or decrease the RSYNC rate by moving the joystick, to see how the sound changes as the RSYNC rate changes.
  14. There were a number of chips called "RIOT," which I presume were all variations of each other (similar to the way the 6507 and other CPUs were variations of the 6502). The specific RIOT chip that the 2600 used is the 6532. You can find documentation for it (pinouts and other specs) at the http://www.6502.org web site.
  15. I didn't mean that VBLANK isn't useful-- I was really referring to "drawing" with VBLANK, as I'd done in my old "Blue Maze" demo (which I unfortunately can't find right now). VBLANK is definitely useful for extending the HBLANK period, or-- as you pointed out-- covering up any unwanted graphics. But since the smallest "pixel" of blanking is 9 color clocks wide (3 CPU cycles, the shortest possible time needed to turn VBLANK on and then off again, or off and then on again), you can't really use it to draw objects on the screen-- well, you can, but the usefulness of doing so is limited by the size of the "pixels," as well as the limitation that a blanking "pixel" must start and end on a 3 color clock boundary. Additionally, trying to "draw" an object with the blanking requires you to devote a portion of the scan line time to turning VBLANK on and off, which takes away from the time you have for drawing the other graphics. My "blue maze" demo was essentially a "proof of concept" program to show that you can "draw" with VBLANK, but since the walls and corridors of the maze were 9 color clocks wide, there were only 17 or 18 "pixels" on each scan line, therefore the maze wasn't very detailed or difficult to "solve." As long as all of the other graphics (sprites) were set up during HBLANK and there were no need to strobe the RESxx registers during the scan lines, it would be possible to have sprites running around in the maze-- although any "collision detection" would have to be based purely on the sprites' positions, since sprites can't "collide" with the blanking.
  16. So if I understand you correctly, the extra CS lines were included during the TIA's design stage so the Atari 2600 could have more memory-- but Atari ended up not doing anything like that with the extra lines, so when they were putting together Revision E of the TIA they decided to delete the extra lines?
  17. The blanking isn't the same as the sync. To do interlacing on the 2600 I think all you need to do is turn on the sync at the right time-- and of course blanking must also be on, but that's the same for the normal progressive video. Turning blanking on and off during an active line doesn't affect the sync at all, it just lets you "draw" black areas on the screen-- not very useful (although extending the HBLANK period can be useful), since the minimum horizontal resolution of such a "blanking pixel" is 9 color clocks (3 CPU cycles). Several years ago I wrote a couple of test programs, one that drew a maze on the screen by using blanking for the walls, and another that compared the blanking with regular black pixels by drawing alternating lines (odd lines alternated between blanking and active video, even lines alternated between black and red). The second program actually helped to improve the Stella emulator a bit, since I noticed that the blanking wasn't lined up with the black pixels in some emulators, although it was in Stella. It turns out that there's an extra 1-color-clock delay in the blanking signal, and at that time Stella wasn't emulating this properly. (This was several years ago; it's been corrected in Stella for a long time now.) I loved your work on interlacing the 8-bit computer, by the way!
  18. This is interesting! I wrote a RIOT timer test program in batari Basic that runs as expected on my 2600, but (if I remember correctly) has an issue on the 7800 when using the T1024T mode. I wonder if this has any bearing on that?
  19. I don't think the electrical level of the /BLK signal itself has anything to do with "blacker than black"-- I think it just indicates when the blanking is active. I don't know what the motherboard does with the signal, so it might be another pin that could have been omitted from the get-go. On the other hand, you can "draw" with the blanking in the middle of active scan lines by turning the blanking on and off manually. I don't know how that works with the PAL TIA-- maybe the color output is set to hue 0, luminosity 0 whenever blanking is active? The 8-bit computers take care of the video for you, so I suppose you can't "draw" with the blanking that way unless you turn off ANTIC?
  20. The colors on my 2600 "heavy sixer" are bright and saturated, but the colors on my 7800 are dim-- but I think it might be partly due to age, as my 2600 is a more recent purchase (and I think it was cleaned up and refurbished by the merchant I bought it from), whereas my 7800 is around 30 years old and has never been repaired or cleaned up. On the other hand, I think I read that there can be quite a bit of difference in the brightness of the 2600's colors from one revision to the next-- or maybe I'm thinking of the Atari 8-bit computers-- so it could be the machines themselves (differences in the wiring, circuitry, etc.).
  21. All four CS pins are inputs. Only two CS pins were truly needed for selecting the TIA chip. If you look at sheet 2 of the TIA schematics, it shows that all four CS pins were used. But on the left side of that page are some notes for "CHIP REV. E," and note number 2 says "2. CS1 + /CS3 DELETED." I don't know why Atari originally had four of them-- maybe some kind of redundancy, just to be on the safe side? And I assume that when the CS1 and /CS3 lines were removed inside the TIA, those two pins became NC or "not connected" pins. I wonder what other things they might have been used for if they'd been available from the beginning? For example, it would have been possible to use one of them for a second audio out pin on the PAL TIA-- or rather, keep the two audio outs from the NTSC TIA, plus the /BLK line, and use those two unneeded CS pins for PAL-S and PAL-I (although I don't think the /BLK line was needed for PAL, anyway, since I don't think PAL has the "blacker than black" blanking level that NTSC does-- although that doesn't mean that a /BLK signal would be worthless for PAL).
  22. There are six audio registers, but they don't have pins dedicated to them-- they get data from the data pins when you write to them. The only audio pins are the audio out, which is combined into a single pin on the PAL TIA. The A0 through A5 pins are the bits for the addresses, which tell the TIA which registers you want to write to or read from.
  23. Somebody at http://www.6502.org might be able to answer that question.
×
×
  • Create New...