Jump to content
IGNORED

Super Mario Bros. on Atari 8bit?


analmux

Recommended Posts

Hi,

 

As some might have noticed, I tried the reverse engineered source code (by doppelganger) of the Nintendo 8bit game "Super Mario Bros.", and I tried to reassemble it on A8. I tested whether it's indeed the correct source code, and it is. Before downloading the source I already started analyzing the ROM image using DIS6502. I encountered a small problem, which is centered around the so called 'Jump Engine', as used in other NES titles (f.e. SMB3 also uses this jump engine). The Jump Engine is a "jsr JumpEngine" instruction, followed by an unspecified number of dbytes. Load accumulator, and it's kind of an ON .. GOTO ... statement in assembly. Another problem is all kinds of conditional jumps & branches. DIS6502 doesn't seem to recognize them all. So I wrote a programm which finds all branch points. The result exactly matches the assembly structure I downloaded two days later.

 

As now source is available it can be reassembled to work on A8. I had some problems around interrupt addresses and other stuff, as the IO chips on NES are of course different. Anyway, the interrupt features aren't that hard, as (talking about NMI) we have only vblank on NES (not even raster interrupts or DLI).

 

So I compiled an executable .atr file. My latest try can be downloaded here: http://www.phys.uu.nl/~bpos/1/2.atr

 

More explanation of this tryout can be found in this thread: http://www.atariage.com/forums/topic/150705-whats-this/

 

Of course we don't have the NES sprites on A8, and the whole gfx system works very differently.

 

 

Starting from this point, I'm wondering if at least a nice port would be possible.

We already have all the game logic, which seems to work OK on A8, but we're missing the sprites and the graphics.

 

I was afraid there would be a complicated collision feature in the hardware, but in the contrary: The collision checks are all done by software, i.e. comparing coordinate values and such.

 

I've noticed that in the source code a section is titled "Sprite Shuffler", which shuffles a lot of data on page 2. This would of course not be needed, as probably we'd need softwaresprites anyway, so we can cut out that part. I think this part takes a lot of CPU time.

 

If I'm correct the NES cpu also runs at 1.79mhz, with only one difference: It isn't bothered by the Video Chip DMA, as it has a separate bus. So it runs at full 1.79mhz speed. But, maybe some routines can be removed or restructured. Talking about software sprites. Most enemies are 'walking' 1 pixel per frame. This would of course only be possible in hires on A8, but I'm more thinking of using Antic 4 instead. So maybe we'd need only processing of the swsprites at the even frames...etc.

 

However, to get a picture of CPU usage, I patched the nes rom image to have some kind of rasterbar CPU time meter. During the game some 'peaks' use nearly all onscreen CPU time. Apparently the logic behind all the enemies is still complex enough to speed it down.

 

I think a lot of routines could be optimized, at least when doing everything the 'atari way'. I think at the time the first SMB came on the market, they were more interested in making the code fit into 32kb instead of trying to optimize it w.r.t. cpu usage.

 

etc.etc.

 

But last days I've been thinking of possibilities of porting, and I'm interested in others' views.

  • Like 2
Link to comment
Share on other sites

If you are able to optimise the routines to be as tight as required for the implementation of the soft sprites and other overheads then absolutely go for it. To succesfully port the biggest selling game of all time from the original code would be an excellent achievement.

Link to comment
Share on other sites

If you are able to optimise the routines to be as tight as required for the implementation of the soft sprites and other overheads then absolutely go for it. To succesfully port the biggest selling game of all time from the original code would be an excellent achievement.

 

Well, first of all, it seems the original code, when running on NES, also wastes a lot of cpu time, as after reset init, it activates an NMI (vblank interrupt in this case), and jumps to an endless loop. Most of the time more than 50% of time the NES cpu is waiting. Only some peaks of activity there, when f.e. scrolling, or when more enemies enter the screen.

 

On atari, maybe a solution would be to precompute prerolled data for the software sprites in the meantime, instead of waiting.

Link to comment
Share on other sites

If you are able to optimise the routines to be as tight as required for the implementation of the soft sprites and other overheads then absolutely go for it. To succesfully port the biggest selling game of all time from the original code would be an excellent achievement.

 

Well, first of all, it seems the original code, when running on NES, also wastes a lot of cpu time, as after reset init, it activates an NMI (vblank interrupt in this case), and jumps to an endless loop. Most of the time more than 50% of time the NES cpu is waiting. Only some peaks of activity there, when f.e. scrolling, or when more enemies enter the screen.

 

On atari, maybe a solution would be to precompute prerolled data for the software sprites in the meantime, instead of waiting.

Link to comment
Share on other sites

Go for it :) Personally I'm more in the Allas camp but that's me, I like to do things all myself from scratch, that's how I've learned to do everything. Saying that, there's a hell of a lot to learn from going through what I'd hope is a quality coded game and as you say, all the logic etc is already done. Just need to strip that out from any machine specific stuff add, screen handling code etc (music it seems you're already on the case) and presto :)

 

 

Pete

Link to comment
Share on other sites

Go for it :) Personally I'm more in the Allas camp but that's me, I like to do things all myself from scratch, that's how I've learned to do everything. Saying that, there's a hell of a lot to learn from going through what I'd hope is a quality coded game and as you say, all the logic etc is already done. Just need to strip that out from any machine specific stuff add, screen handling code etc (music it seems you're already on the case) and presto :)

 

It'd be more fun to write from scratch, but it'd be cool to see this on the A8 no matter what.. You should be at an advantage, after all the NES can only write to the PPU during VBLANK so you should gain a fair chunk of time in the screen access department since it's pretty piss poor at accessing it's memory.. Mind you I don't know how much access is performed in Mario, in fact thinking about it, probably not that much in reality but all of that can go.. I don't know exactly which MMC it used, but since it's such an early game fingers crossed it's MMC1 where the memory controllers input was serial, so lots of bit bashing that wouldn't be needed :)

 

edit: Just checked and found it was one of the last game to not use an MMC, and had no idea the game fitted into the 40K limit before you need a mapper..

Edited by andym00
Link to comment
Share on other sites

...I don't know exactly which MMC it used, but since it's such an early game fingers crossed it's MMC1 where the memory controllers input was serial, so lots of bit bashing that wouldn't be needed :)...

Indeed, it doesn't directly write to the screen area (4 * 1kb chunks at $2000-$2fff). It uses a buffer somewhere in the $03xx area to stuff data by hand through one of the PPU data ports instead.

 

So, the really nice thing is that it only needs $0000-$07ff of workspace, and the accesses to $2000-$2007 and $4000-$4015 can be remapped to another part of RAM, or just totally disabled. Then we'd have 28kb left for the gfx data and preroll buffers / swsprite engines etc.

 

 

(edit)

 

I'm quite surprised how they handled the sprites, the screen RAM and others. But, also remember, the first release of this game was already in 1985, only 3 years after C64 ;)

 

F.e. I know there are really 64 hardware sprites on NES, but only 8 can pull DMA per scanline. I suppose it looks at priority, which sprites to draw first. This means, the first sprite in the table ($0200-$02ff) will be drawn first, if already 8 sprites were drawn, it stops handling them. However, to write a good sprite multiplexer, a sprite shuffler is also needed, but the hardware does NOT support that. This must be done by software.

Edited by analmux
Link to comment
Share on other sites

F.e. I know there are really 64 hardware sprites on NES, but only 8 can pull DMA per scanline. I suppose it looks at priority, which sprites to draw first. This means, the first sprite in the table ($0200-$02ff) will be drawn first, if already 8 sprites were drawn, it stops handling them. However, to write a good sprite multiplexer, a sprite shuffler is also needed, but the hardware does NOT support that. This must be done by software.

 

I can't help with NES sprite flickering and how NES programmers deal with that, but I can tell you on MSX (even though the video chip tells you a sprite wasn't displayed) all that happens when a flicker required situation is needed is the sprite attributes are simply shuffled around.. Move sprite 0>1, 31>0, 30>31 and so on.. That's all they do.. And it works quite well.. Take a look at the Konami games like GradiusII on the MSX for a good examples of this working out really well..

There's more complicated ways, but that's nice and simple for starters :)

 

Most of the NES flicker handlers are plain ugly in comparison to the MSX stuff for some reason I've never really understoof.. GradiusII on the NES is a great example of how bad it can be.. I don't get why it's so bad, but somehow Konami ballsed it up on the crystal level totally, whereas on the MSX it runs so much nicer..

 

In the Multiplexer thread I also posted my way of dealing with them using a ninth bit which is a displayed flag, which is eor'd when drawn/assigned which next time moves the sprite naturally down the sort order.. I know you don't need to sort but it's just an example of one (very neat) way of solving the flickering, well my favourite anyway ;)

 

BUt if you're going to use players for the sprites then you'll probably be sorting, so that system just falls out if you can manage a 9bit sort.. Either 2 pass radix (4&5bit) or a normal 8bit sort with say half vertical resolution..

 

And sorting 32 sprites on the A8 CPU should take you like ~8 scanlines or so (114 cycle lines)..

In fact, the Ocean Sort would be better than a full radix since the sprite Ys are fairly constant with very little changing (yposition) per frame..

Edited by andym00
Link to comment
Share on other sites

Can you use Antic 4 with a multicolor player/missile multiplexer? I have successfully got 16 mono-colored 8 pixel wide sprites and seen samples of 25 multicolored sprites. Even a multicolor multiplexer that combines the players+missiles to get several 10 pixel wide sprites works faster than soft sprites. I am developing one to work with Antic 4 scrolling screen with DLI background color changes, but only uses the players only (8w). All this depends on how many sprites we need to generate on the screen at once, largest height size, etc.

Link to comment
Share on other sites

...all that happens when a flicker required situation is needed is the sprite attributes are simply shuffled around.. Move sprite 0>1, 31>0, 30>31 and so on.. That's all they do.. And it works quite well..

Even if the result may not be better, the NES shuffler seems somewhat more complex.

 

Anyway, I'm not thinking of rewriting all this sprite shuffle or multiplex crap, but starting from scratch with some software sprite routines.

 

 

 

Can you use Antic 4 with a multicolor player/missile multiplexer? I have successfully got 16 mono-colored 8 pixel wide sprites and seen samples of 25 multicolored sprites. Even a multicolor multiplexer that combines the players+missiles to get several 10 pixel wide sprites works faster than soft sprites. I am developing one to work with Antic 4 scrolling screen with DLI background color changes, but only uses the players only (8w). All this depends on how many sprites we need to generate on the screen at once, largest height size, etc.

The plan is indeed antic 4, but I'd like to have the program looking like original as much as possible. Many times we need 4 multicolour sprites (of 8 pixel width) per scanline. Then Atari PMs are out of the question.

 

I'm thinking about software sprites anyway. Would be nice to do only Mario with a hardware sprite (PM0&1), and have 2 players + some missiles left for underlays. Or maybe all PM used for underlays.

 

You're right, a full swsprite engine would consume much CPU time. But, as we're looking at charmode antic 4, I'm seriously thinking of handling at least the enemy sprites by charclusters with precomputed data anyway. Then putting one "goomba" on screen is just a matter of changing 4 (or 6) values in screen memory. The only thing needed would be a nice 'mapper' programm running in the background, which knows which sprite data is needed at which moments. Then this mapper could 'look ahead' f.e. 16 frames, and use all time (normally wasted anyway) to precompute the stuff.....but all this is still theory.

Link to comment
Share on other sites

Even if the result may not be better, the NES shuffler seems somewhat more complex.

 

Anyway, I'm not thinking of rewriting all this sprite shuffle or multiplex crap, but starting from scratch with some software sprite routines.

 

I only mentioned that because you brought up the subject of sprite shuffling, and I wanted to make it clear that's not required unless you're called Mr.Nes or Ms.MSX ;) And since you're going for software sprites, it's even less required..

 

It's an interesting subject of which Konami and Capcom both have different solutions.. Capcom (mostly) alternate the drawing order each frame, giving a constant flicker (0>63, 63>0).. Konami usually either use the round-robin shuffle, *or* place each sprite 17 (or 9) from the last one instead of one, giving a more random appearance to the flicker result.. Anyway, it's not important :)

Edited by andym00
Link to comment
Share on other sites

Can you use Antic 4 with a multicolor player/missile multiplexer? I have successfully got 16 mono-colored 8 pixel wide sprites and seen samples of 25 multicolored sprites. Even a multicolor multiplexer that combines the players+missiles to get several 10 pixel wide sprites works faster than soft sprites. I am developing one to work with Antic 4 scrolling screen with DLI background color changes, but only uses the players only (8w). All this depends on how many sprites we need to generate on the screen at once, largest height size, etc.

 

 

noooo... You have to use the 5th color... and use the the PMs as overlays/underlays... ;)

Link to comment
Share on other sites

OK, update:

 

http://www.phys.uu.nl/~bpos/1/3.atr

 

This time it's a more serious update.

-We don't need to do monitor stuff anymore

-We don't need to do special joystick key redefinitions

-We can actually SEE what we're doing now

 

I activated some sprites: Just dark grey vertical bands for now, but we have an idea what's going on now.

 

The screen is setup by looking at the two screen buffers. The display list shows:

-1 bar of graphics 0 (for some value testing)

-13 bars of graphics 1 (screen buffer 1 = upper buffer)

-13 bars of graphics 1 (screen buffer 2 = lower buffer)

 

Mario always starts in the upper buffer, and when leaving the upper screen on the right, it comes back in the left part of the lower screen. Leaving the lower screen again on the right, it'll be back on the left border of the upper screen. So, to play it without getting lost, keep track of which screen you're playing on. No doubt, when building a simple scrolling engine around it, it will look like the real game.

 

Also beware of the enemies: In the real game they'll enter the screen at right sideborder, but you'll see them already moving, when they are still one screen way from mario. When Mario is in upper screen, the entering enemy is moving in the lower screen (& v.v.), and the enemy can also cross border going from screen 1 to 2 (& v.v.).

 

 

Just plug in normal stick in port 0:

Up = jump

Left = walk left

Right = walk right

Down = duck / enter pipe

Fire = shoot fireball (when Mario picked a flower powerup)

Start = start (like on NES joypad)

 

About the music: I'm only interested in porting the music / sfw when gameplay is worked out.

When coldbooted the music won't sound as it should. Press start 3 times, then music starts to play, but very slowly. Then after dying 1 time, the music plays at normal speed.

 

 

On wishlist / to do list: Remove sprite bars, when enemy is already dead.

 

EDIT: Now we can play it on real atari!!!

Edited by analmux
  • Like 1
Link to comment
Share on other sites

It's quite amazing actually. Although I can't get very far. I was able to get the first mushroom and break some bricks, kill enemies, and get through about 5 or 6 screens.

 

Very awesome if you could actually pull something like this off. I guess it's one of the holy grails for the A8.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   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...