Editing Marble Madness

By George Prout [Updated 18th Feb 2003]

Email: (my full name without the space) @ hotmail dot com

[that's to stop spam crawlers picking my address up]

I will no longer update this file - go to georgeprout.blogspot.com

This page contains information for customising the classic arcade game Marble Madness,


This site is boring to look at - it doesn't have flash movies, graphics (or adverts – except what the host might have added) or any of that “Web Spam” clutter that is choking connections. So it loads nice and fast. And it's easy to print out and refer to. I'd have a bouncing ball on the screen, but I've better things to do with my time, like getting on with hex editing the game!


......


My original idea was to create a stand-alone editor for the levels in Atari's 1984 classic, Marble Madness. Who knows, the idea might still come to light, but there are a number of problems standing between where I am now, and even producing a single line of code.


On this site I will document some of what I have found so far... maybe no-one will ever read it, but quite possibly, someone will also think it could be a fun idea and take the project further?

If you do, please let me know anything you find, I can then update this page – kind of like an open-source community, sharing the information we discover?


There are some interesting 'hacks' that can be added to the game, should you wish, these are documented below. I have coded a patch program that I'll happily share if you want. It's not online at present, but it makes editing some of the options below easy. It also lets you disable 'baddies' on each level – I use this to get around the maze easier when decoding.


My target, Marble Madness, running on the MAME emulator was chosen as it was always my favourite arcade coin-op. For more information about the game, see the following links.


Bernhard Kirsch

James Watts


documented rom dumps link



You'll probably want to download and look at these files – they contain a LOT more information than I'm prepared to write out again! Consider this page as the 'teaser' and the zip file as the real document. Put it another way, I'm updating the zip a lot more often (well, pretty much constantly!) and it contains my notes to date (when I get around to uploading new versions that is)



Firstly, the game runs on Atari's System 1 hardware. This means that we are dealing with a 68010 processor, with copy protection in the form of 'slapstic' protected ROM areas.



Memory

ROM file

Notes

 

Odd

Even

 

0x00000 - 0x07FFF

136032-205

136032-206

Fitted to main board

0x10000 - 0x17FFF

136033-623

136033-624



Program code
and data

0x18000 - 0x1FFFF

136033-625

136033-626

0x20000 - 0x27FFF

136033-627

136033-628

0x28000 - 0x2FFFF

136033-229

136033-630

0x80000 - 0x87FFF

136033-107

136033-108

Slapstic protected


These are the ROMs that we are interested in. Note that there are at least 4 versions, so the ROM files may be different on your board. This is for SET 1, I've not looked at the other versions (yet).

The other ROMs contain the graphics and sound. There may be a graphics page added at some later date with the font/tile details, but they're quite easy to work out anyway! ;-)


The system 1 main board contains some 'standard' code – you'll note that the first 0x8000 of memory is fitted to the board and therefore common to all System 1 games. In other words, we won't find our marble madness mazes stored in there! (or will we?!)


The last memory area shown here, 0x80000 onwards is the slapstic block. I will assume that you understand how addressing works, so I'll only give a brief explanation of what makes this special. The slapstic protection chip controls the top two address lines, namely A12 and A13. The schematic diagrams are on the web, do a google for them and you'll also get the full memory map - I'm a hardware engineer, so this means a lot more to me than a screen full of disassembly!


So what does this mean? Well, put simply, if we access address 0x80084, we can't be sure if the slapstic will 'divert' us to addresses 0x83084, 0x85084 or 0x87084 instead. The C source for MAME contains more information, I'd write something here if I really understood it. Whilst on the subject of MAME, get the source code and the MinGW (for win systems) – it's very easy to compile, you just need these two files and the main MAME site explains how to do it. Warning, on this machine, it took 1½ hours to do a full initial build, but when I make some small changes, it only takes about 3 minutes now. Do it – you need to use the debugger! Run mamed (the d on the end means debug version) with the -cheat option so you can set a watchpoint, I'd go for 0x87F10, and you'll see that this ROM (i.e. READ ONLY) data is changing from 01, E2, 04, 08 at various times. That's the slapstic in action!


It would appear that there are just two routines that cause a slapstic change. These are called at various times when loading a level, and are found at 2FFD4 and 2BCBE. Note that the debug build of mame allows you to set a data watchpoint on the ROM – so you can catch the slapstic changes.


There are a number of small problems (irritations at this stage) that we need to look at before we go too far...


Protection protection protection...

NOTE WE ARE NOT GOING TO REMOVE OR DEACTIVATE THE PROTECTION – JUST REMOVE THE CRC CHECKING SO OUR CUSTOMISED VERSION WILL RUN.


MAME checks the CRCs of the ROMs when loading, and reports any that are 'corrupt'. Fine, except ours will always be corrupt because we've edited some code! We have the MAME source, we can recompile our own version (remember, don't distribute mame binaries!) and this is no longer a problem. If you don't compile, you only have to press a key to acknowledge that the ROMs have a problem anyway!


A bigger problem is that Marble Madness also checks the ROMs when it starts. Normally, when the game reports a problem, it will just wait for the 'player 1 start' button and then continue as normal... but not always!


Our first hex edit will be this test code. We will disable the slapstic test, as this tended to lock the machine up frequently for me. The bytes stored at 10054 are compared to 4E and F9, if they are, then this address is called – which happens to be the slapstic CRC test! Simply change either number and the routine won't be called, and the test is never run!


10054, from the table above, will be in ROMs -623 and -624.

54 (hex) divided by 2 is 2A, so looking at the files, you'll hopefully find that the 2A (42nd byte if you prefer decimal) matches as I described?


Change either (I prefer both) to anything else (I prefer 00) and the slapstic test is no more.


File

Offset

Was

New value

16033-623

2A

4E

00

16033-624

2A

F9

00



Run MAME and you'll hit the next problem! We've changed the ROM at 10054, so you'll get a “ROM at 10000 error U L” (upper and lower bytes) appear. Press player 1 start to continue and the game will run fine.


We need to disable this test too. Fortunately, the same ROM chips also store the start and end address for the ROM test. Look at addresses 10080 and 10084. You'll find the following


Address

Data

10080

00 01 00 00

10084

00 02 FF FE


This tells the test code where to start and end the test. We can replace this data will 0's as well, and we will no longer have any ROM errors.


File

Offset

Was

New Value

16033-623

40

00 00 00 FF

00 00 00 00

16033-624

40

01 00 02 FE

00 00 00 00


We can now edit anything else we like, without MAME or the game itself complaining! Phew!!!


Note that the slapstic is still active – we've just changed the game so that we can make changes to the files and the game will try to run. Sometimes it runs with almost comical effect!


Starting Level

We can all finish the practice race with what, 54 seconds left on the clock? That's my best time so far, just because I've run that level so many times now looking for nice breakpoints! (update: made it in 55 seconds now)


The levels are numbered 0 to 5, as you'd probably expect. The code at 110CC sets the starting level for the game, if you look, it reads it from the ROM at address 1F1C8. So if you want to practice a certain level, e.g. the last one, set this to anything other than 0. Set it to 5 and you'll start the game on the final level each time... ideal for those practice sessions!


The important numbers.... you should work this out (1f1c8 – 18000 divided by 2 = 38E4)

So offset 38E4 in the file 136032-625 is a 0 and should be in the region 0-5. My patcher has an advanced option that does this for you – just specify 1F1C8 and it patches the correct file.


You want the 'secret level'? Try the other values 6-FF, but it really doesn't exist :-(

(you can set a breakpoint on 1F1C8 and change the D0 register instead of editing the ROMs for the same effect – press F3 to reset the machine when you find it locks the game up!)



Time, Gentlemen please

(a reference to the UK's outdated 11 o'clock curfew on alcohol...)


So what difficulty level do you play the game on? Very easy? Or stupidly easy/hard?!


Take a look at address 1F18E onwards.


Address

Data

(decimal)

Level

01F18E

3C 41 2D 28 1E 19

60 65 45 40 30 25

Very easy

01F194

3C 41 28 23 19 14

60 65 40 35 25 20

Easy

01F19A

3C 3C 23 1E 14 14

60 60 35 30 20 20

Normal

01F1A0

3C 37 1E 19 14 14

60 55 30 25 20 20

Hard

01F1A6

3C 32 1E 14 14 14

60 50 30 20 20 20

Very hard



I've put the decimal equivalents in there as well, it should be recognisable as the length of time you get for each level. Edit away as you see fit!



Levels

The levels are the tricky bit. So far, I've managed to get some very dramatic changes to the display, with no change to how the game plays, and also get the course to change, with the display being exactly the same. Unfortunately, it's not particularly playable when I've played around!


It would seem that the graphical and physical layout of the maze is stored in the slapstic ROM. I have successfully managed to decode the goal area position, and move it (and the flags), but not make any changes on screen.


There is a table stored at 2BE00 that contains addresses for each of the 6 levels. The subroutine at 16EC6 takes the current level and points 400474 to the correct address from the table.


1A668 is the critical routine for moving the maze data from ROM to the display memory (A00000 onwards). As it moves from 800E4(+), we cannot be 100% sure which part of memory this really is (remember the slapstic ROM is 'mixed up'), although singe stepping the code lets us see the data as it really is. Note that if you monitor the slapstic contents using the built-in debugger, then the bank switching fails. In other words, you can single step the code, but not look directly at the data.


I started looking at the goal area to see where the game is checking the physics. The routine at 26BD8 is called to change the colours of the goal border, although you'll find this routine also changes the colour of the bridge on the beginner level (I'd never noticed the shading change before I found the code that did it!)


The marble 'co-ordinates' in the game are stored at 400024, 400026 and 400028. To make things more 'interesting', these are 3D co-ordinates.


I'm not going to draw a nice picture, but the 400024 address holds the position from bottom left to top right (higher numbers are further down/left) and 40026 is top left to bottom right. The data at 400028 is the 'altitude' above the playfield.


Look at the data at this address

01D896: 0000 0048 0040 3FDC


This is where the first flag on level 1 is stored. The code takes the hex value 48, multiplies by 8 and adds 4 to put the flag at 240, 200 (hex). 3FDC is the altitude and is thankfully stored as 'raw data'. Moving the flag positions does NOT change the position of the goal – I've identified most of the data in the game now (phew!) with the exception of the slapstic stuff. Look in the zip file for how the zones and goal (zone FF) work.


Level data is spread all over the place. Things are getting trickier the more I look!


What I have found is that each level contains 36 blocks of data. Actually it contains 2 lots of this (excluding whatever is in the slapstic) and these correspond to vertical strips down the screen. The length of the block is longer for the longer mazes (duh!), although so far I've not got far in decoding exactly how it all works, other than the 2 blocks are cross referenced, into the slapstic...


Action Items

Can't think of a better name at the moment, but the data from 1D7D0 onwards stores things like the position of the tubes, bumpers (level 1 barriers), the ice on level 2, the catapult on level 4..... Yup, these can be changed (and disabled) quite easily without causing major problems. (The icy bit at the end of level 2 is quite full to roll around in when the ice effect has been disabled)


Some of these are referenced to a particular level (well, the things I just listed above only appear on 1 level) and others seem to be common to all levels. Not sure on details, but look at my decoded ROM dumps as I've put a lot of comments in there. The marble start location has been decoded, and yes, you can change it so that the marble starts in the goal. The game doesn't recognise this and you have to leave/re-enter to finish the level. Having decoded the zones, this is now clear – you need to pass an invisible 'line' into zone FF to finish the level.


I'll say it again, get the zip file I mentioned earlier!



Text display

The screen consists of 30 rows of 42 characters per row. There are also 22 characters per row that aren't displayed.


The top left of the display character is written to A03000 and takes up 2 bytes. A03002 is therefore the second character, going up to A03053 for the top right. The second row starts at A03080, the screen finishes at A03ED3 for the bottom right. These addresses are useful to put a watchpoint on, for example, a watchpoint for when a level is completed and the bonus time text appears.



The following is from the attraction screen, with the 'press start' messages.


 

 

Text colour

1431

0001 0100 0011 0001

blue, transparent (balls seen through it)

3031

0011 0000 0011 0001

orange

3431

0011 0100 0011 0001

blue

3831

0011 1000 0011 0001

dark orange

3C81

0011 1100 0011 0001

yellow

 

xxtc ccxa aaaa aaaa

Where a is 9 bits = character to display,
c = colour palette,
t = (not) transparent and the x's not used.


I'll write more about this one day, but hopefully you get the idea. The large timer is actually 4 characters (2x2) per digit


Here's useful addresses, more details can be found in the MAME source.


400000-401FFF RAM


A00000-A01FFF Tile details

A02000-A02FFF Sprite details (moving things)

A03000-A03FFF Text details


B00000-B001FF Text colour palette

B00200-B003FF Sprite colour palette

B00400-B005FF Playfield palette

B00600-B007FF Translucancy palette


Tile display


This is the 'maze' itself. The maze is made up of 'stamps' – 8x8 pixel blocks – that are stored in RAM starting at A00000. The system 1 hardware stores an area 64x64 stamps (or tiles if you prefer) although only 42x30 are visible at any one time. Marble madness takes this a little further and blocks the left and right 3 characters – making a playfield that is 36 stamps across.



Representation of memory / screen display




A00000 A00002 A00003 ... A0007E

A00080 A00082... A000FE

A00100



Vertical scroll register

(820000)




...

...

64 stamps

...

...






Horizontal scroll register

(800000)


A01F00

A01F80 ... 64 stamps ... A01FFE



The horizontal scroll register is always 0 - the screen never scrolls left to right. The vertical scroll register is written every VBlank interval (vertical blank of the monitor electron gun) and is used frequently. The memory wraps around in all directions, so line A00000 is after A01F80. Remember that the hardware considers the screen to be 42x30 stamps, the game chooses to use 36x30. Each location requires 2 bytes (16 bits) to store the stamp

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

Flip

Picture number


'Flip' is horizontal flip.

Palette


So that's how the maze and text is stored in RAM. What about the colours?


B00000-B001FF Text colour palette

B00200-B003FF Sprite colour palette

B00400-B005FF Playfield palette

B00600-B007FF Translucancy palette


Text colours are stored in ROM at the following address:


01FBD0: AFFF F0CF F06F F00F AFFF AFCC AF66 AF00

01FBE0: AFFF 0000 700F F00F AFFF 0000 7F00 AF00

01FBF0: 0000 FF00 FF30 FF70 0000 F35F F47F F6AF

01FC00: 0000 0000 0000 FA30 0000 AFFF 0000 FFE0


and get copied to the colour palette RAM (B00000) when the game initialises.


We can see that there are 32 text colours, and we know that 3 bits of the text memory (A03000) store the required palette – that lets us select one of 8 colours. So there must be a way of saying which of the 4 banks we want to use. More on this when I work it out fully!


Colours throughout the game are encoded this way:


Intensity

Red

Green

Blue

F

0

0

F


Each can range 0-F, to set colour and brightness. Change to 70F0 for a darker green, FFFF for bright white etc.



More on the palettes another day.


So far then, a long way from designing a custom level – or even adding changing the existing ones at all! I have a few more notes here, that I haven't written up as yet, but mostly they are routine addresses that you can easily find with the above.


One idea is to add 'marbcust' to a custom MAME binary – declaring my own ROMs somewhere like 30000 and patching the existing data to point to my levels. This means that I can forget about the slapstic coding of the data and anyone can simply create their own add-on ROM sets! That's unfortunately a long way in the future (I don't really want to say never!) as I can't even make a hole in the maze, let alone a catapult or tube! I have managed to add acid/black balls to level one though.


PLEASE HELP if you can. I need some assistance working on the maze layouts themselves. If you're good with 68000 assembly, please fire up mamed and give me some clues as to how

the code at 1A690 takes [800EA] = 15020821 and becomes '20' at A0008D


Lets make this level editor a reality! Contact details are at the top of this page...



This information is provided to the best of my knowledge and is intended to be shared. I'm not interested in 'who' generates 'fame' by writing a level editor, just that someone does! I'd like to adopt the 'open source' view and share any information that people have, please contact me with anything you have – especially if something I have here is wrong, or you've solved something that I haven't.