sources:
- http://www.pantalytron.com/blog7.php/an-evening-with-sim-city
- http://pantalytron.com/blog7.php/a-morning-with-sim-city
- http://pantalytron.com/blog7.php/some-more-sim-city-snes
r.i.p. to these files:
- http://pantalytron.com/media/blogs/blog/Disassembles/sim%20city%20v01.zip
- http://pantalytron.com/media/blogs/blog/Disassembles/sim%20city%20v02.zip
part 1:
-
The Game-Map is in WRAM at $7F0200.
-
Each tile is 16 bit in size (Seems like the data gets transfered from there to VRAM without any changes).
$00 00is empty ground.$01 00is water$02 00is water$03 00is water$04 00is a shore (south-west to north-east, north-west is land)$05 00is a shore (east west, north is land)$06 00is a shore (south-east to north-west, north-east is land)$07 00is a shore (north south, west is land)$08 00is a shore (north south, east is land)$09 00is a shore (south-west to north-east, south-west is land)$0A 00to$13 00are shores, too. Don't care for that$14 00to$25 00are forest tiles$26 00is park (meadow)$27 00is park (tree)$28 00is a polluted area$29 00is a polluted area$2A 00to$2D 00look like animation sprites of a explosion$2E 00and$2F 00are... totally weird- From
$30 00on, you can find the street tiles $70 00are underwater rails (east west)$71 00are underwater rails (north south)$72 00are rails (east-west)$76 00are rails (east-south)
-
AWESOME! Residental areas without power supply have the tiles $80 00 81 00 82 00. Those WITH power supply have the tiles: $80 80 81 80 82 80.THIS IS WRONG I'LL EXPLAIN LATER Seems like the Data is edited somehow before it is transfered to VRAM. That bit that is used is originally for the Vertical Flip of the tile. -
The Scenario Maps are compressed, of course.
-
Somehow the data is transfered from
$7E8000to$7F0200, there it gets decompressed to$7E8000, and gets (unchanged) transfered back to$7F0200. -
The code for the decompression that happens from
$7F0200back to$7E8000is at$03D1C4.#$FFFFis the signal for the end of data. Bits 10 to 13 (#$3C00) are the number of times this tile shall be repeated plus one (#%...0001... = #$0400 = two times the same tile; #%...1111... = #$3C00 = sixteen times the same tile) -
The Data that is AT FIRST at
$7E8000is the data that gets decompressed as explained above. That data itself gets decompressed when it gets transfered from ROM to$7E8000. -
#$FFis a special command in this data, I expect it to be the end signal of data. -
Bits 5 to 7 are reserved for different commands.
-
If Bits 5 to 7 are
#%000?.????(=#$0?or#$1?), the following bytes get transfered directly to the decompressed data buffer as they are. The number of bytes that follow are Bits 0 to 4, minus one. For example:$01 $4F $50sets two bytes,$4F and $50, directly in the buffer.$04 $02 $01 $40 $41 $24sets the last five bytes in the buffer. -
If Bits 5 to 7 are
#%010?.????(=#$4?or#$5?), the other bits are the number of bytes that get set in the following pattern (#$40= one byte,#$41= two bytes,#$50= seventeen bytes etc.). The next two bytes are the pattern that get set. For Example: At the beginning of the San Fransisco Scenario Data, it is$4A $01 $3C. So the next eleven bytes (eleven =#$0B=#$0A+ 1) are$01 $3C $01 $3c $01 $3C $01 $3c $01 $3C $01. That means, with an even number in the first byte, you decompress an uneven number of bytes, which means that the last 16-bit-data value isn't completed yet. The "$01 $3C" gets further decompressed to: "Repeat tile#$01sixteen times". The last entry here has no number of repitions yet (the#$3Cmeans the "repeat sixteen times"). Tile$01is water, this is a whole lot of it. How... fitting for the border of a map. -
If Bits 5 to 7 are
#%110?.????(=#$C?or#$D?), the program repeats some bytes that are already decompressed. The other bits contain the number of bytes that should be repeated minus one (so$C0repeats one byte,$C3repeats four bytes,$C4repeats five bytes and so on). The next byte says how many bytes the thing should move back. So, if the last bytes were$04 $02 $C2 $03and the next command is$C2 $03, the next bytes are$02 $C2 $03. If the next command is$C4 $02, the next bytes are$C2 $03 $C2 $03 $C2. The thing repeats the bytes itself set two loops ago. You get the idea. -
Sim City uses the COP-Interrupt. Like Illusion of Gaia. Unlike Illusion of Gaia, it doesn't use the argument byte after the COP. Instead, it uses the value in A as an Index for a Jump Table.
-
The first decompression subroutine is one of the subroutines in the COP Jump Table. To start it, they load
#$08in A before they COP. If found out by accident that this decompression subroutine is often used on the title screen, too. -
The Address Table for the Scenario Maps is at
$03:CE70onwards. Its not listed in whole 24-bit-values, but each byte is separated: Address Low Byte at$CE70+Y; Address High Byte at$CE79+Yand Address Bank at$CE82+Y.
-
First Decompression Commands, Part 2:
- If Bits 5 to 7 are
#%001?.????(=#$2?or#$3?), the subroutine repeats the following byte multiple times. The number of repition is the value in Bits 0 to 4 plus one. E. g.:$22 $15results in$15 $15 $15. - If Bits 5 to 7 are
#%011?.????(=#$6?or#$7?), the subroutine puts out a line of bytes that are counted up. The Argument Byte is the start value. E. g.:$64 $4Aresults in$4A $4B $4C $4D $4E. - If Bits 5 to 7 are
#%100?.????(=#$8?or#$9?), it seems like it is another of these repition things, but with absolute addressing instead of the relative addressing at#%110?.????. - I don't know what
$A0does, but it seems like it's for a horizontal repition of a vertical tile series. Not sure, don't interested in checking it (right now).
Other notes:
- The game maps are 120 x 100 tiles in size.
- At the end of each scenario data, they write an
$FF $FF $FF. A single, well-placed$FFshould have done it, too. - The game won't break if the compressed map data isn't enough to fill the whole screen. I tested it by completely removing one scenario map, directing straight on a
$FF $FF $FF. The game started to run, the map was a mess, of course, because it interpreted every junk that was left in WRAM as map data. Unfortunately, there were some weird things that happened, so you can possibly crash your game if you play it that way. - The road tiles are at
$30-$3F.$40-$4Fand$50-5Fare the very same tiles, but crowded and super-crowded. If you place them by WRAM editing, they soon turn normal if there is nothing around that would justify the crowdedness, of course. - Tilemolester says the graphics for Bowser In-Game (the monster that is destroying Tokyo) are at $20000, so I guess the program means $04/8000. The graphics fill the whole bank. Man, this game is small!
- The last bank (
$0F/8000ingame, this game is small!) consists of the messages for Dr. Wright for all the ingame announcements. In plain ASCII code. The missions descriptions are not there, they seem to compressed in one way or another. - At
$2A000(so...$05/A000?) are the UFO graphics, followed by the roads and stuff. $7E0CA5contains the city level. This ZSNES Cheat Search function is great.- The 15th Bit in the tiles has nothing to do with electricity supply. If it is set, a 3x3 square gets generated. This is useful for positioning 3x3-buildings. It doesn't work for bigger buildings, like power plants or ports.
- The subroutine at
$03/CE8Bloads the start values for the scenarios into the RAM registers. There are tables at$03/CEC9onwards for this, each with eight doublebyte entries. The value in$CEE9+Yis the city level,$CEF9+Yis the population's lower double byte,$CF09+Yis the population's higher double byte. $40contains the scenario number, if I hadn't mentioned that before.- The city's name is stored at
$7E0B5Conwards. This ZSNES Cheat Search function is really great. - City name is coded in
#$00-#$09numbers, from#$0Aon alphabet, signs should be after the alphabet. $7E0B5Bcontains the length of the name (max. 8, the zero doesn't count, so#$04means: four letters). If you diminish it through RAM editing/ARP code, the name of the city on the small radar when you scroll the map is cut off (the next time that graphics have to load, i. e. when you leave the screen for a menu and return)- For the scenarios, you find a 16-bit address table at
$03/CF32(=$01CF32in ROM). The addresses are bound to that bank and point to the scenario cities' names. These addresses are in a list themselves that you can find at$CF44onwards. The first byte is the number of letters, the rest is the name. The first byte gets transfered in$7E0B5B(see above). If you ever want to change the name, luckily you have some#$10s of byte free space at the end of the bank. The subroutine that does the ROM read-out and name setup is$03/CF32. $7E00B5contains the HDMA flags.$7E00B7contains the DMA flags (maybe someone should write a proper RAM map?).- The code at
$00/81BFshows that registers$7E0016-21are buffers for$210D-12. - The subroutine at
$00/833Ashows that registers$7E005F-71are buffers for registers around$2100/30. - OAM-Buffer is at
$7E2000(see$00/8D65). - If I see correctly, the whole tileset for the scenario screen is compressed as the scenario city map data (
LDA #$0008,COP #$00), and fairly unorganized. So editing the city name and image will be a mess, unless someone writes a nice de-/recompressor tool with Editing GUI.