Jump to content

EricBall

Members
  • Content Count

    2,362
  • Joined

  • Last visited

Posts posted by EricBall


  1. Surprise no one caught this - this is a series we ran a few years ago by someone who was actually in the arcade industry from the early 80's through to a few years ago.  He explains what happened from the coin-op company and vendor side (rather than the player side that everyone else is posting here about):

    Thanks for the pointer. Kevin does a decent job confirming much of what I mentioned, although he seems (almost foolishly) optimistic about a future rebirth.

     

    As far as I can determine, there has been very little change since his 2003 and previous articles. The development arm of the industry still hasn't figured out universal ways to make arcade games / machines which will bring in the players and allow the operators to make money. (There are special, specific cases like Golden Tee in bars, but that's not enough to support the whole industry.)

     

    And I'm not sure they ever will. Modern consoles are a far larger market (in potential unit sales) than even the most successful arcade game could ever hope to be. And they have huge standardization benefits (including development toolkits) along with top-notch CPU & GPU technology. For the player's view there's less & less reason to leave home, even to compete with other people.


  2. Note that Jink's digitized speech & music occurs only during the static title etc screens. This is because the game needs to update the TIA every line (15.7KHz sampling) for best quality, which make it basically impossible to do any useful CPU work.

     

    Digitized speech & sound are also pigs for ROM space. For pure PCM the TIA has a 4 bit volume register, so you're looking at almost 8Kbytes per second. It may be possible to compress that somewhat, though that will obviously increase code complexity and increase RAM usage.


  3. There's no one reason why far fewer arcades exist. Well, there is one reason - money - but there's a lot of reasons that arcades aren't as profitable as they once were.

     

    First, on the supply side

    1. It costs a lot to make a new arcade game. Higher quality graphics means higher costs for artwork. 3-D graphics means even more artwork, motion capture and higher code complexity to boot.

    2. Reduced demand means lower production runs which means one time costs per machine are higher.

    3. Custom hardware is stupidly expensive in development & production costs, so many games use the same hardware (Neo-Geo) or modified PC or console hardware.

    4. Higher costs means companies don't want to take as many risks, thus sequels and look-alike games are "safer".

    5. Realistic graphics can be restrictive because games get constrained by reality.

     

    Second, on the operator side:

    Higer percentage of games in unique, often oversize, cabinets. Although these games can increase traffic because they are unique, they are often higher cost and can't be converted to another game when they cease to be popular.

     

    Finally, the players:

    1. Arcades used to have better graphics and gameplay than computers and consoles; that's no longer the case.

    2. Cost of computers & consoles has gone down, while arcade cost has gone up.

    2. Fewer truely unique and interesting games. If you don't enjoy the established genres there is less reason to go to an arcade.

     

    I'm sure there's other reasons.


  4. Would you agree with my calculation that a 1K minigame entry should be 1008 bytes or less not counting headers (figuring eight bytes for the program header and 4x2 bytes for the block headers)?  I know makewav doesn't need the checksums, but the real tape format does.

    920938[/snapback]

    Any SC file will be 8448 bytes, whether it uses 1K or 6K. I don't think MakeWav is smart enough to handle files of other sizes.

     

    Hmm, on the other hand there's nothing that says you can't make a standard 1K bin which intentionally accesses $1FF8 to kick on write mode. MakeWav would load it as a standard <=4K cart. Probably wouldn't work on a CC/CC2 or in an emulator though.


  5. In part 1 I covered how to write to SuperCharger RAM and the Control Register ($1FF8/$FFF8). Now I will cover the SuperCharger header and file format.

     

    Actually, The SuperCharger doesn't really have a file format; instead it has a audio format. The file is just a standardized way of storing the data which is used to create the audio. This file is then used by a tool like MakeWav or WPlayBin to create the audio or by an emulator to execute the code.

     

    Supercharger 8448 bin format
    6114 bytes       24 pages each 256 bytes
    2048 bytes       padding (ROM pages)
      8 bytes        game header
                     - start address LSB
                     - start address MSB
                     - RAM config byte (saved in $80)
                       D7-D5 write pulse delay
                       D4-D2 bank config
                           000	3	ROM
                           001	1	ROM
                           010	3	1
                           011	1	3
                           100	3	ROM
                           101	2	ROM
                           110	3	2
                           111	2	3
                        D1 write enable (1 enable, 0 disable)
                        D0 ROM power (0 power on, 1 power off)
                      - page count (number of non-blank pages)
                      - checksum (sum of all 8 game header bytes = $55)
                      - multi load index number
                      - progress counter LSB (page count)*256/21 - (MSB-1)*256
                      - progress counter MSB (page count)/21 + 1
      8 bytes        padding
     24 bytes        page number table
                           page # * 4 + bank # - 1 (0<=page #<=7, 1<=bank #<=3)
      8 bytes        padding
     24 bytes        page checksum table
                           sum of bytes in page + page number value + page checksum = $55
    184 bytes        padding
    

     

    So, the first 6K of the file is the code & data for the game. This doesn't have to be in order because the header contains a page mapping table. So not only doesn't it have to be Bank 1, Bank 2, Bank 3, but you could have the odd numbered pages (e.g. $11xx, $13xx, $15xx; each page is 256 bytes) followed by the even numbered pages (e.g. $10xx, $12xx). Why would you want to do this? Putting the banks out of order may reduce the number of RORGs you have to do. (i.e. if you use bank layouts 2+3 and 1+3, you could lay out the file as Bank 2, Bank 3, Bank 1 so only Bank 1 needs RORGs.) Also, if you put any usused pages after the used pages then MakeWav etc will automatically skip those pages when creating the audio stream (smaller file, faster loads).

     

    After the 6K of game code & data is 2K of padding. What's this you ask? It's the SC address space reserved for the ROM. This is then followed by the header (maybe I should call it a footer, eh?). Assuming that you ORG'd your data & code at $1000, then this should be ORG'd at $3000. First in the header is the start address of your game, MSB first. This is easy, a simple DC.W Start_Label. Next is the Control Register setting you want your game to start with. (Just be careful that if you do start with write enabled that you don't have your Start_Label at $10xx since that would result in spurious writes!)

     

    Okay, the next byte is the number of non-blank pages you are loading. So for a 6K game this would be 24, for a 4K game it would be 16. This tells MakeWav et.al. both the number of pages to make into audio and the number of entries in the page number table.

     

    The next byte is a checksum. Ideally this should set so the sum of the first 8 bytes in the header is $55. However calculating checksums is a pain and MakeWav et.al. will do it automatically so just set to $55.

     

    The next byte is the multi load index. For single load games and the initial load for multiple load games this is zero. For multiload games this can be used to select which level to load. For multiload games this means rather than having to cue up the tape for a specific load, the user could just rewind and play the whole thing through and the SuperCharger would find the right level to load. Obviously with CDs and PCs this isn't as big an issue any more. One important note for multi-loaders: for some reason the SuperCharger clobbers the last page of Bank 1 as part of the load process, whether or not that page is loaded. So don't put anything there which you want to keep between loads.

     

    The next two bytes are used to control the speed of the load bars. Again, MakeWav et.al. will calculate this for you. This is then followed by 8 more bytes of padding.

     

    The next chunk is the important bit because it determines where the 6K of pages at the beginning of the file are stored in SuperCharger RAM. If you have 6K of code & data in bankwise order this shouldn't be too difficult. But if you are making use of the unused page feature or other re-ordering you will need to be careful when calculating these values. Note the ranges for page (0-7) and bank (1-3) and page is uses the most significant bits (e.g. The last page in the first bank is $1C and can be mapped to either $17xx or $1Fxx.)

     

    Finally there's another 8 bytes of padding, 24 bytes of checksums (again MakeWav will handle this so set to $55) and a final 184 bytes of padding.


  6. Not to say your source is wrong, but it seems to contradict what the CC2 documentation states.

     

    919585[/snapback]

    ;value from (hardcoded)
               CMP    RAM+VALUE_TO_STORE; preps the value for the write
               NOP
               CMP    DESTINATION_ADDRESS; does the write
    

    Yes, this makes sense.

    address 0 = read from $F080, load $80 into write register

    address 1 = read NOP

    address 2 = read CMP

    address 3 = read $00 (DESTINATION_ADDRESS LSB)

    address 4 = read $F1 (DESTINATION_ADDRESS MSB)

    address 5 = read from $F100, write $80 to $F100

    ;value comes from X
               LDX     #VALUE_TO_STORE
               CMP     RAM,X; preps the value for the write
               CMP    DESTINATION_ADDRESS; does the write
    
    ;value comes from Y
               LDY     #VALUE_TO_STORE
               CMP     RAM,Y; preps the value for the write
               CMP    DESTINATION_ADDRESS; does the write
    

    These don't make sense cause the DESTINATION_ADDRESS isn't accessed 5 address cycles after $F0xx. (Unless DESTINATION_ADDRESS is $1FF8 of course.) Remember it's not CPU cycles, but address cycles.


  7. Shouldn't that be

        CMP $1000,Y
       NOP
       CMP BASE,X

    to avoid bus contention on the SuperCharger write?

    Doh! Yes, you are correct. (I've editted my post to reflect.) Both CMP & LDA will work. (Although CMP doesn't overwrite a register, it doesn't preserve the Carry bit.)

    Would it be useful to mask address $80 with #$E0 at program startup and leave a $10 stored at address $81?  Then switch banks or modes with

        LDY #NEWMODE
       CMP ($80),Y

        CMP $FFF8

    Hmm, interesting idea. I don't know if it would be compatible with the SC multi load subroutine, though.

    Also, how often is it necessary to enable/disable writes?  Except when strapped for RAM, I'd think it simpler to simply avoid using $10xx.

    918884[/snapback]

    I think you mean strapped for ROM. You certainly could leave your program in write mode all the time as long as you leave $10xx empty, or use it as RAM (always writing back after each access to a dummy location).


  8. Hopefully this will help those people interested in creating a SuperCharger homebrew for Glenn's contest. Part 2 will be about the SC header (but first I have to re-learn it myself.)

     

    The SuperCharger contains 6K of RAM organized as three 2K banks. These three banks (and the 2K internal ROM) can be mapped in various combinations into the 4K cartridge address space ($1000-$1FF8) via the SuperCharger control register. (Note: Since the 6507 inside the 2600 only has 12 address lines, $1000 is equivalent to $F000.)

     

    The SuperCharger control register also controls whether write mode is enabled. Once write mode is enabled, any RAM mapped to the the cartridge address space may be written to. Unfortunately, since the 2600 cartridge slot doesn't have the necessary control signals to allow direct writes (e.g. STA) to work, writes to the SuperCharger RAM require multiple reads to implement a write. First the program generates an access to address $10xx to select the value to write. This value is then written to the fifth address bus value after the $10xx access. For example

    CMP	$1000
    CMP	(PTR), Y
    

    stores $00 in the address pointed to by (PTR),Y

    CMP	$1000,Y
    NOP
    CMP	BASE,X
    

    stores the value in Y into the address BASE+X (i.e. POKE BASE+X,Y), the NOP is to generate an additional address cycle. It's very important not to store code or data which will be accessed while write mode is enabled at $10xx, since it will generate spurrious writes.

     

    The SuperCharger control register ($1FF8 aka $FFF8) is written to in the same way as SuperCharger RAM with some exceptions. First, write mode doesn't have to be enabled. Second, there is no restriction on the number of cycles between the $10xx access and the $1FF8 access; so any access to $1FF8 will trigger a control register update! (Hence why certain 2K/4K games are not compatible with an unmodified SuperCharger.) Third, the top three bits of the control register should not be changed, so a copy of the register is saved in normal RAM at $80.

     

    Control register format: dddbbbwr where

    ddd = write pulse delay (determined by internal ROM)

    bbb = bank mode

    w = 1 = write enable

    r = 1 = ROM powerdown

    bbb	$1000-$17FF	$1800-$1FFF
    000	bank 3    ROM
    001	bank 1    ROM
    010	bank 3    bank 1
    011	bank 1    bank 3
    100	bank 3    ROM
    101	bank 2  ROM
    110	bank 3    bank 2
    111	bank 2    bank 3
    

    (Note: there are some combinations missing.  In particular, bank 1 and bank 2 never appear together.)

    LDA	$80  ; load saved control register 
    AND	#%11100000; save write pulse delay
    OR	#%000bbbwr; set bank mode, write enable & ROM powerdown
    STA	$80  ; save control register
    TAX
    LDA	$1000,X  ; set write register
    LDA	$1FF8  ; set control register
    

    Bankswitching occurs immediately, so unless you enjoy suffering, I'd recommend only changing one bank at a time. (And use the same location for each bank.)

     

    Just like programming any other bankswitching game, you will need to use RORG to tell DASM what the actual memory location each bank is mapped to, and ORG to order the banks in the file. Note: the SC header allows for pages to be loaded out of order, so there is no requirement for the source to be in BANK 1,2,3 order.


  9. Just to announce that Glenn's extremely generous prize has guilted me into restarting my long dormant Lode Runner-esque game for the SuperCharger. I only hope that other VCS programmers will take up the challenge and put mine entry to shame.

     

    In the interests of open-source development, I will document my progress (along with source code) in my AA Blog. I will also gladly answer any comments posted to my blog.

     

    For those programmers interested in SuperCharger programming, I would encourage you to see the Cuttle Cart manual starting on page 15.


  10. I'm surprised no one's attempted PF2 given that a special banking for megaboy was successfully written for the CC2.

    908795[/snapback]

    Pitfall II is much more than bankswitching. There's a heck of a lot of logic on the board assisting with vertical sprite positioning & lookups along with 3 voice PCM music.

     

    The DPC chip used in the Atari 2600 version of Pitfall II: Lost Caverns is NOT a POKEY, nor is there one to be found anywhere in the cartridge. The DPC was invented and designed by David Crane (DPC are his initials), and he holds a U.S. Patent for the device.

     

    Patent #4,644,495

     

    The above link takes you to somes pretty difficult reading, unless you happen to work with patents every day.  Basically, the patent description for Crane's chip describes 20 unique claims for his invention.  Claims 11,12,18 and 19 pertain most directly to its sound generation capabilities.  But it's all rather fascinating and definitely worth a look if you're curious.

    222946[/snapback]

    The patent is very interesting reading (and not that tough if you have a decent familarity with the 2600 and basic electronics). It's evident that the DPC was envisioned to be used for more than Pitfall II. Note: the patent expired in 2001, so you could legally reuse / reproduce the DPC design (although the data might still be subject to copyright).


  11. Yes, it's very possible. See http://www.freelists.org/archives/atari7800/02-2005/ for the message thread in the Atari 7800 mailing list. (Unfortunately, the attachments aren't archived, so I've attached it.)

     

    There are two ways to read the paddles. The first (attached) is to use a "pseudo kernel" which polls the paddle bits once per line. This gives high resolution, but means only VBLANK is available for normal CPU processing. The second (see my AA blog) is to poll every N lines using a DLI. This means normal CPU processing can happen during the active display, but significantly reduces the number of paddle values (e.g 0-31).

    paddle78.zip


  12. If a lemmings are 16 pixels high by a max of 5 pixels wide, the above code would be run twice to plot each lemming.  The loop takes 7+6+6+7+5+2+3 (23) cycles per iteration, so with the surrounding overhead that would be about 800 cycles per lemming.  Pretty efficient as such code goes, though not really good enough to draw 99 lemmings at a good frame rate.

    894067[/snapback]

    Consider that my Ball Demo requires 224 cycles, or two scanlines, to add to the display list.


  13. I guess, then, I should learn to program so that a Star Castle port can be made...

     

    (I stink at that game, but it is fun.)

     

    I didn't think about it at first, but yeah, moving the rings and cannon plus keeping the buzzards going full speed would be a little hardware intense.

    Then you have to add in the color--Star Castle used a monochrome display with colored overlays.

     

    Could the 7800 do vector style graphics or would we need to try something else?

    893445[/snapback]

    Not vector graphics per-se, but if the graphics can be broken down into sprites (small rectangular bitmaps) then the 7800 has a chance.

     

    For Star Castle the biggest problem would be the rings, especially the way they grow when a full ring is eliminated. The rest of the objects could be created as pre-defined sprites. (Like I did for SpaceWar! 7800.)


  14. Here's an interesting idea - separate CPU and MARIA banks, selected by the HALT line.  Or 32K of RAM as two 16K banks selected by HALT XOR a CPU settable flag for implementing seamless double buffering of a bitmapped display.
    That sounds rather clever.  Why don't you try it out?  :-)  Anyhow, if you have enough graphics to use up a whole 16K of RAM, you probably won't have enough CPU time to fill the buffers.  And double buffering still won't help your frame rate if it takes 1/20 sec or more to redraw a new buffer.  With less graphics, you should be able to just maintain two separate DLLs and switch between them during retrace by simply updating DPPH and DPPL.  And if you really think that you need two 16K screens, it would probably be a good idea to try a 32K flat RAM mode first.

    It's something which occurred to me over on the Lemmings! 7800 thread. The double buffering is just so the CPU can update the bitmap without corrupting the active display. I agree that the amount of CPU time will be very small, which will probably mean a low frame rate to boot.

     

    The only way you can make sure a hardware project like that gets done is to do it yourself.  That's why I started this whole thread in the first place: There are no boards for 7800 homebrews yet, and I wanted to see a board that was as flexible and simple as possible.

    892434[/snapback]

    Hmm, I think I've heard something like that before. Ahh, right, it was me responding to request for arcade-perfect ports to the 7800.

     

    Sorry, folks, not me.  I don't have the time to research completely new and radical ideas like that.  My goal was a board that could run as many released games as possible, plus a few obvious extentions like more bank address lines.  I didn't expect to find such an easy hack to implement low-mode with one extra GAL output, but I'm glad I did, as it seems like a really useful memory layout.

    892416[/snapback]

    Hmm, I didn't realize that was your original goal, although it seems that you have accomplished it. I thought you were trying to come up with a cheap & simple way to create >32K 7800 homebrews.


  15. You got it.  Sound like a workable approach for the 7800?  It shouldn't take too many CPU cycles to update those five character map entries, meaning that the game would play just fine even with MARIA stealing 90% of the CPU cycles.

     

    BTW, do you like the idea of doing Wormy as I've suggested?  Do you agree with my judgement that tiles would be the way to go?

    Yes, very do-able on the 7800. Keeping the character map will probably make porting the code fairly easy; maybe even easier since you can lose the character graphics update code.

     

    Any way to make the rows be 128 bytes instead of 256?

    Nope. You're constrained by CHARBASE. This does mean you can use $C000-$FF7F for the graphics since it won't overlap the digital signature at $FF80-$FFF9. And I'm sure you will find some use for 63 chunks of 128 bytes (assuming that you use all 64 characters).

     

    ... Xilinx 95C36 ... How does that sound for an idea?

    891913[/snapback]

    You lost me there. But custom HW probably should be avoided; just too expensive. It will also make coding and testing tough.

     

    FYI I've got a framework ASM about half done for Wormy 7800. Need to cut & paste the startup code and a placeholder mainline. I'll try to get it done & posted this weekend.


  16. Oh, one major problem with going the bitmapped screen route (versus bitmapped background + sprites) is you then would be restricted to 4 colors total instead of 4 colors for the background and 8 palettes of 3 colors for the sprites.

     

    Although I suppose for the bitmapped screen you could use 160B and get 13 colors per pixel (4 palettes of 3 colors + background). However, that would require twice as much RAM (you could just squeeze 200 lines into 16K RAM) and twice as much DMA time. (Again leaving the CPU with 2500 cycles per frame to update the bitmapped screen.)

     

    Hmm, there is a cartridge signal for when the system is doing DMA. I wonder if that could be used to implement transparent double buffering. Or it could be used to have separate CPU and MARIA ROMs. Interesting idea....

×
×
  • Create New...