Intro Post Part 1/2Preamble
Have you ever searched this forum for Toejam and Earl hacks? Or for general information relating to which is considered by many (including myself) to be the single greatest game on the Sega Megadrive? If you haven’t let me save you the time, a search for “Toejam” (as at 24/1/2016) turns up a measly 8 results and 3 of them are mine!
Although it isn’t just RHDN that is sparse on information, even googling “Toejam and Earl Rom Hack” turns up next to nothing, a solitary page on Sonic Retro with some sparse notes about uncompressed graphics and ASCII text: http://forums.sonicretro.org/index.php?showtopic=20964
Well, this project aims to change all that!TL;DR –
I’m creating a disassembly of Toejam and Earl, I’m about 5% through, I’ve only done the easy parts I've created a disassembly of Toejam and Earl! You can check out the source code on its BitBucket repository here or keep reading to find out more about the project and the work done to date.Intro
I am Ryan and I am from Scotland, hence the user name RyanFaeScotland. I’ve been posting here and ROM hacking on and off for several years now and despite having my own site dedicated to the information I’ve discovered, a few video tutorial on ROM hacking and even an accepted (and then rejected) submission to RHND I’ll be the first to admit I am still yet to contribute anything of any serious substance or value to the community. That is part of the reason why I’ve set myself the rather lofty challenge of creating a complete disassembly of Toejam and Earl on the Sega Megadrive.
The other part of the reason is that it is without a doubt the one game that has cemented its place deep within my childhood memories. It is a game I used to play for hours on end with my best friend (who has since moved to America) and alone on single player. It scares me to think how many hours I lost to this game, easily on par with games that are actually meant to be long like Shining Force 2, FF7, Metal Gear and so on.
I’m now at a point where I find myself, as an adult software developer, more interested in the magic behind the game than I am in actually playing the game itself. Just what is it that makes Rocket Skates impossible to stop? What is the game doing behind the scenes during the elevator cut scenes? How does the random level generator work? And, most importantly, how can I make the game more centred around spending time in the hot tub with the hula girls?
So this project is more than just a means of giving back, it is also a tribute or a living memory of my childhood and all the joy T&E brought to it, a sort of labour of love to honour the game that gave me so much enjoyment.
The whole thing kicked off back in October 2015 when a ROM hacker by the name of Juan Perez contacted me saying he had created a disassembly of Toejam and Earl and would like my help to get the results understood. He had worked out a few things but since the disassembly had been created fairly blindly by running disasm.exe against the entire ROM file the output contained a mess of data, instructions, tiles, music and text which had all be decompiled as code.
Although I haven’t heard from Juan since it was enough of a proposal to really capture my interest and get my off by butt and start and now that I am I’m resolved to complete it!Project Goals
This post will be kept up to date as the project progresses and goals will be added and removed as time goes on. Main Goal
There is of course one main goal that will always remain:
- Create a complete, annotated disassembly of Toejam and Earl that can be modified, reassembled and played on real hardware.
To help me achieve the main goal here are some additional sub-goals that will make it possible (these will always be needing fleshed out):
Get Megadrive initialisation mapped out and understood.
- Get intro loop mapped out and understood.
- Get initial game menu mapped out and understood.
Locate uncompressed graphics.
- Locate compressed graphics.
- Understand graphics compression algorithm.
Locate uncompressed text.
- Locate compressed text.
- Understand text compression algorithm used.
And here are some fun goals to do along the way to save me going too crazy looking at line after line of 68K!
Progress ReportsProgress Report 1
- Slingshot to be a deadly tomato cannon.
- Make Santa chase Toejam / Earl.
- Make it possible to change which presents are in the inventory.
Change the presents T&E start the game with. Make presents always identified.
I started the project in earnest at the end of December 2015 and have done this initial post on the forum on the 24th of January 2016. At this point roughly 5% of the game has been disassembled and marked up, however, a large portion of this is made up of the uncompressed graphics that are clearer visible in the ROM using Tile Layer Pro so don’t get too excited.
To date the majority of time has been spent trialling different emulators and related tools to see which ones are going to aid me best in the project. A little write up of the current toolchain and process used to disassemble and understand the ROM is given below but as it stands I am currently using GENS r57shell Mod for my exploration and testing of the ROM, Easy68K for my re-assembling and Notepad++ for the majority of my note taking.Progress Report 2
- 04-Mar-2016Progress Report 3
- 01-Nov-2016Progress Report 4
- 19-Jul-2018Progress Report 5
- 13-Mar-2019Progress Report 6
- 20-May-2019Progress Report 7
- 30-Jun-2019Progress Report 8
- 19-Jun-2020Sections of Interest
Here are a few sections of interest I’ve uncovered so far:Game Setup
Part of setting up the game, setting lives, score, cash.
*Initial Presents Setting
* Loading lives and so on
0000BB78 207C 00FFA248 MOVE.L #$00FFA248,A0
0000BB7E 4A10 TST.B (A0) *Checks if Toejam is in the game.
0000BB80 6D1C BLT $0000BB9E
0000BB82 13FC 0001 00FFA2A6 MOVE.B #$01,$00FFA2A6
0000BB8A 13FC 0017 00FFA252 MOVE.B #$17,$00FFA252 *Sets Toejam's health to $17 on game start.
0000BB92 10BC 0003 MOVE.B #$03,(A0) *Sets Toejam's lives to 3 on game start.
0000BB96 13FC 0003 00FFA24A MOVE.B #$03,$00FFA24A *Sets Toejam's cash to 3 on game start.
0000BB9E 4A28 0001 TST.B $0001(A0) *Checks if Earl is in the game
0000BBA2 6D1E BLT $0000BBC2
0000BBA4 13FC 0001 00FFA326 MOVE.B #$01,$00FFA326
0000BBAC 13FC 001F 00FFA253 MOVE.B #$1F,$00FFA253
0000BBB4 117C 0003 0001 MOVE.B #$03,$0001(A0)
0000BBBA 13FC 0003 00FFA24B MOVE.B #$03,$00FFA24B
0000BBC2 13FC 00FF 00FFA259 MOVE.B #$FF,$00FFA259
0000BBCA 13FC 00FF 00FFA258 MOVE.B #$FF,$00FFA258
0000BBD2 13FC 00FF 00FFDE50 MOVE.B #$FF,$00FFDE50
0000BBDA 13FC 00FF 00FFDE51 MOVE.B #$FF,$00FFDE51
0000BBE2 4878 0001 PEA $0001
0000BBE6 42A7 CLR.L -(A7)
0000BBE8 4EBA F2AE JSR $0000AE98(pc)
0000BBEC 4878 0001 PEA $0001
0000BBF0 4878 0001 PEA $0001
0000BBF4 4EBA F2A2 JSR $0000AE98(pc)
0000BBF8 42A7 CLR.L -(A7)
0000BBFA 4EBA EE3E JSR $0000AA3A(pc)
0000BBFE 4878 0001 PEA $0001
0000BC02 4EBA EE36 JSR $0000AA3A(pc)
0000BC06 42A7 CLR.L -(A7)
0000BC08 4EBA F0A0 JSR $0000ACAA(pc)
0000BC0C 4878 0001 PEA $0001
0000BC10 4EBA F098 JSR $0000ACAA(pc)
0000BC14 42A7 CLR.L -(A7)
0000BC16 4EBA F7AC JSR $0000B3C4(pc)
0000BC1A 4878 0001 PEA $0001
0000BC1E 4EBA F7A4 JSR $0000B3C4(pc)
0000BC22 4FEF 0028 LEA $0028(A7),A7
*Input Polling (Pad1)
* Adds Bonus HiTops to Toejam's inventory, 4 on single player, 2 on 2 player.
0001435C 4E71 NOP
0001435E 588F ADDQ.L #$4,A7
00014360 14BC 001B MOVE.B #$1B,(A2)
00014364 157C 001B 0001 MOVE.B #$1B,$0001(A2)
0001436A 4A39 00FFA249 TST.B $00FFA249
00014370 6C0C BGE $0001437E
00014372 157C 001B 0002 MOVE.B #$1B,$0002(A2)
00014378 157C 001B 0003 MOVE.B #$1B,$0003(A2)
0001437E 4A39 00FFA249 TST.B $00FFA249
00014384 6D2C BLT $000143B2
00014386 4878 0001 PEA $0001
0001438A 4EBA 07D4 JSR $00014B60(pc)
* Adds Bonus HiTops to Earl's inventory, 4 on single player, 2 on 2 player.
0001438E 4E71 NOP
00014390 588F ADDQ.L #$4,A7
00014392 157C 001B 0010 MOVE.B #$1B,$0010(A2)
00014398 157C 001B 0011 MOVE.B #$1B,$0011(A2)
0001439E 4A39 00FFA248 TST.B $00FFA248
000143A4 6C0C BGE $000143B2
000143A6 157C 001B 0012 MOVE.B #$1B,$0012(A2)
000143AC 157C 001B 0013 MOVE.B #$1B,$0013(A2)
000143B2 245F MOVE.L (A7)+,A2
000143B4 4E75 RTS
*Present Time Counter
* Input Reading Routine
00027006 33FC 0100 00A11100 MOVE.W #$0100,$00A11100 *Turn off Z80
0002700E 13FC 0040 00A10009 MOVE.B #$40,$00A10009
00027016 13FC 0000 00A10003 MOVE.B #$00,$00A10003 *Request Low byte from A10003 (Pad1)
0002701E 323C 000A MOVE.W #$000A,D1 *Move A (10) into D1
00027022 51C9 FFFE DBRA D1,$00027022 *Loop until D1 = 0 (short delay to read pad)
00027026 7000 MOVEQ #$00,D0 *Clear out D0
00027028 1039 00A10003 MOVE.B $00A10003,D0 *Move value from A10003 (Pad1) to D0
0002702E E508 LSL.B #2,D0 *Bit shift D0 left 2 bits
00027030 0200 00C0 AND.B #$C0,D0 *And it with C0
00027034 13FC 0040 00A10003 MOVE.B #$40,$00A10003 *Request High byte from A10003 (Pad1)
0002703C 323C 000A MOVE.W #$000A,D1 *Move A (10) into D1
00027040 51C9 FFFE DBRA D1,$00027040 *Loop until D1 = 0 (short delay to read pad)
00027044 1239 00A10003 MOVE.B $00A10003,D1 *Move value from A10003 (Pad1) to D1
0002704A 0201 003F AND.B #$3F,D1 *And it with 3F
0002704E 8001 OR.B D1,D0 *Or them together
00027050 4600 NOT.B D0 *Negate D0
00027052 5539 00A0004A SUBQ.B #$2,$00A0004A
00027058 13F9 00A0004B 00FFE46E MOVE.B $00A0004B,$00FFE46E
00027062 33FC 0000 00A11100 MOVE.W #$0000,$00A11100 *Turn on Z80
0002706A 4E75 RTS
* From around this address controls the length of time left for presents
000158F0 3002 MOVE.W D2,D0
000158F2 48C0 EXT.L D0
000158F4 207C 00FFDE50 MOVE.L #$00FFDE50,A0
000158FA 4A30 0800 TST.B $08(A0,D0.W)
000158FE 588F ADDQ.L #$4,A7
00015900 6C4C BGE $0001594E
00015902 6048 BRA $0001594C
00015904 3002 MOVE.W D2,D0
00015906 48C0 EXT.L D0
00015908 D080 ADD.L D0,D0
0001590A 204A MOVE.L A2,A0
0001590C 5370 0800 SUBQ.W #$1,$08(A0,D0.W) *Subtracts 1 from the amount of time left on the present.
00015910 3030 0800 MOVE.W $08(A0,D0.W),D0
00015914 0C40 012C CMP.W #$012C,D0 *Checks if less than 300 cycles are left on present.
00015918 6302 BLS $0001591C
0001591A 6030 BRA $0001594C
0001591C 3002 MOVE.W D2,D0
0001591E 48C0 EXT.L D0
00015920 D080 ADD.L D0,D0
00015922 0C72 0064 0800 CMP.W #$0064,$08(A2,D0.W) *Checks if less than 100 cycles are left on present.
00015928 6314 BLS $0001593E
0001592A 3002 MOVE.W D2,D0
0001592C 48C0 EXT.L D0
0001592E D080 ADD.L D0,D0
00015930 7200 MOVEQ #$00,D1
00015932 3232 0800 MOVE.W $08(A2,D0.W),D1
00015936 700C MOVEQ #$0C,D0
00015938 C280 AND.L D0,D1
0001593A 6712 BEQ $0001594E
0001593C 600E BRA $0001594C