Jump to content
  • entries
    62
  • comments
    464
  • views
    85,349

7800 thoughts

Sign in to follow this  
supercat

720 views

Well, I just started playing with 7800 programming and it seems somewhat interesting. Haven't really figured out what to do, though. I've been thinking it might be interesting to see if I can manage a missile defense or area-filling game using only the 4K of internal RAM. The location of the zero-page and stack shadows is nuisancesome, but I have a kernel that seems like it should work for 128x96x4 colors with some cycles left over for a few overlay objects. The bitmap is stored linearly at 32 bytes/row, except for an annoying gap at $2000 to allow for the zero-page and stack shadow areas.

 

I was also thinking that if I can manage to do some CPLD design it might be interesting to try to push the 7800 to its limits like I did for 4A50. Probably should invest more time and effort in 4A50 first, but I would think that with the right hardware the 7800 might be able to do a pretty decent rendition of a color vector graphics game.

 

The first key, if possible, would be to use the HALT signal to distinguish CPU cycles from MARIA cycles. 16K of the Maria address space would fetch data from one of four 16K banks; another 16K would access a different one of four 16K banks but assert R/W and drive the data bus low. This would provide a fast means of clearing display memory.

 

For graphics plotting, I'd tweak things a little bit beyond my 4A50 design. If $1000-$17FF is open, I'd set things up to allow pixel plotting via something like:

 cmp $1000,x; X=x coordinate of pixel
 cmp $16FF,y; Y=y coordinate of pixel

The $10xx read would latch bits 3-7 of the address and data bits 0-7 (controlling what's plotted). The $16xx read would fetch data from an address formed by munging the bits 3-7 latched above along with some other address registers and the 8 LSBs of the specified address and then latch data bits 0-7 into a second register. The $17xx read would use the same address as the $16xx read, but perform a write there with the masked contents of the first two reads and a "color" register.

 

Combining these techniques, I think a color vector game in the style of Tempest could probably run at 20fps in NTSC--possibly even 30--even using a 256x192x4 bitmap screen.

Sign in to follow this  


10 Comments


Recommended Comments

Hmm... If there's one thing I've learned about the 7800 is it is CPU limitted. At least with a virtual bitmap you're not having to contantly rebuilt the display lists. The DMA cycle stealing should also be a little easier to predict.

 

Note: there's no 2LK for the 7800, so you're limitting yourself to the only half of the screen height with 128x96.

Share this comment


Link to comment
Note: there's no 2LK for the 7800, so you're limitting yourself to the only half of the screen height with 128x96.

 

My code shows each scan line of the bitmap twice. It requires servicing the display every scan line, but it's no worse than anything on the 2600 in that regard. It only uses one display list, and each item in the display list list is 16 lines high.

Share this comment


Link to comment

Hmm... If there's one thing I've learned about the 7800 is it is CPU limitted. At least with a virtual bitmap you're not having to contantly rebuilt the display lists. The DMA cycle stealing should also be a little easier to predict.

 

Note: there's no 2LK for the 7800, so you're limitting yourself to the only half of the screen height with 128x96.

 

I was considering starting on a project where I was going to have a bitmapped display with double height lines (kinda like graphics 7 (antic D?) on 8 bits). It would require a display list list entry for every two scan lines though.

Share this comment


Link to comment

I was considering starting on a project where I was going to have a bitmapped display with double height lines (kinda like graphics 7 (antic D?) on 8 bits). It would require a display list list entry for every two scan lines though.

 

The approach I use requires one DLL entry every 16 lines, which is the absolute minimum required for even the feeblest screen display. Everything else is done by manipulating things during display drawing. Unfortunately, I can't figure out how to make the code compatible with both the Prosystem emulator and the real hardware except by doing a really gross cheat (which would probably fail if the emulator was made somewhat more compatible).

Share this comment


Link to comment

Have you tested your pseudo kernel out on actual hardware? Are you updating the display list entry or the DLL entry? How do you sync with MARIA? (Since you're probably using more than 7 CPU cycles per line.)

Share this comment


Link to comment
Have you tested your pseudo kernel out on actual hardware? Are you updating the display list entry or the DLL entry? How do you sync with MARIA? (Since you're probably using more than 7 CPU cycles per line.)

 

It updates the display list itself. I've tried things two ways: preload A and X and then store them within the first six cycles after a WSYNC, or else do a WSYNC and then wait at least 7 cycles before doing the stores. Either way works with real hardware, though the code has to be run a line sooner when using the latter approach (naturally). In both cases, the real hardware requires one less WSYNC between my DLI and the start of the loop than does the ProSystem emulator.

 

BTW, I'm also planning to test whether a Toyshop Trouble kernel could work well on the 7800 using 320 mode. The plan would be have each of the three toys be a solid color and use register-bashing to color-stripe them. The colors of the second and third toys would be set within the first six cycles after WSYNC; the color of the first toy would be set later in the scan line (after the beam was past it). The elf would be draw with 160-dot resolution and four colors plus transparent (no need to color-stripe him). DMA requirements should be quite reasonable (three toys @ 3.5 cycles, plus the elf at 5 cycles, plus two ends of the conveyor--probably 2.75 or 3.5 cycles), but the 320-dot mode should improve some of the toys compared with the 2600's 160-dot mode. Not sure it would be worth the effort to code the game for the five or six people who might actually play it, but it would be interesting from a technical perspective.

Share this comment


Link to comment

Have you tested your pseudo kernel out on actual hardware? Are you updating the display list entry or the DLL entry? How do you sync with MARIA? (Since you're probably using more than 7 CPU cycles per line.)

 

I posted the test code up above. Push the joystick left or right to shift the routine's execution down by one or two lines. You'll see that the real machine's code execution is off a line compared with the emulation.

Share this comment


Link to comment

Ahh, WSYNC + 7 would logically put you at the end of the DMA for the line. Then update the display list entries to fiddle the start address. Neat. And safe with a fixed display list since you can determine the number of cycles you have.

 

Oh... do you use the same display list for _every_ visible display? That would be even more cool. (And makes the ZP/SP hole even more annoying I imagine.)

 

I suspect the emulators don't handle DMA cycle stealing so that's why there's a difference. From the emulator perspective, it's only counting WSYNCs.

Share this comment


Link to comment
Oh... do you use the same display list for _every_ visible display? That would be even more cool. (And makes the ZP/SP hole even more annoying I imagine.)

 

That's the idea, precisely. Though things like score, etc. could be handled using a different display list (character mode, etc.) if desired.

 

I suspect the emulators don't handle DMA cycle stealing so that's why there's a difference. From the emulator perspective, it's only counting WSYNCs.

 

The funny thing is that there's a one-line difference between the real thing and emulation whether I put the pointer updates at the start of the line or seven cycles into it. Since ProSystem is fairly new, and it's the only emulator I've tried, my guess would be that its DMA calculations are off by a line, though I'll have to play with things to see if that's what's going on. From my understanding, a change to a palette register should affect things immediately; a change to the display list that occurs within the first seven cycles won't affect the current line but instead the one after; a change after the seventh cycle won't take effect until two lines below the current line. My guess is that existing games haven't used that level of display-list bashing for some reason, though I don't know why not (it should allow for some really nice tricks).

 

BTW, have you checked out my Wormy demo yet (7800 prog forum)

Share this comment


Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...