Recently, someone reminded me that Mega Drive emulators kinda suck, as does the hardware they emulate. Not keeping this in mind may lead to your hacks not working on hardware or even certain emulators. So I've decided to make this thread to list as many as we can, so that money I spent on an Everdrive doesn't go to waste... Hardware Hardware's very picky, but in an age where emulators are getting better in terms of accuracy, hardware is no longer alone. If you want compatibility with the likes of Regen and Exodus, you gotta keep an eye out for hardware quirks. Odd Address Error I don't know the technicals behind it, but the 68k can't access a word/longword of data that starts on an odd address. This can be code, data or even RAM variables. Attempting to do so will trigger an exception, which, depending on the game you're hacking, can have different results: Sonic 1 - enters debugger - game freezes and debug text appears (can be escaped by pressing C) Sonic 2 - enters ErrorTrap - game hangs with no way out Sonic & Knuckles - enters ErrorTrap and then EntryPoint - game resets None of these are really something you want to see happen during normal gameplay. Regen and hardware are the only platforms I've noticed that trigger an odd-address exception. If you want to support those platforms, make it a goal to correct anything that can cause that (and even then, plain Gens doesn't seem to agree with code that starts on an odd address, so it's probably just worth doing in general). The assembler itself can help with detecting any fishy reads/writes. Well, asm68k doesn't, but AS at least raises a warning when obvious broken reads/writes are detected, like this little gem from Sonic 2 REV00: Code: > > >s2.asm(27974): warning: address is not properly aligned > > > move.w (1).w,d0 ; causes a crash on hardware because of the word operation at an odd address This here is what causes REV00 to crash when you try to place an object in debug mode while dead. Note that the more cryptic instances like this will not be detected: Code: lea (1).w,a0 move.l #'lolo',(a0) As for what you can do... there's the 'even' macro, which aligns things to an even address. Consider the following example: Code: byte_6E36: dc.b 0, 0,$FF, 0, 0 even ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| ;sub_6E3C SSPlaneB_SetHorizOffset: moveq #0,d7 ... byte_6E36 starts on an even address, continues for five bytes, then ends. Directly following that is code. That code must remain on an even address. The presence of an 'even' macro ensures that the code will be placed on an even address. You might ask why 'even's should be used when a simple 'dc.b 0' can do the same thing. The reason is that 'even's are safe to use even where they're not needed: placing an 'even' on an already-even address will not cause it to misalign everything after it, or waste space by padding until the next even address; it will simply not do anything. It is for this reason that it is advisable for 'even's to be placed after any and all data, even if you know the data won't end on an odd address. One less thing to worry about, you know? The programmer can be at ease knowing there's no chance their shiny new table will cause any odd address issues down the road. As for code, I'm pretty darn sure all 68k instructions are even in size, so there's no need to worry about that. Code just needs to start on an even address. RAM works a bit differently. You can't use an 'even' macro on 'ramaddr( $FFFFEE0B )'. That's definitely an area where AS' detector comes in handy. As for the S2 disassembly's way of declaring RAM, 'even' should work well enough, I guess. You'd be wasting RAM by filling it with padding, though. It's usually worth just rearranging your RAM so little byte-sized variables act as the padding instead. VDP Read Error Why was that last section so big but these ones aren't? Here's something that eludes even Regen, and has haunted my main hack for ages. You may be tempted to optimise the following instruction by changing it to a 'clr.l'... Code: move.l #0,(a6) ; a6 is VDP_data_port This, however, causes the game to hang. Again, I don't know the technicals behind it, but it's there, so it should be avoided. 'move' seems to be the only safe instruction to use. I hear it's got something to do with how 'clr' involves reading the destination, but I can't be too sure on that. Just remember to be careful if you batch replace 'move #0', to 'clr', like I did. CRAM Dot Bug Due to a bug with the VDP, if the CRAM (palette) is updated mid-frame (that is, while the hardware is still drawing the screen), stray dots of varying colour will appear all over the screen. It doesn't cause any crashes, but it's pretty distracting. You can see this in S1, S2 and some areas of S3K in the water levels, by looking where the level's colour change from normal to water-tinted. Normally, you never see this in the likes of Sandopolis act 2, where the palette is always changing, because the Sonic engine queues changes to CRAM, and only actually does them at the end of the frame, where there's no risk of the dots appear over anything important. For zones like AIZ, S3K found a clever way of avoiding it, even with the water palette: by only updating small parts of VRAM per H-Int, the dots only appear in the overscan to the left of the screen, but this comes at the cost of the colours only being updated gradually, with some colours changing a significant distance below the actual water line (dip half of Tails in water in AIZ1 to see what I mean). Basically, don't update CRAM directly, unless you really know what you're doing, especially if you don't know exactly when it's gonna update. Z80 DMA Pause EDIT: Apparently there's actually a reason the Z80 is paused. See here for more. In stock S1/S2/S&K, before beginning a DMA transfer, the game manually stops the Z80, and starts it back up afterwards. This is likely so the Z80 doesn't try to use the 68k's bus while it's being used for DMA, but this is unnecessary, as, if this does happen, the Z80 will just wait it out and pause, anyway. Or, at least, that's what it does on hardware. Every emulator I've checked lets the Z80 keep running, leading to such things as brilliant PCM playback in emulators, but the same stuttering mess we've grown used to on hardware. Emulators There are also quirks that can break compatibility with emulators, inaccurate or not. Being fancy with your hack can lead to odd cases where only one certain emulator is left in the dust, with the others seemingly completely okay with it. Regen SRAM Scrambling If your hack uses SRAM, don't expect Regen to play ball. It seems to byteswap SRAM when you close it, so the average user will pick up your hack after leaving it for a while only to find their save data gone. No fun. Fusion mode 1 DMA Failure Many look at Kega Fusion as the only way to play hacks that take advantage of the Mega CD's mode 1 functionality (coughgenplusgxcough) but it has a pretty nasty problem in that DMA transfers never seem to occur. In games like Sonic 2, this can impact Sonic & Tails' displaying, the animated level art, and even the animated menu backgrounds. You can see this just by loading stock S2 and doing CTRL-B, which boots the Mega CD (make sure you have Mode 1 enabled in the INI file). Well, that came to an abrupt end. If anyone else knows any other cryptic stuff like this, please do tell.