Amiga Monitor v1.60 instructions ================================ This is a machine code monitor/debugger program for the Amiga. The first version was created over 3 years ago, and many of the features and commands of the monitor were made similar to those of the monitors available for the Commodore 64. However, because the Amiga is a quite different machine many new commands and features were needed. Later versions of the monitor add many more useful features, as expressions and variables. This version is quite close to an actual symbolic debugger as it can read symbol table information from executable files and display them in disassembly listings. It also has a built-in script language. The monitor can be started both from CLI and from workbench. If you want to start the monitor from workbench, you must first make an icon for it. (starting the monitor from workbench is not recommended, because the programs that are run under the control of the monitor may require the CLI environment or else they may wait for workbench startup message forever...but you can use IconX to start the monitor from workbench as a CLI process) The monitor is re-entrant (pure) code and can be made resident (for example using the Workbench 1.3/2.0/3.0 resident command or ARP 1.3 ares) Command line arguments ---------------------- options: -w -h -o (see `Options Flags') -s (see `Scripts') An optional filename can also be given in the command line. The monitor will try to load the named executable file immediately after starting. The filename must be in quotes if it contains spaces. If there is anything on the command line after the file name, that will be used as the command line for the program loaded to the monitor (a0/d0 registers, see @-command) If a `+' character is used before the filename, the monitor tries to load symbol information from the file (see also `l'-command). Using the monitor from a remote terminal ---------------------------------------- The monitor can be used from a terminal connected to the Amiga serial port. If you want to do this, first set the correct baud rate and other serial settings using the preferences program. Then mount AUX: if necessary, and start a new CLI/Shell with the command NewShell AUX: (or NewCLI AUX:). You get the normal CLI/Shell prompt to the terminal. Now simply start the monitor by typing `mon' to the terminal (do not `run' the monitor from the terminal; if you do it, the monitor opens a window on the Amiga display). If the terminal is not vt100/ansi compatible, you may need to use the `Dumb Terminal' option flag (flag #3) to disable some features of the monitor (such as command line editing and history, but you can still delete the last character with backspace/delete). Easies way to do that is to start the monitor with the command `mon -o4'. Option flags ------------ Commands `opt +n' and `opt -n' where `n' is a number between 1 and 4 can be used to set and reset monitor option flags. Currently four flags are implemented: - flag #1 Switches on the narrow disassembly output mode (does not show the data as hex digits) - flag #2 Causes characters $a0-$ff to be considered printable in `m' command memory dump (and `?' command ascii display) (Note that this was changed in 1.42, previously they were printable by default). - flag #3 This is the `Dumb terminal' mode flag. When this is set on, the command line history and editing features of the monitor are disabled, and the monitor does not use any vt100/ansi- escape sequences. - flag #4 When this flag is set, the monitor echoes each command to its output window/file before actually executing the commands. This is mainly useful with scripts. - flag #5 Normally the monitor automatically resets the stack pointer to point to the normal stack area if it originally was out of range in the j/g/w/e/q-commands. This automatic stack reset can be disabled with this option flag. This is useful when debugging programs that allocate their own stacks and change the stack pointer there. The stack pointer can be reset manually with the rs-command. Command `opt' without parameters lists the current flag settins. This includes a hexadecimal `flag value' that can be used on the command line with the `-o' option to set initial flags when the monitor is started (That flag value is simply a bit map of the option flags, option #1 is bit #0). Input line editing and command line history ------------------------------------------- You can edit the input lines by using the left/right cursor keys to move left and right, backspace to delete the character before the cursor and del to delete the character under the cursor. You can use the up/down cursor keys to get the old command lines (the monitor remembers 10 last command lines). Shift-cursor-up gets the last command and enters it automatically (you don't need to press ). In assembler mode you can press Ctrl-E to edit the assembler instruction currently stored in that address. These features are not available if the `Dumb terminal' mode is selected. In that case the only editing function is deleting the last character with backspace or delete key. Stopping the output ------------------- In most cases the output of the monitor can be suspended by pressing SPACE or control-S and continued by pressing control-S or SPACE again. To permanently stop the output, press Ctrl-C. Numbers ------- Default number base is hexadecimal but it can be changed with the ba- command (the argument of the ba-command is always decimal). the prefixes used to identify number bases are: `$' hexadecimal `@' octal `%' binary `_' decimal Numbers can also be entered as ASCII strings in single quotes, for example: 'FORM' --> hex 464f524d Note that `+' was the decimal prefix in older versions. Now it is `_'. Expressions ----------- The monitor accepts expressions in most places where you need a number. The calculator (`?') command allows you to directly display values of expressions. The following operators are available: == equality tese != inequality test < less than these tests return 1 if true and 0 if false > greater than they are most useful in scripts <= less or equal than >= greater or equal than + addition - subtraction | bitwise or ^ bitwise exclusive or (xor) & bitwise and * multiplication / division (integer only, truncated) % modulo << left shift >> right shift parenthesis can be used to group the operations in the expressions. `*' represents the `current address'. [reg_name] represents the value of register `reg_name'. All calculations are done in 32-bit integer arithmetic. No overflow checking is done. Functions --------- The expression parser currently accepts the following built-in functions: hunk(n) -- start address of nth hunk of currently loaded seglist hlen(n) -- length of nth hunk of currently loaded seglist hend(n) -- end address of nth hunk of currently loaded seglist nhunks -- number of hunks in the currently loaded seglist abs(x) -- absolute value of a number peek(a) -- 8-bit contents of a memory location peekw(a) -- 16-bit contents of a memory location peekl(a) -- 32-bit contents of a memory location avail(x) -- call AvailMem() with the argument x. for example avail(0) returns total available memory, avail(2) returns available chip memory avail($20000) return largest available block. The following functions can be used to examine exec library, device, resource, task and port lists. Note that the pointers returned by these functions may become invalid any time if the library/device/task/port is expunged/removed from the system. lib("libname.library") -- returns base address of a named library. note that this does not try to load the library from disk, it only searches ExecBase->LibList. dev("devname.device") -- returns base address of a named device. note that this does not try to load the device from disk, it only searches ExecBase->DeviceList. res("resname.resource") -- returns base address of a named resource. task("taskname") -- returns pointer to named task. task(number) -- returns pointer to CLI process with the given number. task(0) -- returns pointer to current task (the CLI process that runs the monitor) port("portname") -- returns pointer to the public message port names "portname". board(manufacturer,product) -- returns base address of an autoconfig board with the specified manufacturer and product codes. lib, dev, res, task and port-functions fail with error if the requested library/device etc. is not found, unless option flag #6 is set. In that case they return zero in error situations. Function names are not case sensitive. Variables --------- In addition to numbers and functions, variables can be used in expressions if they have been previously defined. Variables are defined with the set-command. All variable values are 32-bit integers. Variable names can contain alphanumeric characters and underscores (`_'), but they cannot begin with a number. Variable names are case sensitive in this version. (There are some problems using variables with the assembler. Especially variables with names starting with `a',`d' or `s' may not be accepted in the assembler because it tries to interpret them as register names. You can get around this by using expressions like `0+variable') Byte strings ------------ Strings are used in the fill command, the hunt command, the modify memory command and the assembler directive dc.b . Byte strings are series of bytes, represented by numbers or ASCII- characters in single quotes or both together separated by commas. Note: the single quote itself may be included in a quoted string if it is duplicated. examples: 'this is a byte string' 12,34,56 '''' -- this means one single quote 'both',$0A,'text',10,'and','numbers' Special Note ------------ There is a problem with the walk (trace) command and several instructions that cause processor exceptions. These instructions are chk, trap #n, trapv and divu/divs (with divisions by zero). If you try to trace these instructions, a trace-exception occurs in supervisor-mode, out of the control of the monitor and you get a guru meditation alert with number 00000009. This problem was with the earlier monitor versions as well. Included with the monitor distribution is a program called patchtrace that changes directly the processor hardware trace-exception vector to point a new routine that removes the trap-trace problem. (The monitor does not support executing code in supervisor mode, so there is not normally any reason to trace any of the instructions that can cause problems. However, because you can accidentally cause the machine to crash by tracing these instructions, the patchtrace-program may be useful.) Stack usage ----------- The monitor allocates 2K of stack for its own use and the rest of the stack can be used by the program being debugged. If you need a larger stack, you can use the CLI `stack' command before you start the monitor. File/directory names -------------------- When the monitor requires a file or directory name or the device name for the `dev'-command, the name must be in double quotes if it contains spaces. This has been changed from the previous versions. Also, some escape processing is now done to the filename strings and the arguments of the echo-command. See the entry for echo-command for details. The following commands are available in the monitor --------------------------------------------------- h or the HELP key on the keyboard displays a list of commands. i -- Info displays a small info-message. o -- Redirect output usage: o name -- redirects monitor output to file or device `name' o -- returns to normal, output comes to the monitor window For example, to send the output to printer use `o PRT:'. If the file specified in the `o'-command already exists, the monitor output will be appended to the end of the file. ? [expr] -- Calculator Displays the value of the expression in hex, decimal, octal, binary and ASCII characters. If the number is negative, displays it as signed and unsigned. set [var[=expr]] -- Set/show variables The set-command without parameters displays the values of all currently defined variables. The form `set var=expr' sets the value of `var' to the value of the expression. `set var' removes the definition of `var'. cv -- Clear all variables Asks if you really want to do it, answer `y' to clear them. ba [num] -- Set/show current number base ba without parameters displays the current number base. ba [num] sets the base to [num] which is always decimal. this is the default base used in number input if no base prefix is specified. initially it is 16 (hexadecimal). mi [addr] -- Display information about memory locations The mi-command tells you if the address `addr' is in the system memory list, is it allocated or not and is it inside any of the hunks of the currently loaded segment. m -- Display memory in hex and ASCII Usage: m -- display 20 lines from current address m -- display 20 lines from m -- display from to If the memory display was started inside a hunk of currently loaded executable, it automatically stops at the end of that hunk. mf -- Formatted memory display Usage: mf "formatstring" mf "formatstring" mf "formatstring" This command displays memory in user-specified format. The format string can contain normal text that is printed directly and c-printf-style format specifiers. The following format specifiers are currently supported: %b -- hex byte %w -- hex word %l -- hex longword %db -- decimal byte %dw -- decimal word %dl -- decimal longword %a -- current address (in hex) %c -- ASCII character (printable ones only, others show as `.') %s -- string (longword pointer to a NUL-terminated string) %x -- BCPL string (longword pointer to a string with length byte) (non-printable characters in strings are printed as `.' Strings longer than 100 characters are truncated) The escape sequences described in the `echo'-command entry can also be used in the format string. Note1: words and longs that are displayed must be at even addresses. If the current address is odd when a word or longword value is going to be displayed, the address is incremented to the next even address and an asterisk is printed as a warning to the user. Note2: a space is required between this command and its arguments. : -- Modify memory Usage: : Puts the in memory at This can also be done with the command `a dc.b ' (but then must be even) f -- Fill memory with a byte or a string of bytes Usage: f ;fills with f ;fills with the string Example: f $60000 $601FF $4E,$71 fills from $60000 to $601FF with NOP-instruction t -- Transfer (move) memory Usage: t The command works correctly even if the source and destination memory blocks overlap. (if destination is at a higher address than source, the block is moved backwards, starting at the end) h -- Hunt (find) string in memory Usage: h Displays all addresses in the range .. where the is found. c -- Compare memory Usage: c Displays all addresses in the range .. where is corresponding byte in the destination block is different from the source. a -- Assemble usage: a : assemble to the current address a : assemble to a : assemble at After assembling an instruction the monitor prompts with the address of the location following the instruction just assembled and waits a new instruction to be entered. To exit this mode, simply press without entering an instruction. To edit an existing instruction, press Ctrl-E when the monitor is waiting an assembler instruction. The assembler understands all the normal 68000 instructions and also the `pseudo-instructions' dc.b, dc.w and dc.l, which can be used to directly put data in memory. Some notes about using the assembler: ------------------------------------- When entering assembler instructions which have an implicit size, no size specifier is allowed in the monitor assembler. These instructions are for example btst, bchg, bclr, btst, lea, move to/from sr/ccr/usp, andi/ori/eori #data,sr/ccr Scc (set according to condition), abcd/sbcd/nbcd and shifts with memory operands. Instructions that can have different sizes must have the size specifier, there is no `default size' (normal assemblers use a default size of word. The omission of default size is intentional, because it is so easy to forget the size specifier when you really don't mean the size to be word). Branch instructions with no size specifier or the .l-specifier assemble to normal (16-bit offset) branches, if given the .s-size specifier they assemble to the short form (8-bit offset). The dbxx-(decrement and branch) -instructions allow no size specifier. The assembler converts add/sub/and/or/eor with immediate data source automatically to adda/addi/subi/andi/eori. It does not convert move or add/sub to the quick form nor does it convert branches automatically to the short form. You must specify those yourself (so you must use the moveq/addq/subq- instructions or specify the size .s to branches as noted above). Also cmp-memory instruction must be entered as cmpm, the assembler does not convert cmp (an)+,(an)+ to cmpm. The above conversion rules do not apply to andi/ori/eori with status register or condition code register. In these cases you must enter the instruction as andi/ori/eori (don't leave the `i' out). Also, you can't enter any size specifier in this case. (In fact I want to make the assembler more flexible than it currently is, but that is not an easy task...maybe in some future version...) d -- Disassemble Usage: d -- disassemble 20 lines from current address d -- disassemble 20 lines from d -- disassemble from to If the disassembly was started inside a hunk of currently loaded executable, it automatically stops at the end of that hunk. r -- Show or change registers Usage: r -- displays all registers r = or r -- puts the value into examples: r D0=0 r A5 $60000 b -- Set breakpoints Usage: b [count] -- sets a breakpoint to with optional count Breakpoints are implemented by putting an illegal opcode ($4AFC) in the breakpoint locations when a G or J command is given. After returning to the monitor the original contents of the breakpoints are restored. This means that you can not put breakpoints to ROM (but you can trace ROM code). If no count is specified, default count of one is used. That means that the execution of a program stops and control returns to the monitor immediately when the breakpoint is encountered. If the breakpoint has a count that is greater than one, then control returns to the monitor when the breakpoint has been `hit' as many times as the count is. Breakpoint counts do not work with the `q' (quicktrace) command. br -- Remove breakpoints usage: br -- removes the breakpoint at br all -- removes all breakpoints bl -- List breakpoints Usage: bl -- display a list of all breakpoints. The g, j, w, q and e-commands use the current program counter value (displayed with the r-command) if you don't give them an address. The stack pointer is reset and a return address to the monitor is put in the stack if the stack pointer is out of range. This automatic stack pointer reset can be disabled with option flag #5. The stack pointer can be manually reset with the 'rs'-command. g [addr] -- Go (execute machine code) j [addr] -- Jump to subroutine As g-command but pushes return address first. this return address will give control back to the monitor when rts-instructions is executed. w [addr] -- Walk (single step trace) This single steps code using the 68000 processor built-in trace mode. It works even with ROM code (but the e-command doesn't). (This command does not activate breakpoints) e [addr] -- Extended trace (execute with temporary breakpoint) This command allows you to execute subroutine calls in full speed when tracing and you don't need to manually place a breakpoint after the calls. when the e-command is executed, a temporary breakpoint is placed in the location after the instruction to be executed. this break- point is automatically removed after the control returns to the monitor. The e-command can be used instead of the w-command to trace most of the instructions, but it is recommended that you use the w-command for tracing and when tracing code until you get to a subroutine call instruction. then enter the e-command and the subroutine is executed normally, but after that the monitor interrupts execution to the invisible breakpoint. Note that if you use the e-command in an address that contains a flow- control instruction, the code flow may never come to the temporary breakpoint. Normally it is better to trace using the w-instruction, but for example, system calls cannot always be traced, and even if they can, you most probably don't want to do it. In previous versions of the monitor you had to manually insert a breakpoint after the call and use the g-command. Now you can simply use the e-command. q [addr] -- QuickTrace (execute until flow-control instruction) This command executes code one instruction at time (in the 68000 trace mode) until it