supercat
Members-
Content Count
7,259 -
Joined
-
Last visited
Content Type
Profiles
Member Map
Forums
Blogs
Gallery
Calendar
Store
Everything posted by supercat
-
They had 128 bytes each of RAM if I recall. In 1984, an 8Kx8 RAM chip was a rather pricey item; even 2Kx8 chips weren't free. Mask ROM was pretty cheap, but RAM wasn't yet.
-
Barnstorming - Game #1 - 32.04 - What the...?!?!!
supercat replied to Jeffy Arensmeyer's topic in Atari 2600
Sound and CPU loading wouldn't affect a Barnstorming time, but it would seem plausible that the game might increase a player's speed as a reward for flying extremely close to a windmil. -
Combat can be either a good game or a bad game depending upon the skill level and motivation of one's opponent. Without an opponent, it is completely pointless. Even adding a plane variation in which one of the planes flew around rapidly and randomly (but didn't fire) would have allowed some single-player entertainment without much extra programming. BTW, everyone always seems to think that in biplane-vs-bomber the biplanes have an insane advantage, but somehow when I take bomber I usually do pretty well. Is that just because I can't find good opponents or what?
-
1984 is maybe a bit far back, but I was aiming pre-crash. By 1989, other systems were already starting to take over the market and the Atari was considered 'closeout' material. BTW, 16K+16K would probably have been a bit much even in 1989. 32K+8K would probably have been more reasonable, though even that would have been a stretch (IIRC, an 8Kx8 RAM would have been about $3, which would turn into $12 retail--and that's just for one chip) I will grant, though, that I was probably being a little too much of a killjoy though as a programmer who often programs for tiny processors (e.g. 2K instructions and 128 bytes RAM) I tend to admire 'cute' approaches. Perhaps, though, the right way to view things is that the goal on an Atari is not to pack stuff into 4K (or 16K, or 2K) of code space, but rather to pack stuff into 76 cycles. And that's a constraint that doesn't vanish no matter how much memory you throw in.
-
A mask ROM really? Or an OTP? What reason would there be for Atari to make $tens of thousands worth of diagnostic cartridges?
-
Can anyone explain what one is supposed to do in that game?
-
Funny--I was going to mention that game. Actually, though, I should not disparage that cartridge too strongly, since I actually use it a fair amount. The original ROM chip is no longer in it, but unlike many carts this will accept a standard 27C64 EPROM. I no longer have any EPROMs of my first coding efforts; they've been replaced with other game images (I used Harry Dodgson's 7800 cart for some later development). BTW, Froggo Karate never worked right on my TV. Anyone have a scan-line count for that stupid thing?
-
Search for a program called "22nice". That's a CP/M 2.2 emulator that works pretty well.
-
I already took that into consideration. Note that on half the scan lines I do nothing except load a PF register from a temp. The idea would be to arrange the code so that the store would occur at a suitable time. Getting the timing might require adding a few extra register save/restores, but since the X register isn't used for anything it may not, and even if it does there should still be enough cycles to handle it. The most notable oddity would probably be that the four sets of columns would likely end up not all appearing the same length for any particular 'programmed' length (depending upon where the ror/cpy code was placed). This shouldn't be a problem, though, since the code that sets up the lengths could take that into consideration.
-
Yeah, but there's a 1:1 correspondence between old and new byte values. I'd tend to think something like: lda random1 lsr ror random2 ror random3 ror random4 bcc nocarry eor #$A3 sta random1 nocarry: ... would yield more randomish behavior with a period of 4,294,967,295. If you only want to use three bytes for your generator, eliminate the "ror random4" instruction and use an "eor" value of #$DB. If you want to use two bytes, use an eof value of $BD. Note that it is possible to run one of these generators 'in reverse' if necessary (e.g. if using it to generate random playfield data in an environment where a player can fly up or down). lda random1 add #128 bcc nocarry eor #$A3 nocarry: rol random4 rol random3 rol random2 rol sta random1 Cute, eh?
-
I think the idea of connecting Ataris via the joystick ports would be cool. Using anything other than a direct connection might be tricky, though, since the Atari lacks any sort of UART functionality and blanking the entire screen during communication would be most uncool. Thus, it would be necessary for both Ataris to be operating in lockstep with each other so that each would be communicating precisely when the other one was expecting to hear it. Over a short direct cable, this shouldn't be a problem. If one of the Atari units is called the 'master' and the other the 'slave', the units could be set up roughly as follows: (Master) At scan line #220, start blanking At scan line #228 start outputting a pulse and waiting for the reply Once you get the reply, communicate some data (you have about 16 lines to do it) If you've gotten to scan line #236 without a pulse, give up for that frame At scan line #259 turn on VSYNC At scan line #262 turn off VSYNC and restart frame (Slave) At scan line #220 start blanking Start looking for a pulse. If you find one before line #236 make note of where you found it and do the necessary communication. If pulse was found before scan line #224, trigger VSYNC/frame end at line #258 and 261; if after line #232, VSYNC/frame end at #260/263; if never seen at all, VSYNC/frame end at 269/272. Otherwise at #259/#262 The result will be that the slave's frame timing will be synced to the master within a few scan lines. The slave may sometimes outout a long or short frame if necessary to keep things in synchronization, but frame length should always be reasonable.
-
Has anyone been looking any more at the ooze concept? If one wanted to control 32 pixels (using reflected mode, and aiming for perfectly-timed stores to PF2) it should be possible to get two-line resolution using an eight-line kernel. The key would be to store the height of each column in two ways: the most significant bits would be stored using 32 bytes of RAM, one per column. The least-significant two would be stored in "bitplane" format, to allow for parallel processing of eight columns at once. A rough sketch of the code necessary to handle one group of eight columns throughout eight scan lines would be: ; Assume Y is line counter ; This first bit of code may be split among scan lines lda now0 sta was0 cpy lineheight00 rol cpy lineheight01 rol cpy lineheight02 rol cpy lineheight03 rol cpy lineheight04 rol cpy lineheight05 rol cpy lineheight06 rol cpy lineheight07 rol sta now0 ;49 cycles for this bit [plus a little more if it's necessary to save/restore regs] ; Remaining code is one snippet per scan line. lda bitL0 ora bitH0 ora now0 and was0 sta temp0 sta pf1 ...; 18 lda temp0 sta pf1 ...; 6 lda bitH0 ora now and was0 sta temp0 sta pf1 ...; 15 lda temp0 sta pf1 ...; 6 lda bitL0 and bitH0 ora now0 and was0 sta temp0 sta pf1 ...; 18 lda temp0 sta pf1 ...; 6 lda now0 sta pf1 sta was0 ...; 9 lda now0 sta pf1 ...; 6 This takes 49 plus 84 cycles to do about 1/4 of the work necessary for eight scan lines. Multiplying this by four yields 532 cycles (out of 608). Not exactly huge gobs of slack time left, but there should be enough. I would expect the code could be optimized further, but the key here is to note the approach. Actually, using the bitplaned-counter approach might be more efficient than using the discrete counters for even the upper bits, but I haven't worked out how to do it really efficiently.
-
Well, getting a 2600 to do cool stuff by ANY means is nothing to sneeze at, but the way I see it, if someone took one of today's better homebrew 4K or 8K carts back in time to 1984 and went to Atari or Activision with it, they'd be extremely interested. By contrast, if you went back in time with a game that required 128K of ROM and 32K of RAM, they'd wonder what you were smoking. I'm sure different people have different goals, but to my mind part of the fun of 2600 coding is thinking about what would have been possible in 1984. Even if a game with 128K of code and 32K of data storage would have been theoretically possible back then, from a practical standpoint it would have been unmarketable.
-
Session 23: Moving Sprites Vertically
supercat replied to Andrew Davie's topic in 2600 Programming For Newbies
Pitfall II actually uses a different method for vertical motion. Unfortunately, it's not likely to be available to most 2600 programmers, but it's interesting to know about. The Pitfall II cartridge, rather than using a normal ROM chip, uses a custom chip with special hardware that automatically does the address calculation and table lookup. Software writes some special on-cartridge registers to select a sprite and set its vertical position, and can then simply read a special address to get the proper byte of data for that sprite. This makes possible effects that would be literally impossible with just straight code. Unfortunately, I don't think anyone makes a cartridge that emulates the Pitfall II hardware, and the fact that the hardware is combined on the same chip as the ROM means it can't very well be used for other games (it might be somewhat interesting to design a cartridge which plugged into a 2600, and which would accept a Pitfall II cartridge that was plugged in, and which would use the Pitfall II cartridge with custom code; I wouldn't be surprised if Activision built such a thing for development. Unfortunately, even if such a thing worked, whatever game one designed would have to use the Pitfall II shapes. -
Session 19: Addressing modes
supercat replied to Andrew Davie's topic in 2600 Programming For Newbies
I've seen different 6502 assemblers handle this issue differently. My preferred approach is to have four-letter mnemonics which explicitly specify zero-page or non-zero-page addressing, and otherwise have the addressing mode be inferred based upon the numerical value of the operand. Trying to use the way in which the operand is written to make such inference can be dangerous unless the assembler distinguishes among eight-bit labels, sixteen-bit labels, and numeric quantities. For example, suppose I write the following: foo equ $FF bar equ foo+1 lda (bar-1) What addressing mode should be generated? BTW, I would suggest that when coding for the Atari, a good way to address the TIA or RAM using absolute addressing mode would be to simply add 256 to the address, since addresses $0100-$01FF map to $0000-$00FF. -
Session 11: Colourful Colors
supercat replied to Andrew Davie's topic in 2600 Programming For Newbies
This presupposes that the stack pointer is set somewhere in usable RAM. On most computers, this would be a reasonable assumption, but not on the 2600. Many programmers do weird tricky things like point the stack pointer at TIA registers. Using a "JSR KnownRTS" instruction in such cases will cause the processor to execute code in some 'random' spot. BTW, if the IRQ vector points to an RTI, a BRK instruction followed by an arbitrary byte could be used for a slightly more compact time-waster in cases where the there are 3 bytes available at the stack pointer. -
Session 5: Memory Architecture
supercat replied to Andrew Davie's topic in 2600 Programming For Newbies
I wouldn't be terribly surprised if $0030-$003F map back to $0000-$000F, but I would expect that $0040-$005F would map to $0000-$001F [rather than to $0010-$002F as your diagram would suggest] -
The 6502 is a chip mounted in a 40-pin lead frame; the same chip was made available in a 28-pin package under a variety of part numbers by simply leaving off some pins. Applications which didn't need to connect all the pins on the 6502 could save a little bit of money and a 1.2"x0.7" area of board space by buying a package with 28 pins instead of 40. The selection of pins on the 6507 is somewhat curious, which leaves me wondering how it came to be.
-
Session 2: Television Display Basics
supercat replied to Andrew Davie's topic in 2600 Programming For Newbies
A standard NTSC frame (two fields) consists of precisely 525 scan lines of 227.5 chroma clocks each. The Atari hardware outputs 228 chroma clocks per scan line, thus producing a horizontal scan rate which is about 1/4% slow. Using 262 scan lines instead of 262.5 helps make the vertical scan rate more nearly correct than 263 though in practice it doesn't matter. A standard NTSC field (1/2 frame) is precisely 59,718.75 / 3,579,545 second. A 262-scan-line Atari 2600 field is 59,736 / 3,579,545 second, i.e. about 0.002% slow. BTW, this translates into a frame rate of 59.92Hz. Programmers who work with other systems may find it interesting to note that on platforms which output 227.5 chroma clocks per scan line, using 262 scan lines per frame will yield a different screen appearance from using 263. Using 262 scan lines, a solid color will generate a faintly visible stationary 'checkerboard'; using 263 scan lines, the checkerboard will alternate phases each frame. I would expect that the PAL hardware on the 2600 always starts each frame in the same color phase, thus requiring the use of an even number of scan lines. -
Session 17: Asymmetrical Playfields - Part 1
supercat replied to Andrew Davie's topic in 2600 Programming For Newbies
Is that the start of horizontal RETRACE or horizontal BLANKING? My recollection is that the TIA reenables the 6507 when the electron beam hits the right-side border, which is actually a fair bit before the beam actually starts sweeping left. I fully appreciate that it's often useful to regard a scan line as starting as soon as the displayed portion of the previous one ends (indeed, that's how I've drawn timing charts when working out code) but in some goofy cases the distinction might be important. BTW, would STA $xx be suitable for use as a three-cycle NOP, where $xx is a non-existent TIA write register? I know that some registers like $3F may be used for some bank-switching carts, but I would think some should be available. -
Forgive me if this is answered elsewhere, but what are the requirements for RAM/ROM? It would seem really neat to have a level-based game using the SuperCharger, with messages to "Load track 13" [for people with the "levels" on CD]. Unfortunately, I don't think Boulderdash would likely fit on that; unless the currently-active level is packed two characters per byte (I think there may be fewer than 17 character types, making this possible) I would think that the holding the current level alone would nearly fill up the SuperCharger, and that's before you start putting in other annoying things like code... I know there are some cartridge platforms that add really huge amounts of memory to the Atari, but somehow that seems a little anachronistic. Yeah, it would be possible to design a game to use 128K of flash and 32K of RAM, but that wouldn't really seem like an "Atari" game. OTOH, I've sometimes thought it would be amusing to build a "cartridge" which included a FIFO, a CPLD, and a modern embedded PC. The PC would generate instruction sequences in real-time for the 2600 to execute and the FIFO would feed them to the 2600. The 6507 wouldn't be doing a whole lot of processing--the only instructions would be LDA, LDX, and LDY (immediate), STA, STX, and STY (both zp and abs versions) TSX, TXS, NOP, and BIT (abs). The CPLD would include special logic for the latter instruction to capture the operand fetch when it appears on the bus. Conceptually, this would be somewhat like the way Pitfall II works, but in more extreme fashion.
-
Forgive me for asking, but is there a FAQ someplace that says where to find all these goodies? BTW, as I think about it, my current inclination would probably be to do a version of Mahki/Boxxi/Bubble Ducky/etc. on either an 8x16, 16x12, or 16x16 grid using a venetian-blind color trick somewhat like Boulderdash but better [but unsuitable for full-screen-width use]. Should require somewhat less tricky coding than my other ideas while still being pretty playable.
-
Well, Wormy is a bit different from those games: -1- Unlike Surround or (as far as I can tell) Warring Worms, the Wormy worm has finite length. This requires keeping track of where the worm has been to allow for erasing the tail. With a 32x16 playfield, a worm should probably be allowed to grow to a length of at least 64. Even with optimal coding, keeping track of the worm tail would thus require a minimum of 16 bytes. I don't know how Tapeworm keeps track of the worm's tail, but I notice its grid size is about 32x16. -2- Unlike Commodore's Slither (from which Tapeworm seems to be derived), which only shows one goodie at a time and has no obstacles other than the snake's tail, Wormy has a playfield laden with mines and goodies. Best-case storage would probably be about 16 bytes to keep track of 128 objects which could be goodies or mines (I would have one or more ROM-based maps showing where the 128 object-spots were; if a bit in the 128-bit bitmap was set, the corresponding spot on the playfield would be occupied by either a mine or a goodie, depending upon whether the other bitmap showed 'occupied' or not.) I would expect that it might barely be possible to make everything fit, but RAM would be extremely tight since 96 bytes would be allocated to array structures before I even start counting up 'loose' variables. Coding for a SuperCharger would make things a LOT easier.
-
I'll have to see if I can dig out my code. What's the best development system to use these days? Also, I was thinking of doing a version of Mahki/Boxxi/Bubble Ducky/etc. using a 16x16 five-color grid. Colors could be nicer in an 8x16 grid, but I don't know if that would be as much fun. It is nice to see that the forum seems to be alive, though. >:*3
-
I just rediscovered my interest in 2600 programming after about a decade away from trying it, and am wondering whether I should finish the game I started (a "columns" clone) or do something else. I've got a nice six-column twenty-row gradient-shaded gems display (gem colors are packed two per byte with an odd interlacing scheme) so the game should look pretty good, but I haven't figured out the best way to detect three or more adjacent gems of the same color. Further, I'm not sure how much interest there would be in such a game. The other idea I had would be a 'worm' game for the SuperCharger. Doing a program for the 'straight' 2600 would be cooler than doing one for the SuperCharger, but even with the most efficient coding in the world the playfield would probably be limitted to a dimension of 32x16 and I don't know how playable the game would be at that size. One technique I would use with the 'worm' game that I haven't seen used elsewhere would be to 'venetian blind flicker' the playfield between two colors so as to allow a four-color playfield display (probably black/red/green/yellow). Using this approach would allow for a green worm, red mines, and yellow munchies, with flicker that would hopefully not be too bad. BTW, I know how Galaxian's seven sprites per row works, but does anyone know how Commie Mutants' score digits work? And how on earth did Warren Robinnet do his Basic Programming cartridge in 4K ROM with only 128 RAM (of which 64 are available to the programmer!?)
