Documentation of the ATARI F030 DSP56001 Debugger. V1.00 (15-oct-1992). V1.01 (21-nov-1992) V1.02 (7-feb-1993) V1.03 (1-mar-1993) V1.04 (17-mar-1993) V1.05 (6-apr-1993) V1.06 (9-may-1993) V1.07 (21-sep-1993) General Interface Overview: There are two types of windows, the list windows and the action windows. The list type is used to display: registers, disassembly, memory, stack, breakpoints and variables. The action type is used to: load to memory, set preferences, copy memory, fill memory, send file, receive file, evaluate expression, set or edit breakpoint, lock window, goto address/memory find word and replace word. A list window can be closed, moved, resized and fulled as the usual way. An action window can be closed and moved as the latter. The fuller button is used to reset the window to its old position. The close button acts always as a Cancel button. The default button can be selected with the Return key, in wich case the action is done, and the window remains opened. If the Enter key is pressed, then the action is done and the window is closed. The same features can be done with the mouse: a single click is equivalent to the Return key, and a double-click to the Enter key. If there are other buttons in the window, some are radio-buttons, some are check buttons and some are other action buttons. They never close the window. Almost all editable textfields in action windows do scroll. All those fields accept regular expression for evaluation (see The Evaluator appendix for regular expression syntax). All the debugger functions are accessible through entries in menus. You will find the functions description below. At one time, some menu entries can be disabled because they make no sense in the current context. Mainly, when the program is running, all context actions (except Halt): Trace Into, Trace Over, Skip, Run are disabled. The Halt and Host Command functions are selectable. When the program is stopped, the first four entries are selectable, and the last two are disabled. Same thing for context buttons in Disassembly windows. Deeper in Debugging Techniques: If you use the linker to output the LOD file, you will get the symbols automatically. Otherwise, if you use the assembler directly, use asm56000 -a -b source.asm and the cld2lod utility. You will also have all the symbols if you use the CLD file (which is a faster way to debug). Variable names are generated up to 20 characters. You cannot halt the DSP if the debugged program IPL is higher than 2. You have no need to change the default IPL level (2), anyway. Note that you can freely be in IPL0, IPL1 or IPL2 as the debugger polls to communicate with its remote part. By the way, you should start your program by setting the HCIE bit of HCR (DSPDebug forces it anyway). You cannot predefine code between: P:2 to P:7, Stack Error, Trace Exception, SWI Exception P:$1e to P:$1f, NMI exception P:$3e to P:$3f, Illegal exception P:$7e00 to $7eff, Remote part of DSPDebug X:$ffff to X:ffff DSP ISR Your program shouldn't use the previous vectors for any purpose when debugging. For the moment, DSPDebug doesn't check for those addresses when copying, filling, loading to memory, setting memory by the evaluator ... Changing HCR during program execution is left to the programmer's responsibility, except for the HF2 and HF3 bits. The HCR flags configuration HF2=1 and HF3=1 are used by the debugger to communicate with its remote part, as well as the HSR flags configuration HF0=1 and HF1=1. Same thing for the OMR bits 0 and 1, which enable the Host Interface. Remember that the remote debugger uses one stack level when called by the DSP to handle an exception, or if asked for a Host Interrupt. If there is no space on the stack for the exception, a Stack Error exception will occur, and the stack will be reinitialised. This is a difference between running under the DSP driver and the DSP Debugger, as you have one stack level less. You can use SWI in your program in order to stop it at some point, in the same way as the illegal 680x0 instruction. But note that since the SWI exception has a lower priority than the Trace exception, the DSP CPU will ignore a SWI instruction during a Step Into command. Please read carefully the DSP manual on page 8-14: - you can't trace fast interrupts (nor put breakpoints into). - if you trace while having fast interrupts occuring, then you have different cases: - your interrupt is set in the IPR at IPL > 2. Then you won't be able to halt your program. - in any case, you have 2 choices if you want to step: you will be stuck to the instruction following the interrupt enabling. you can step without any problem, but no interrupt will occur. One can grab the current DSP context by holding the control key when launching the debugger or with '-g' in command line. This means that the debugger will not make a hardware reset of the DSP, nor it will upload the remote code into the DSP. Obviously, the debugger must have been run at least once before grabbing context. If you have the "DSP is not responding" message, you've lost. Software functions description: DSPDebug menu: Informations Display interesting things as well as the current free memory. The latter is real time updated and displayed in the window. File menu: Open LOD Load a LOD file from disk and upload it in the DSP. The program start address can be set to any address, using the END statement in the assembler. ex: ORG p:0 Start: jmp Main ;you MUST begin in 0 if you want to be launched ;by the DSP driver functions DspExec... ;DSPDebug allows starting from anywhere wich is ;not a restricted area ORG P:$10 nop nop ORG P:$200 Main: nop nop ... END Start The line 'END Start' tells the debugger that the program start address is the Main function. The default start address of a LOD file is, of course, the lowest address. For more information about the LOD format, read the MOTOROLA DSP Assembler documentation. The debugger handles P, X, and Y initialized and non-initialized datas. Warnings: "Warning in file "+ "No _END directive before EOF" Self explicit. "No _DATA directive before EOF" Self explicit. "Tab used" The caracter TAB is used as a separator instead of space. This will eventually lead to problems with DspLoadProg (not with DspDebug anyway). Error messages: "Error in file "+ "File is empty" File has a length of zero. "No _START directive" File has no "_START" directive, and so is not likely to be a LOD file. "Unknown RAM specification" A memory specification different from P, X, Y and L is used. "Bad number format" A number which is not of the form FFFF (hexadecimal radix) is used. "Bad number size" A number that exceeds a word size (24 bits) is used. "Bad line size" A line containing more than 10 words is used. "Memory access violation" The program uses vectors which are reserved by the debugger. "Invalid RAM address" A RAM address exceeding the preferences sizes is defined. "Invalid block size" A block size exceeding the preferences sizes is defined. "Space or tab expected" Couldn't find a valid separator. Open CLD Load a CLD file from disk and upload it in the DSP. Same remarks as above. Warnings: "Unknown optional header. Skip it?" Optional header should be of RUN type. DSPDebug is able to load it anyway, but the start of the program will be at P:0. "Unknown section type. Skip it?" A section type is found which is not understood by DSPDebug. This should not prevent normal debugging (please send us such a file). Error messages: "Read error" Self explicit. "Wrong machine implementation type" You tried to load a non-CLD file or a CLD for another processor type. "File must be executable" You tried to load a non-absolute CLD (maybe a CLN?). "Seek error" This probably means that the file is corrupted. "Bad sections number" Your program has a negative or null number of sections. "Memory error" Not enough memory for temporary load buffers. Restart program Reloads and restarts the currently debugged LOD or CLD program. Load ASM Load an ascii file in a window. This is mainly used to load a source file. Load to memory Load a file in memory. This allows to load a file into the DSP memory. Save from memory Save a file from memory. This allows to dump part of the DSP memory. If the file already exists and the expert mode is not set, you will be warned before overwriting the previous file. Preferences Indicates the available P, X and Y ram sizes on the DSP. They are used in memory windows, and for the search loop. Autosave desk: automatically save current windows configuration at quit time. Autoload desk: automatically load DEFAULT.DSK windows configuration at launch time. Set expert mode: skip one-way alerts and less important warnings: - when quitting the program: "Do you really want to quit?" - when loading a LOD file: "Warning. No _END directive before EOF", "Warning. No _DATA directive before EOF", "Warning. Tabs used.", - when loading a CLD file: "Unknown optional header. Skip it?" will skip "Unknown section type. Skip it?" will skip - when deleting a breakpoint: "Delete breakpoint ?" - when reaching a breakpoint: "Breakpoint reached at $xxxx" - when writing on disk "File already exists. Overwrite ?" Set in-line help mode: options which are described in the bottom help line are indicated by changing the mouse cursor to a magnifier. In-line help texts are displayed at the bottom of the screen. Load source: The program source will be loaded together with the LOD or CLD file. Interrupt DSP: When the DSP is running, any action requesting communication with it will be serviced. Tab size: is used in disassembly and source windows. Set help path: this is where DSPDebug will search for help files (*.HLP). Default is current directory. Save desktop Save current windows configuration. Load desktop Load a windows configuration. Print top window Prints the top window to an ASCII file. Quit Exit the DSP Debugger Edit menu: Copy memory Copy memory. It manages overlapping memory blocks. Fill memory Fill memory. "Increment" is added to fill value at each loop. Start address is incremented by fill size after completion. Modify Modify breakpoint selection settings. If running, the changes will occur at the next context switching. Delete Delete selection in breakpoints window. If running, the changes will occur at the next context switching. Delete all Delete all breakpoints in breakpoints window If running, the changes will occur at the next context switching. Context menu: Trace into Single steps current instruction. When running, this option is disabled. Use Halt to break program execution. Trace over Sets a breakpoint on the next instruction, and run. Useful for JMP, JScc or DO LOOP. When running, this option is disabled. Use Halt to break program execution. Skip Skips the current instruction (sets the PC to the next instruction). When running, this option is disabled. Use Halt to break program execution. Run Starts program execution from the current instruction. When running, this option is disabled. Use Halt to break program execution. Halt Halts the program with a NMI exception. If not running, this option is disabled. DSP Reset Hardware reset of the DSP. Whether the program is running or not, it hardly resets the DSP and reuploads the remote debugger part. It restores software and hardware registers. It resets the context states. Send Host Command Requests the given interrupt vector. If not running, this option is disabled. Send to Host Sends a binary words file to the DSP (by the host port). Data can be 1 word = 3 bytes or 1 word = 4 bytes. Receive from Host Stores all words sent by the running program (by the host port). Data can be truncated or padded to any byte(s) per word combination. Matrix set Sets the Matrix according to the developer's documentation. Changes are context-dynamic. This box is the only way to access the matrix. An example of SSI program is given. For an basic use, set the buttons ADC->DSP and DSP->DAC. NB: - due to the way the DevConnect is implemented in the system, it seems that it is not possible to remove a connection once it is set. You must then reset the Codec if you want to clear a connection, so don't rely on the display if you don't remember what you have really selected. - begin matrix work by resetting codec. Actions menu: Evaluate exp. Evaluates a regular expression, display the result in hexadecimal, decimal and fractional form. See the Evaluator appendice for details on regular expression syntax. Goto Goto (P ram) address in disassembly windows. Goto address and ram in memory windows. Goto line in ASCII windows (ASM and source). Error message: "Wrong line number" You have entered a (long) negative line number or it does exceed the window's maximum line number (which is the file's one). Lock window Lock a disassembly or memory window address with an expression/ram. To unlock the window, enter an empty expression. Set break Set a breakpoint with the following parameters: - address: where the breakpoint will be set in P ram. - count: decremented at each breakpoint hit. The context is rerun if count!=0. - expression: evaluated at each breakpoint hit. The context is rerun if the evaluation doesn't return true (1L). Another way of setting breakpoints: clicking on the leftmost character in a disassembly window will toggle standard breakpoints. Search Search for word value in memory. Loop through the specified ram and from the specified address, searching the "what" word value. If it reaches the top of the memory (as indicated in the preferences), it restarts from the beginning. It stops when the search start address is reached. Replace Search for word value in memory and replace with another. Windows menu: Registers Displays DSP 56001 registers. Please refer to the Help or DSP Manual. Single-clicking on registers names (bold) directly brings an evaluate window (setup for setting a new value for that register). Single-clicking on a bit name (like T for instance) toggles the bit's state. Single-clicking on a bit combination (like I) cycles up its value. Disassembly Displays P ram in assembly code. Line format:(between [] means optional) [Check]
[pc marker]<[operand][operand]...>[Cond] - [Check] sign ( or $8) indicates a breakpoint at this address. One can double-click on the sign in order to edit the breakpoint. It is also possible to remove it by clicking on the sign, or set one by clicking on the space. If you double-click on a space, a breakpoint will be created at this address and a breakpoint editing window will be opened. -
is the disassembly line address in P ram (16 bits). If there is a label at this address, its name will be displayed on one line, with the disassembly line following. If there is more than one label, they are displayed one after the other. - is only a (visual) separator. - [pc marker] indicates if the PC register points to this line of code. It can be: - (Up arrow), instruction branches upward. - (Down arrow), instruction branches downward. - (Right arrow), instruction is not a branch instruction. -? (Question mark), instruction branches on memory value. Memory is not tested to avoid disturbing I/O processing. - is the instruction opcode. Help on it is available in-line or by double-clicking on it. - allows the alignement of same types of data The tab value is set in the preferences. - [operand] is one of the instruction's operand. If it contains an I/O register (X:$ffe? or X:$fff?), its name is printed instead of its value, according to the following table: PBC is $ffe0 ;Port B Control register PCC is $ffe1 ;Port C Control register PBDDR is $ffe2 ;Port B Data Direction Register PCDDR is $ffe3 ;Port C Data Direction Register PBD is $ffe4 ;Port B Data register PCD is $ffe5 ;Port C Data register HCR is $ffe8 ;Host Control Register HSR is $ffe9 ;Host Status Register CRA is $ffec ;SSI Control Register A CRB is $ffed ;SSI Control Register B SSISR is $ffee ;SSI Status Register SSITSR is $ffee ;SSI Time Slot Register RX is $ffef ;SSI Serial Receive data/shift register TX is $ffef ;SSI Serial Transmit data/shift register SCR is $fff0 ;SCI Control Register SSR is $fff1 ;SCI Status Register SCCR is $fff2 ;SCI Clock Control Register STXA is $fff3 ;SCI Transmit data Address Register SRX is $fff4 ;SCI Receive data register (4-5-6) STX is $fff4 ;SCI Transmit data register (4-5-6) BCR is $fffe ;Port A Bus Control Register IPR is $ffff ;Interrupt Priority Register You can double-click on one to get the help information on it. If the operand contains an address, it will be underlined. Double-clicking on it will bring the current window to its address if in P memory, otherwise it will open a new dump window at this address/memory. - [expr] the breakpoint expression set at this address, if any. Note: the end of loop address of a DO LOOP instruction is incremented by 1 in the display, to allow the symbol address matching. Buttons: I: Trace Into O: Trace Over S: Skip R: Run H: Halt PC: If selected, locks the window with the PC Memory Displays P, X, Y, or L ram in hexadecimal or fractional base. (You can't use fractional base in L ram.) Buttons: P: Selects P ram X: Selects X ram Y: Selects Y ram L: Selects L ram H: Displays in hexadecimal radix F: Displays in fractional form Stack Displays the 15 SSH and SSL. The current level of the stack is indicated by an horizontal line. That means the initialized stack is from SSH1-SSL1 to the horizontal line. Breakpoints Displays the breakpoints list. You can scroll the cursor, and double-click or press return on one to change its settings. Source Displays the program source (currently works only with the first file: will be changed for CLD files). Variables Displays the variables list. You can scroll the cursor, and double-click or press return on one to set the last window directly to the variable address. The display is alphabetical. Equates variables will be shown with no memory type. Host regs Edit DSP Host registers Changes are context-dynamic. SSI regs Edit DSP SSI registers Changes are context-dynamic. Close window Closes current window. Cycle window Cycles through the program windows list. Help menu: Index Back Registers Assembly Host SSI Assembler (Not finished) Linker (Not yet) User The Help modes: There are two kinds of help: -the in-line help, which is displayed at the bottom of the screen if the In-line Help flag is set in the preferences. This help mode provides on line upon each menu title and entry, each active object in action windows, and each window button. It also gives a short definition for software and hardware registers, and for instructions. -the window help, which provides a full explanation upon the topic chosen by a single click on a bold word (in registers, disassembly and help windows). One can add his own help by editing the usrndx.hlp and usrdta.hlp files. The help text format is fully described inside. General error messages: "DSP is not responding" means that the debugger has asked the remote part in the DSP to make some action, and that it does not perform it. Usually, this is lethal. You'd better choose the Reset button. "Unexpected send event" generally means that the remote DSP code is hang. It usually follows or precedes a "DSP not responding" alert box. "Unexpected context event" means that, by some means that you must reveal to us, you have reentered the context switching. This should NOT happen. Appendixes: I - The Evaluator: -variables: A variable name cannot begin with a digit. It can only include characters, digits and underscores(_). If you want to use the content of a variable instead of its value, you must preceed it with the indirection operator '*'. ex: *dummy= $4 The evaluation is always case-dependent. Equates always need memory indicator (X: for instance). -constants: They are coded on 32 or 64 bits. They can be written in decimal (ex: 123), in hexadecimal (ex: $1FC3), in binary (ex:%101) or fractional (ex: .123, 100e-3). -registers: Every register used in DSP addressing modes can be written. ex: ( A, AB, A10, MR, SR, A2, etc...) -adresses: Access to a memory location is made in a 56001 syntax: X:$1234 accesses to X ram at location $1234. -operators: (sorted by priority) - Add: + - Substract: - - Multiply: * - Divide: / - Rest (modulo): % - And bit to bit: & (This operator can't be used with fractional) - Inclusive Or: | (This operator can't be used with fractional) - Exclusive Or: ^ (This operator can't be used with fractional) - Not bit to bit: ~ (This operator can't be used with fractional) - Right shift: >> (This operator can't be used with fractional) - Left shift: << (This operator can't be used with fractional) - Logical Not: ! - Logical Or: || - Logical And: && - Equal: == - Not Equal: != - Higher: > - Lower: < - Higher or Equal: >= - Lower or Equal: <= - Set: = the left operand must be a variable, an address or a register. ex: (dummy = 3, x:$200 = 45, PC = $41, x:(r0 + 10) = $DEAD) In that case, the variable doesn't need the indirection operator (its content will be set automatically). Equates must have a memory type indicator (like X:). Other variables already contain their memory type. - Unary Plus: + - Unary Minus: - - Indirection: * - Block start: ( - Block end: ) -error messages: "Bad expression syntax" This is a Panic message, when nothing has been identified. "Invalid memory" The evaluator couldn't set or get a memory value. "Memory required" You didn't indicate a memory type for accessing an equate, like: IPR=$45 instead of: X:IPR=$45 "Incomplete expression" You didn't set the close parenthesis, for instance. "Constant overflow" The constant given is too big. "Address overflow" The address given is too big. "Unknown label" The label you typed in doesn't exist. "Incompatible operator" You tried to shift a fractional number, for instance "Fractional overflow" The computed fractional number is too big. "Divide by zero" The computed result leaded to a divide by zero, like: 4/(2-2) "L-value required" You tried to set a non pointer, like: $123=0 instead of: Y:$123=0 "Not implemented" Not implemented message. II - How to communicate with the DSP Debugger: As shown in the source example contained in the MSGEX folder, an accessory (or a program, under MultiTOS) can receive the DSP data from the Host Port via the debugger and gem-pipe messages. Here is the method to do so: #define DSPDEBUG_MESAG 127 typedef enum { START_RECEIVE=0, END_RECEIVE=1 } DSPDEBUG_CMD; /* appl_find the DSP Debugger: (for instance at program start) */ DSP_DebugId=appl_find("DSPDEBUG"); /* appl_write to the DSP Debugger that you are ready to receive: */ msg[0]=DSPDEBUG_MESAG; msg[1]=DSP_DebugId; msg[2]=0; msg[3]=START_RECEIVE; appl_write(DSP_DebugId,sizeof(msg),msg); /* and then through the event loop, check for a DSPDEBUG_MESAG message et get the word from the pipe: */ if (evnt&EVNT_MESAG) { if (msg[0]==DSPDEBUG_MESAG) { DSP_word=((long)(msg[3])<<16)+msg[4]; /* do stuff with it ... */ } } /* when you want to finish the pipe: (for instance at program end) */ msg[0]=DSPDEBUG_MESAG; msg[1]=DSP_DebugId; msg[2]=0; msg[3]=END_RECEIVE; appl_write(DSP_DebugId,16,msg); Brainstorm.