Edit: I made a new version fixing a bug and adding a binary-blob version. See this post for more information. The original post now follows: [hr] I was going to make this an update to the old topic... but decided it would be best suited to a new topic entirely. So, you remember that aging debugger I made for address/bus errors? I updated. A few things that changed: The disassembler is now logically separate from the drawing code and from the debugger (the debugger depends on both of them, the disassembler depends on the drawing code); I made sure that the code almost fully position-independent, meaning a binary blob can possibly be made (but see below); loads of bug fixes; recovers more information from branches and jumps, and does so correctly now for dbCC opcodes; brand new font; handles far more errors than just the address and bus errors (the latter of which I have since learned never happens on a real Genesis...); has code that will make macro haters want to stay away. Note: If you use asm68k, you will not be able to build this. I use macros and functions to make the code more maintainable and readable, and asm68k sucks. Badly. And I am not saying this only in regards to macros -- I used to think it was only slightly worse than AS, but now I stand corrected: while I was working on a binary blob to support asm68k, I ran into a serious bug in it that caused it to misassemble the code generating wrong output. It suffices to say that instead of helping, I will mercilessly mock anyone that insists on using asm68k because of their bad decision-making skills. There is another warning I must give: I won't give support for anything but the Community disassemblies, so if you insist on using outdated disassemblies, you are on your own. With those out of the way: first, let me explain how you will go about generating a listing file. In the previous version, I talked about map files; listing files are much better because they are generated much faster; the S2 and S&K disassemblies disable it by default, though. In S2, you have to edit 3 places: one in s2.macrosetup.asm and the rest in s2.asm; so: in s2.macrosetup.asm: find this: [68k] listing off[/68k] and change it to this: [68k] listing purecode[/68k] You can also use "on" or "noskipped" instead of "purecode", but I recommend using the latter. So now over to s2.asm, do the same twice. Now whenever you build your hack, a s2.lst file will also be generated. For S&K, you have to do the same once in sonic3k.macrosetup.asm, then in sonic3k.asm find this: [68k]Z80_Snd_Driver: include "Sound/Z80 Sound Driver.asm"[/68k] and change it to this: [68k]Z80_Snd_Driver: include "Sound/Z80 Sound Driver.asm" listing purecode[/68k] Now that you are armed with listing files, time to hook up the new debugger! So go on ahead and grab it here. There are seven files in this archive; only 6 are needed for S2, the seventh is for compatibility with the S&K disassembly. Extract these to your hack's main folder. You can move these around, as long as you edit the includes in the relevant files. You want to add these includes: For S2: [68k] include "_inc/Debugger.asm"[/68k] For S&K: [68k] include "skcompat.asm" include "Debugger.asm"[/68k] These are enough to get everything working; he other files are pulled in automatically. Now the debugger is being assembled inside your hack; you want to setup the interrupt vector table to make use of it: In S2: find ";Vectors:" and replace the whole table with this: [68k];Vectors: dc.l System_Stack , EntryPoint , BusError , AddressError ; 4 dc.l IllegalInstrError , ZeroDivideError, CHKExceptionError, TRAPVError ; 8 dc.l PrivilegeViolation, TraceError , LineAEmulation , LineFEmulation ; 12 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 16 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 20 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 24 dc.l SpuriousException , ErrorTrap , ErrorTrap , ErrorTrap ; 28 dc.l H_Int , ErrorTrap , V_Int , ErrorTrap ; 32 dc.l TrapVector , TrapVector , TrapVector , TrapVector ; 36 dc.l TrapVector , TrapVector , TrapVector , TrapVector ; 40 dc.l TrapVector , TrapVector , TrapVector , TrapVector ; 44 dc.l TrapVector , TrapVector , TrapVector , TrapVector ; 48 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 52 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 56 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 60 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 64[/68k] In S&K: find "Vectors:" and replace the whole table with this: [68k]Vectors: dc.l Vectors , EntryPoint , BusError , AddressError ; 4 dc.l IllegalInstrError , ZeroDivideError, CHKExceptionError, TRAPVError ; 8 dc.l PrivilegeViolation, TraceError , LineAEmulation , LineFEmulation ; 12 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 16 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 20 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 24 dc.l SpuriousException , ErrorTrap , ErrorTrap , ErrorTrap ; 28 dc.l H_int_jump , ErrorTrap , V_int_jump , ErrorTrap ; 32 dc.l TrapVector , TrapVector , TrapVector , TrapVector ; 36 dc.l TrapVector , TrapVector , TrapVector , TrapVector ; 40 dc.l TrapVector , TrapVector , TrapVector , TrapVector ; 44 dc.l TrapVector , TrapVector , TrapVector , TrapVector ; 48 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 52 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 56 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 60 dc.l ErrorTrap , ErrorTrap , ErrorTrap , ErrorTrap ; 64[/68k] If you try to assemble and you get errors, it is because you are using an older version of AS; get the new version and replace the ones you have. The Git repositories for the Community disassemblies already have this version, by the way. Now you just need to trigger an error to see it in action; but if you do that, you will notice that your name and e-mail are wrong; so open "Debugger.asm" and find the following lines: [68k]HackerName: vtstring WHITE,"Your name" EMailmsg: vtstring BLUE ,"[email protected]"[/68k] Except that the e-mail will not be in yellow and underlined, that is just the forum software being an ass. Anyway, supported colors are WHITE, RED, GREEN and BLUE; you can edit the text at will, but your name should not exceed 11 characters -- this is all the space available in the current setup. As the comment near this says, you can use any of the characters int he ASCII set. Another thing to do is edit the value of the "Revision" constant in the same file -- this number can be used to uniquely identify the version in which the error happened, so you will know if you already fixed the error or not. When all is said and done, this is what you will see (using two manufactured examples): As a bonus: since the code is logically separate, the disassembler can be used on its own; here is an example of a minimal disassembler that can be build using it: This was done with this code: [68k]DisassemblyTest: bsr.w InitTerminal lea DrawTerminal(pc),a3 tellp.l -(sp) ; Save end of buffer setcursor DisassemblyAlign,0 .instr_loop: shared .instr_loop move.l (sp),d0 ; Get end of screen buffer vtchkp.l d0 ; Is this after current position? blo.w .draw_terminal ; Branch if not tellp.l -(sp) ; Save start of line move.w (a3)+,d5 ; Read instruction lea RewindStub(pc),a4 ; Pointer to rts bsr.w Disassemble_Opcode movea.l a2,a3 ; PC for next instruction tellp.l d0 ; Save current position on buffer seekset (sp)+ ; Seek back to old position .next_line: seekp.l nCols ; Advance it by one line vtchkp.l d0 ; Is this after current position on buffer? bhs.s .next_line ; Branch if not bra.s .instr_loop ;--------------------------------------------------------------------------------------- .draw_terminal: addq.w #4,sp ; Pop end of screen buffer from stack bsr.w DrawTerminal .error_trap: nop nop bra.s .error_trap ; ===========================================================================[/68k]
It has been pointed out that the version of AS in the Community disassemblies is a bit outdated, and does not have a function I used in the macros; I compiled a new version that handles it just fine, and I will be uploading it to the repositories soon. Edit: The community repositories are now up to date.
I made an alternative font for this, because I am endlessly nostalgic for the early days of teletext and the BBC Micro. This is based on the characters you would have got out of an SAA5050. The descenders are squashed because it's a bit too tall for 8x8, but it's otherwise very faithful. Download (Kosinski-compressed tiles)
Excuse me for bumping this up, but I have just noticed a little issue trying to build it for my SegaCD hack: Code (ASM): subi.w #System_Stack,d3 ; d3 = -1 * number of bytes to print This line gave me a little error, which I fixed this way... Code (ASM): subi.w #(System_Stack)&$FFFF,d3 ; d3 = -1 * number of bytes to print I know this may look insignificant, but you know, perhaps not everybody knows about it or whatever :v * NOTE: I'm using the 1.42 (beta, build 92) version (Win32).
The error is because the System_Stack constant was not defined as a negative value, preventing AS from recognizing it can be sign-extended. This most likely happened because you defined it as a 32-bit (or less) hex value, whereas AS uses 64-bit arithmetic internally (because of other processors, most likely). Look at how the S2 and S&K disassemblies handle that for another way of making it work.
So, a double-post with an update: I found and fixed a nasty bug in the disassembler in one case of an illegal instruction which could cause the disassembler to overwrite a good chunk of RAM. I also went back at ASM68K, and managed to beat it into submission, so folks who can't (or won't, for some reason) switch to a less sucky assembler can now use a binary blob with a smidge of customizability. So, the links: For the full source: click here. For the binary blob: click here. Instructions for the source version are unchanged. For the binary blob, here is what you should do: First, configure ASM68K to output a listing. This is done by editing the build script; it should have a line that looks like this: Code (Text): asm68k /k /p /o ae- sonic.asm, s1built.bin >errors.txt Change it to this: Code (Text): asm68k /k /p /o ae- sonic.asm, s1built.bin >errors.txt, , sonic.lst If it already has the added bits, it was generating a listing file already, so you don't need to do this. Next, download the binary blob and extract it to a folder called "_debugger" in your disassembly; it will not be there by default, so you will have to create it (doh). Now include the blob includer: [68k] include "_debugger\DebuggerBlob.asm"[/68k] somewhere in your disassembly. Parts of this file can be edited: you can edit these lines: [68k] jmp (KosDec).l jmp (EniDec).l[/68k] to point to the correct targets, you can edit the variables HackerName, EMailmsg and Revision; read the comments before you edit them. Make sure to not change the spacing before stuff, of the blob will fail. Next step is to remove the old debugger (S1 only) or it will conflict with some names used in the blob. To do this, find the line [68k]BusError:[/68k] Then find this line: [68k]; End of function sub_5CA[/68k] and delete everything from the first line up until this line. It is now time to hook up the debugger. Find this: [68k]Vectors: dc.l $FFFE00, EntryPoint, BusError, AddressError dc.l IllegalInstr, ZeroDivide, ChkInstr, TrapvInstr dc.l PrivilegeViol, Trace, Line1010Emu, Line1111Emu dc.l ErrorExcept, ErrorExcept, ErrorExcept, ErrorExcept dc.l ErrorExcept, ErrorExcept, ErrorExcept, ErrorExcept dc.l ErrorExcept, ErrorExcept, ErrorExcept, ErrorExcept dc.l ErrorExcept, ErrorTrap, ErrorTrap, ErrorTrap dc.l HBlank, ErrorTrap, VBlank, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap[/68k] (HBlank may be with different name depending on how outdated a disassembly you are basing your work on) and edit it to match this: [68k]Vectors: dc.l $FFFE00, EntryPoint, BusError, AddressError dc.l IllegalInstrError, ZeroDivideError, CHKExceptionError, TRAPVError dc.l PrivilegeViolation, TraceError, LineAEmulation, LineFEmulation dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l SpuriousException, ErrorTrap, ErrorTrap, ErrorTrap dc.l HBlank, ErrorTrap, VBlank, ErrorTrap dc.l TrapVector, TrapVector, TrapVector, TrapVector dc.l TrapVector, TrapVector, TrapVector, TrapVector dc.l TrapVector, TrapVector, TrapVector, TrapVector dc.l TrapVector, TrapVector, TrapVector, TrapVector dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap dc.l ErrorTrap, ErrorTrap, ErrorTrap, ErrorTrap[/68k] The debugger should be working now, unless I forgot a step on the guide. Please let me know if I did and I will update it.
Slight bumping to report that when I attempted to use this, and built the game I got a ton of errors thrown in my face. My build.bat (using AS not ASM68K) states pretty much every offset table from NegX_Clr_Neg_Notmsgs and down presents an unknown opcode error. Not sure why, seeing as how the offset tables before that do not have such an error.
Have you tried using the new version of AS from the second post I made? I need to update the posts before to mention it.
Even using the new version of AS I get the same exact errors. Edit: Basically getting around 140 errors like this: Code (ASM): > > > OFFSETTABLE > > > NegX_Clr_Neg_Notmsgs: offsetTable > > >_inc/disassembler2.asm(3): error: unknown opcode > > > OFFSETTABLEENTRY > > > offsetTableEntry.w NegXmsg > > >_inc/disassembler2.asm(4): error: unknown opcode > > > OFFSETTABLEENTRY > > > offsetTableEntry.w Clrmsg > > >_inc/disassembler2.asm(5): error: unknown opcode > > > OFFSETTABLEENTRY > > > offsetTableEntry.w Negmsg > > >_inc/disassembler2.asm(6): error: unknown opcode > > > OFFSETTABLEENTRY > > > offsetTableEntry.w Notmsg > > >_inc/disassembler2.asm(14): error: unknown opcode > > > OFFSETTABLE > > > Reset_Nop_Stop_Rte_Rts_TrapV_Rtrmsgs: offsetTable > > >_inc/disassembler2.asm(15): error: unknown opcode > > > OFFSETTABLEENTRY > > > offsetTableEntry.w Resetmsg > > >_inc/disassembler2.asm(16): error: unknown opcode
Hm. AS generally emits this error only when the macro has not been defined (assemblers in general implement macros as pseudo-instructions).
But I'd assume that the macro is defined due to the rest not throwing errors at me... So what could possibly cause this?
Lets see: including the debugger before the macro definitions would be one, but I doubt this is it; hrm. See PM.
This is pretty awesome! I actually didn't even know about this until a few days ago; thanks for making this flamewing. A couple of things in the blob to note though (nothing too serious, but I guess should be mentioned): -The include for Part 1 doesn't point to the _debugger folder by default. -The 'Revision' label in the debugger is used already in sonic.asm (for Sonic 1, at least), perhaps it can use a different name, like RevisionNumber? Again, not serious problems at all (as they are fixable by anyone in a matter of seconds), but I felt they should be mentioned.
I updated the debugger blob version using these suggestions. The links above now download the new version, but you can just click here for convenience.