DEVPAC 2 PART 2 See part one for who did what. PARASITE CHAPTER 4: SYMBOLIC DEBUGGER INTRODUCTION Programs written in assembly language are particularly error- prone because even a slight mistake can result in the entire machine crashing. There are various forms of bugs, ranging from the trivial (e.g. a missing CR in a printout), though the usual (e.g. an incorrect result_ to the very serious (e.g. the machine completely hanging, perhaps with a weird display). To help you find and correct all forms of bugs, Devpac includes MonAm. MonST is a symbolic debugger and disassembler which lets you examine programs and memory, execute programs an instruction at a time and trap processor exceptions caused by programmer error. As MonAm is symbolic you can look at your program complete with all the original labels, making debugging very much easier than having to battle with 6-digit hex numbers (or 8 digits on the 68020!). Although MonAm is a low-level debugger, displaying such things as 68000 instructions and bytes of memory, it can also be used for debugging programs written with any compiler that generates machine-code output. If the compiler has the option to dump the symbols into the binary code then you will see your procedure and function names within the code, and you can even view your original source code. As MonAm uses its own screen (in the Amiga sense), if you are debugging a program with windows your program will not be sent re-draw messages whilst you are using the debugger. Many other Amiga debuggers do send these messages - it can be very confusing. EXCEPTIONS MonAm uses the 68000 processor exceptions to stop runaway programs and to single-step, so at this point it would be useful to explain them and what normally happens when they occur on an Amiga. There are various types of exception that can occur, some deliberately, others accidentally. When one does occur the processor saves some information on the SSP, goes into Supervisor mode and jumps to an exception handler. On the Amiga these normally produce a software error tash held system requester, or the dreaded guru, but when MonAM is active it re-directs some of these exceptions so it can take control when they occur. The various forms of exceptions, their usual results, and what happens when they occur with MonAm active is shown in the following table: No. EXCEPTION MONAM ACTIVE 2 bus error trapped 3 address error trapped 4 illegal instruction trapped 5 zero divide trapped 6 CHK instruction trapped 7 TRAPV instruction trapped 8 privilege violation trapped 9 trace single stepping 10 line 1010 emulator trapped 11 line 1111 emulator trapped 32 trap #0 to #15 trapped The exact causes of the above exceptions (and how best to recover from them) are detailed at the end of this section, but to summarise: Exceptions 2 to 8 are caused by a programmer error and are trapped by MonAM. Exception 9 can remotely be caused by programmer error and is used by MonAM for single stepping. The rest (i.e. Trap instructions) are diverted into MonAm, but can subsequently be re-defined to be exploited by programs if required. Occasionally very nasty crashes can cause the whole screen to fill with colourful garbage, which looks very impressive, but is not very useful! INVOKING MONAM Monam is invoked by typing the command monam2 (RETURN) This can optionally be followed by a program name, and a command line to be passed to it. For example: monam2 c:genam2 examples/demo.s (RETURN) will cause Monam to be invoked, to in turn load genam, and pass a filename to it. When Monam has loaded, the screen will display three windows in which all Monam information is displayed. Immidiatly after loading the prompt enter program name or press return: will appear. At this point you have to choose weather you are going to debug a particular program, or just have a look around memory. DEBUGGING A PROGRAM If you wish to debug a specific program, you should enter it's filename including drive and directory if required and Manam will try and load the program. If it fails, it will display: AmigaDOS error xxx and you can use the (CTRL)-L command to try again. Assuming the filename is valid, monam will load it. it will also check for any symbols within a file. After a succesful load, the prompt enter command line: will appear and you may type in a command line thet will be passed to the program being debugged in the standard way. If you don't want a command line, press return alone. The message Exception:Breakpoint will appear together with the front panel display. It says Breakpoint because Monam places a breakpoint at the first instruction of the program then executes it. MONAM & MULTI-TASKING the Amiga is a multi-tasking machine, and this imposes some restrictions on what monam can do. Having loaded a program (or task) into it, that task is suspended. This means it is waiting, in this case for a Monam command to let it continue. The other state the task can be in is executing - that is it is running at the same time. Some commands require one of these states to operate - for example you can only single-step a task that is suspended. if it is running you will get the error 'Task must be suspended!' when you try. EXAMINING MEMORY If you are just interested in looking at memory, press (RETURN) and you will see the front panel display, and get the command: prompt. SYMBOLIC DEBUGGING A major feature of MonAm is its ability to use symbols taken from the original program whilst debugging. MonAm uses standard AmigaDOS file SYMBOL hunks as produced by most Amiga programs that produce executable files, such as linkers, compilers and GenAm. MONAM DIALOGUE AND ALERT BOXES MonAm makes extensive use of dialogue and alert-boxes which are similar in concept to those in intuition programs but have several differances. A Monam dialogue box displays the prompt ESC to abort above the top left corner of the box together with a prompt, normally followed by a blank line with a cursor. At any time a dialogue box may be aborted by pressing Esc, or data may be entered by typing. The cursor keys, Backspace and Del keys may be used to edit entered text in the usual way and the whole line may be delted by pressing the (AMIGA)-X key combination. An entered line is terminated by pressing the Return key, though if the line contains errors the screen will flash and the Return key will be ignored allowing correction of the data before pressing Return again. A MonAM alert box is a small box displaying a message together with the prompt (Return) and is normally used to inform the user of some form of error. The box will disappear on pressing the Return or Esc keys, whichever is more convenient. INITIAL DISPLAY Unless you have chosen the Debug option within the editor you will be presented with a dialogue box prompting for an executable program name. If you wish to debug a program from disk you should enter the filename (which defaults to an extension of .PRG) then press Return, then you will be prompted for any command line. If you do not wish to debug a program from disk at this stage, for example you wish to investigate memory, press the Esc key or enter a blank filename. FRONT PANEL DISPLAY The main display of MonAm is via a Front Panel showing registers, memory and instructions. The name Front Panel stems from the type of panels that were mounted on mainframe and mini computers to provide information on the state of the machine at a particular moment, usually through the use of flashing lights. These lights represent whether or not particular flip-flops (electronic switches) within the computer are open or closed; the flip-flops that are chosen to be shown on this panel are normally those that make up the internal registers and flags of the computer thus enabling programmers and engineers to observe what the computer is doing when running a program. So these are hardware front panel displays; what MonAM provides you with is a software front panel - the code within MonAm works out the state of your computer and then displays this information on the screen. The initial MonAm display consists of three windows: The top window (number 1) displays the values of the data and address registers, together with the memory pointed to by these registers. The next window (number 2) is the disassembly window which displays several lines of instructions, by default based around the program counter (PC), shown in the title area of the window. A => sign is used to denote the currant value of the PC Window number 3 is the memory window which displays a section of memory in word-aligned hex and ASCII. One of the most powerful features of MonAm is its flexibility with windows - up to 2 additional windows may be created, the font size can be changed, and windows may be locked to particular registers, these features are detailed later. SIMPLE WINDOW HANDLING MonAm has the concept of a current window - this is denoted by displaying its title in black. The current window may be changed by pressing the Tab key to cycle between them, or by pressing the (AMIGA) key together with the window number, for example (AMIGA)-2 selects the disassembly window. NOTE: If your typing seems to be ignored in MonAm don't be alarmed, it means that another window is active, such as your programs. To correct this clich on any part of the MonAm display. you can always tell when the monAm window is active because the mouse pointer will be bug shaped. COMMAND INPUT MonAm is controlled by single-key commands which creates a very fast user-interface, though this can take getting used to if you are familiar with a line-oriented command interface of another debugger. Users of HiSoft Devpac on other machines will find many commands are identical, particulary with the Spectrum and QL debuggers, though the window commands are unique to MonAm. The commands are almost identical to DEVPAC ST version 2. In general the (AMIGA) key - when used in conjunction with other keys it it acts on the current window. Commands may be entered in either upper or lower case. Those commands whose effects are potentially disastrous require the Ctrl key to be pressed in addition to a command key. The keys used where chosen to be easy to remember, wherever possible. Commands take effect immediately - there is no need to press Return and invalid commands are simply ignored. The relevant sections of the front panel display are updated after each command so any effects can be seen immediately. MonAm is a powerful and sometimes complex program and we realise that it is unlikely that many users will use every single command. For this reason the remainder of the MonST manual is divided into two sections - the former is an introduction to the basic commands of the program, while the latter is a full reference section. It is possible for new users and beginners to use the debugger effectively while having only read the Overview; don't be intimidated by the Reference section. MONAM OVERVIEW To start with you will need to load a program to debug; if you have assembled a program to memory you can use the Debug option of the assembler or linker. The most common command in MonAm is probably single-step, obtained by pressing Ctrl-Z (or Ctrl-Y if you find it more convenient). This will execute the instruction at the PC, the one shown in the Register window and, normally, also in the Disas sembly window. After executing it the debugger re-displays the values of the registers and memory displayed, so you can watch the processor execute your program, step by step. Single-stepping is the best way of going through sections of code that are suspect and require deeper investigation, but it is also the slowest - you may only be interested in a section of code near the end of your program which could take ages to get to if you have to single-step all the way. There is, of course, an answer. A breakpoint is a special word placed into your program to stop it running and enter MonST. There are many types of breakpoint but we will restrict ourselves to the simplest for now. A breakpoint may be set by pressing (AMIGA)-B, then entering the address you wish to place the breakpoint. You can enter addresses in MonSt in hex (the default base), as a symbol, or as a complex expression. Examples of a valid address are 1A2B0, prog_start, 10+mydata. If you type in an invalid address the screen will flash and allow you to correct the expression. Having set a breakpoint you need some way of letting your program actually run, and Ctrl-R will do this. If will execute your program using the registers displayed and starting from the PC. MonST will be re-entered if a breakpoint has been hit, or if an exception occurs. MonAm uses its own screen display which is independent from your own programs. If you press the v key you will see your current programs display, pressing another key switches you back to MonST. This allows you to debug programs without disturbing their output at all. MonAm uses its own windows to, and any window may be zoomed to the full screen size by pressing (AMIGA)-Z. To return to the main display press (AMIGA)-Z or the Esc key. The Esc key is also the best way of getting out of anything you may have invoked by accident. The Zoom command, like all (AMIGA)- commands, works on the current window which you can change by pressing Tab. You can dump the current window to your printer by pressing (AMIGA)-P. To change the address from which a window displays its data, press (AMIGA)-A, then enter the new address. Note that the disassembly window will always re-display from the PC after you single-step, because it is locked to the PC. The locking of windows is detailed in the Reference section. To quit MonAm press Ctrl-C. This returns Monam directly to the CLI. If the task you are debugging is still running or suspended when you try and quit, you will be warned. If Monam terminates while the task under investigationis running, the machine will crash if any execption occurs subsiquently. A safer way is to use the ctrl-Q command to stop the task first. If you used the Debug option from the editor then Ctrl-C will always terminate MonAm as well as your program. We hope this overview has given you a good idea of the most common features of MonST to let you get on with the complex process of writing and debugging assembly language programs. When you feel more confident you should try and read the Reference section, probably best taken, like all medicine, in small doses. MONAM REFERENCE NUMERIC EXPRESSIONS MonAm has a full expression evaluator, based on that in GenST, including operator precedence. The main differences are that the default base is hexadecimal (decimal may be denoted with a \ sign), there is no concept of types of expressions (relative or absolute), ø is used only for multiplication and there is a not- equals operator, <>. Symbols may be referred to and are normally case-sensitive and significant to either 8 or 22 characters (depending on the form of debug used), though this can be changed with the MonAm Preferences command. Registers may be referred to simply by name, such as A3 or D7 (case insensitive), but this clashes with hex numbers. To obtain such hex numbers precede them with either a leading zero or a $ sign. A7 refers to the user stack pointer. There are several reserved symbols which are case insensitive, namely CODE, SP, SR, and SSP. SP refers to either the user- or supervisor-stack, depending on the current value of the status register. CODE refers to the first in the program. This is the same as HUNK1. The second hunk is HUNK2 and so on. In addition there are 10 memories numbered M0 through M9, which are treated in a similar way to registers and can be assigned to using the Register Set command. Memories 2 through 5 inclusive refer to the current start address of the relevant window and assigning to them will change the start address of that window. The MonAm expression evaluator also supports indirection using the { and } symbols. Indirection may be performed on a byte word or long basis, by following the } with a period then the required size, which defaults to long. If the pointer is invalid, either because the memory is unreadable or even (if the word or longword indirection is used) then the expression will not be valid. For example, the expression: (data_start+10).w will return the word contents of location data_start+10, assuming data_start is even. Indirection may be nested in a similar way to ordinary parenthesis. WINDOW TYPES There are four window types and the exact contents of these windows and how they are displayed is detailed below. The allowed types of windows is shown in the table below. Window Allowed Types 1 Register 2 Disassembly 3 Memory 4 Disassembly, Memory or Source-code 5 Memory REGISTER WINDOW DISPLAY The data registers are shown in hex, together with the ASCII display of their low byte and then a hex display of the eight bytes they point to in memory. The address registers are also shown in hex, together with a hex display of 12 bytes. As with all hex displays in MonAm this is word-aligned, with non-readable memory displayed as **. The status register is shown in hex and in flag form, additionally with U or S denoting user- or supervisor-modes. A7' denotes the supervisor stack pointer, displayed in a similar way to the other address registers. The PC value is shown together with a disassembly of the current instruction. Where this involves one or more effective addresses these are shown in hex, together with a suitably-sized display of the memory they point to. For example, the display TST.W $12A(A3) ;00001FAE 0F01 signifies that the value of $12A plus register A3 is $1FAE, and that the word memory pointed to by this is $0F01. A more complex example is the display MOVE.W $12A(A3),-(SP) ;00001FAE 0F01 =>002AC08 FFFF The source addressing mode is as before but the destination address is $2AC08, presently containing $FFFF. Note that this display is always of a suitable size (MOVEM data being displayed as a quad-word) and when pre-decrement addressing is used this is included in the address calculations. DISASSEMBLY WINDOW DISPLAY Disassembly windows display memory as disassembled instructions to the standard described below. On the left the hex address is shown, followed by any symbol, then the disassembly itself. The current value of the PC is denoted with >. If the instruction has a breakpoint placed on it this is shown using square brackets ([ ]) afterwards, the contents of which depend on the type of breakpoint. For stop breakpoints this will be the number of times left for this instruction to execute, for conditional breakpoints this will be a ? followed by the beginning of the conditional expression, for count breakpoints this will be a = sign followed by the current count, and for permanent breakpoints a symbol resembling a small zero in superscript is shown. The exact format of the disassembled op-codes is Motorola standard, as GenAM accepts. All output is upper-case (except lower-case labels) and all numeric output is hex, except Trap numbers. Leading zeroes are suppressed and the $ hex delimiter is not shown on numbers less than 10. Where relevant numerics are shown signed. The only deviation from Motorola standard is the register lists shown in MOVEM instructions - in order to save display space the type of the second register in a range is abbreviated, for example: MOVEM.L d0-d3/a0-a2,-(sp) will be disassembled as: MOVEM.L d0-3/a0-2,-(sp) Certain library calls will be shown symbolically even if no symbol information was loaded with your program. The dissassembler is intelligent and recognises a MOVE into register a6 follower by a JSR using a6 and if it is recognised then will be displayed by name, for example: MOVE.L 4,a6 JSR _LVOOpenLibrary(a6) It does this for the exec, graphics and intuition libraries, using the special file libs:libfile.monam. if this file is not found during Monams initialisation than such a dissassembly will not occur. MEMORY WINDOW DISPLAY Memory windows display memory in the form of a hex address, word-aligned hex display and ASCII. Unreadable memory locations are denoted by **. The number of bytes shown is calculated from the window width, up to a maximum of 16 bytes per line. SOURCE-CODE WINDOW DISPLAY The source code window displays ASCII files in a similar way to a screen editor. The default tab setting is 8 though this can be toggled to 4 with the Edit Window command. WINDOW COMMANDS The (AMIGA) key is generally used for controlling windows, and when used to apply to the current window. This is denoted by having an inverse title and can be changed by pressing the Tab or (AMIGA) plus the window number. Most window commands work in any window, zoomed or not, though when it does not make sense to do something the command is ignored. (AMIGA)-A SET ADDRESS This sets the starting address of a memory or disassembly window. (AMIGA)-B SET BREAKPOINT Allows the setting of any type of breakpoint, described later. (AMIGA)-E EDIT WINDOW On a memory window this lets you edit memory in hex or ASCII. Hex editing can be accomplished using keys 1-9, A-F, together with the cursor keys. Pressing Tab switches between hex & ASCII, ASCII editing takes each keypress and writes it to memory. The cursor keys can be used to move about memory. To leave edit mode press the Esc key. On a register window this is the same as (AMIGA)-R, Register Set, described shortly. On a source code window this toggles the tab setting between 4 and 8. (AMIGA)-L LOCK WINDOWS This allows disassembly and register windows to be locked to a particular register. After any exception the start address of the window is re-calculated, depending on the locked register. To unlock simply enter a blank string. By default window 2 is locked to the PC. You can lock windows to each other by specifying a lock to a memory window, such as M2. (AMIGA)-O SHOW OTHER This prompts for an expression and displays it in hex, decimal and as a symbol if relevant. (AMIGA)-P PRINTER DUMP Dumps the current window onto the printer. It can be aborted by pressing Esc. (AMIGA)-R REGISTER SET Allows any register to be set to a value, by specifying the register, an equals sign, then its new value. It can also be used to set the value of memories. For example the line: a3=a2+4 sets register A3 to be A2 plus 4. You can also use this to set the start address of windows when in zoom mode so that on exit from zoom mode the relevant window starts at the required address. NOTE: Do not assign M4 if window 4 is currently a source-code window. (AMIGA)-S SPLIT WINDOWS This either splits windows 2 into 2 and 4, or splits window 3 into 3 and 5. Each new window is independent from its creator. Pressing (AMIGA)-S again will unsplit the window. (AMIGA)-T CHANGE TYPE This only works on window 4 (created either by splitting window 2 or by loading a source file). It changes the type of the window between disassembly, memory and source-code (if a file has been loaded). (AMIGA)-Z ZOOM WINDOW This zooms the current window to be full size. Other Alt commands are still available and normal size can be achieved by pressing Esc or (AMIGA)-Z again. NOTE: Zooming the register windows shows the values of the memoris M0 to M9. CURSOR KEYS The cursor keys can be used on the current window, the action of which depends on the window type. On a memory window all four cursor keys change the current address, and Shift Up Cursor and Shift Down Cursor move a page in either direction. On a disassembly window Up Cursor and Down Cursor change the start address on an instruction basis, Left Cursor and Right Cursor change the address on a word basis. On a source-code window Up Cursor and Down Cursor change the display on a line basis and Shift Up Cursor and Shift Down Cursor on a page basis. SCREEN SWITCHING Monam uses its own screen display and will always make itself the front and active window whenever an exception (including breakpoints) occurs. V VIEW OTHER SCREEN This will put the monam screen to the back, normally showing your prograns screen Pressing any key will return the MonAm screen (so lang as you have not activated any other window). BREAKPOINTS Breakpoints allow you to stop the execution of your program at specified points within it. MonST allows up to eight simultaneous breakpoints, each of which may be one of five types. When a breakpoint is hit Monam is entered and then decides whether or not to halt execution of your program, entering the front panel display, or continue, this decision is based on the type of the breakpoint and the state of your program's variables. SIMPLE BREAKPOINTS These are one-off breakpoints which, when executed, are cleared and cause Monam to be entered. STOP BREAKPOINTS These are breakpoints that cause program execution to stop after a particular instruction has been executed a particular number of times. In fact a simple breakpoint is really a stop breakpoint with a count of one. COUNT BREAKPOINTS Merely counters; each time such a breakpoint is reached a counter associated with it is incremented, and the program will resume. PERMANENT BREAKPOINTS These are similar to simple breakpoints except that they are never cleared - every time execution reaches a permanent breakpoint MonAm will be entered. CONDITIONAL BREAKPOINTS The most powerful type of breakpoint and these allow program execution to stop at a particular address, only if an arbitrarily complex set of conditions apply. Each conditional breakpoint has associated with it an expression (conforming to the rules already described). Every time the breakpoint is reached this expression is evaluated, and if it is non-zero (i.e. true) then the program will be stopped, otherwise it will resume. (AMIGA)-B SET BREAKPOINT This is a window command allowing the setting or clearing of breakpoints at any time. The line entered should be one of the following forms, depending on the type of breakpoint required:
will set a simple breakpoint.
, will set a stop breakpoint at the given address, after it has executed times.
,= will set a count breakpoint. The initial value of the count will be zero.
,* will set a permanent breakpoint.
,? will set a conditional breakpoint, using the given expression.
,- will clear any breakpoint at the given address. Breakpoints cannot be set on addresses which are odd or unreadable, or in ROM. Every time a breakpoint is reached, regardless of whether the program is interrupted or resumed, the program state is remembered in the History buffer, described later. HELP SHOW HELP AND BREAKPOINTS This displays the current breakpoints, task status, its segment list (showing where the program is), free memory and the system memory list. (AMIGA) commands are available within this display. For UK A500 1.2 users (who cannot use the help key) this can also be obtained by pressing (AMIGA)-H Ctrl-B SET BREAKPOINT Included mainly for compatibility with MonAm 1, this sets a simple breakpoint at the start address of the current window, so long as it is a disassembly window. If a breakpoint is already there then it will be cleared. U GO UNTIL This prompts for an address, at which a simple breakpoint will be placed then program execution resumed. Ctrl-K KILL BREAKPOINTS This clears all set breakpoints. Ctrl-A SET BREAKPOINT THEN EXECUTE A command that places a simple breakpoint at the instruction after that at the PC and resumes execution from the PC. This is particularly for DBF-type loops if you don't want to go through the loop, but just want to see the result after the loop is over. Ctrl-X STOP PROGRAM EXECUTING This is a command to stop your task while it is executing. It does this by forcing the trace bit to be set, so you will get a trace exception. While this does work, be very careful if you stop it in th middle of some AmigaDOS ROM routines, particually signal handling and message passing. NOTE: The above command accesses memory fields that are not guarenteed to remain the same for differant versions of the Amiga operating system. Initially you should try it at a time when nothing important is in the machine to check compatibility with the version of the operating system you are using before you are forced to use it when a task goes a little beserk. This command used to be Ctrl-S on MonAm version 1. HISTORY MonAm has a history buffer in which the machine status is remembered for later investigation. The most common way of entering data into the history buffer is when you single-step, but in addition every breakpoint reached and every exception caused enters the machine state into the buffer. Various forms of the Run command also cause entries to be made into this buffer. NOTE: The history buffer has room for five entries - when it fills the oldest entry is removed to make room for the newest entry. H SHOW HISTORY BUFFER This opens a large window displaying the contents of the history buffer. All register values are shown including the PC as well as a disassembly of the next instruction to be executed. NOTE: If a disassembly in the History display includes an instruction which has a breakpoint placed on the [ ]s will show the current values for that breakpoint, not the values at the time of the entry into the history buffer. QUITTING MONAM Ctrl-C TERMINATE This returns Monam directly to the CLi or to the editor if you invoked Monam from the editor. If the task you are debuggingis still running or suspended when you try and quit, you will be warned. If monam terminates while the task under investigation is running, the machine will crash if any exception occurs subsiquently. A safer way is to use the Ctrl-Q command to stop the task first. If the Debug option has been used from the GenAm editor then MonAm will terminate automatically when the program it is debugging has terminated. CTRL-Q QUIT A PROGRAM This is a way of forcing a task being debugged to Quit. This can be hazardous to use, and should only be done as a last resort. if your program is terminated in this way it will not clean up, and thus not de-allocate any memory it was using or close windows etc. NOTE: The above command accesses memory fields that are not guaranteed to remain the same for differant versions of the operating system. Initially you should try it at a time when nothing important is in th machine to check compatability with the version of the operating system you are using before you are forced to use it when a task goes a little beserk. LOADING & SAVING Ctrl-L LOAD EXECUTABLE PROGRAM This will prompt for an executable filename then a command line and will attempt to load the file ready for execution. If MonAm has already loaded a program it is not possible to load another until the former has terminated. The file to be loaded must be an executable file. use the load binary file command if you wish to edit other file types. NOTE: This command in not available if Monam has been invoked using Debug from the editor. B LOAD BINARY FILE This will prompt for a filename and optional load address (separated by a comma) and will then load the file where specified. If no load address is given then memory will be allocated from the system and used. M0 will be set to the start address and M1 to the end address. S SAVE BINARY FILE This will prompt for a filename, a start address and an (inclusive) end address. To re-save a file recently loaded with the above command ,M0,M1 may be specified, assuming of course that M0 and M1 may be specified, assuming of course that M0 and M1 have not been re-assigned. A LOAD ASCII FILE This powerful command allows an ASCII file, normally of source code, to be loaded and viewed within Monam, Window 4 will be created if required then set up as a source code window. Memory for the source code is taken from the system so sufficient free memory must be available. EXECUTING PROGRAMS Ctrl-R RETURN TO PROGRAM / RUN This runs the current program with the given register values at full speed and is the normal way to resume execution after entry via a breakpoint. Ctrl-Z SINGLE-STEP This single-steps the instruction at the PC with the current register values. Single-stepping a Trap, Line-A or Line-F opcode will, by default, be treated as a single instruction. This can be changed using Preferences. Ctrl-Y SINGLE-STEP Identical to Ctrl-Z above but included for the convenience of German users. Ctrl-T INTERPRET AN INSTRUCTION (TRACE) This interprets the instruction at the PC using the displayed register values. It is similar to Ctrl-Z but skips over BSRs, JSRs, Traps, Line-A and Line-F calls, re-entering the debugger on return from them to save stepping all the way through the routine or trap it works on instructions in ROM or RAM. Ctrl-S SKIP AN INSTRUCTION Ctrl-s increments the PC register by the size of the current instruction thus causing it to be skipped. Use this instead of Ctrl-Z when you know that this instruction is going to do something it shouldn't. R RUN (VARIOUS) This is a general Run command and prompts for the type of the Run to be done, selected by pressing a particular key. Run G GO This is identical to Ctrl-R, and resumes the program at full speed. Run I Instruction This executes the entered number of instructions remembering information in the history buffer and then returning to monam. Traps will be treated as single-instructions. SEARCHING MEMORY G SEARCH MEMORY (GET A SEQUENCE) This will prompt Search for B/W/L/T/I?, standing for Bytes, Words, Longs, Text and Instructions. If you select B, W or L you will then be prompted to enter the sequence of numbers you wish to search for, each separated by commas. MonST is not fussy about word-alignment when searching, so it can find longs on odd boundaries, for example. If you select T you may search for any given text string, which you will be prompted for. The search will be case-dependent. If you select I you can search for part or all of the mnemonic of an instruction, for example if you searched for $14 (A you would find an instruction like MOVE.L D2,$14(A0). The case of the string you enter is important (unlike Monam version 1), but you should bear in mind the format the disassembler produces, e.g. always use hex numbers, refer to A7 rather than SP and so on. Having selected the search type and parameters, the search begins, control passing to the Next command, described below. N FIND NEXT This can be used after the G command to find subsequent ccurences of the search data. With the B, W, L and T options you will always find at least one occurrence, which will be in the buffer within MonAM that is used for storing the sequence. With the T option you may also find a copy in the system keyboard buffer. With these options, the Esc key is tested every 64k bytes and can be used to stop the search. With the be used to stop the search. With the I option, which is very much slower, the Esc key is tested every 2 bytes. The search area of memory goes from 0 to the end of chip memory, then from $F80000 to $FFFFFF (the ROM), then any additional RAM. The search will start just past the start address of the current window (except register windows) and if an occurrence is found re-display the window at the given address. SEARCHING SOURCE-CODE WINDOWS If the G command is used on a source-code window the T sub- command is automatically chosen and if the text is found the window will re-display the line containing it. MISCELLANEOUS Ctrl-P PREFERENCES This permits control over various options within MonAM. The first three require Y/N answers, pressing Esc aborts or Return leaves them alone. RELATIVE OFFSETS This option defaults to On and effects the disassembly of the address register indirect with offset addressing modes, i.e. xxx(An). With the option on the current value of the given address register is added to the offset then searched for in the symbol table. If found it is disassembled as symbol (An). This option is very useful for certain styles of assembly language programming as well as high level languages which use a base register as a major offset, such as HiSoft BASIC which uses A3 as a pointer to the run-time system. SYMBOLS OPTION This allows control over the use of symbols in expressions in MonAm. It will firstly ask whether the case of symbols should be ignored, pressing Y will cause case independent searching to be used. It will then prompt for the maximum length of symbols, which is normally 32 but may be reduced to as low as 8. Or increased if required. PRINTER DEVICE This lets you set the device that Monam uses for its printer commands, the default is PRT: SAVE PREFERANCES Reply Y to this command to save your current preferances to the file monam2.inf in the current directory. When monAm2 loads it will read your current preferances from this file. Monam2.inf is firstly searched for in the current directory, then in the c: directory, in a similar way to the editor preferances file. I INTELLIGENT COPY This copies a block of memory to another area. The addresses should be entered in the form: ,, The copy is intelligent in that the block of memory may be copied to a location which overlaps its previous location. NOTE: No checks at all are made on the validity of the move; copying to non-existent areas of memory is likely to crash Monam and corrupting system areas may well crash the machine. L LIST LABLES This opens up a large window and displays all loaded symbols. Any key displays the next page, pressing Esc aborts. The symbols will be displayed in the order they were found on the disk (or in memory if using the Debug option from the editor). Ctrl-U name UNLOAD SYMBOLS This command can only be used if you are debugging a task which had a symbol table loaded with it. What it does is de-allocate the memory used for storing symbols, freeing it for the system to use. This can be very useful if memory is tight while debugging a lager program, as you can load it, together with symbols, set a breakpoint at a symbolic address, then lose the labels before letting it run. Of course once you hit your breakpoint you won't have any symbols. NOTE: Thois command used to be Ctrl-L on Monam version 1. COMMAND SUMMARY WINDOW COMMANDS (AMIGA)-A ..................... Set Address (AMIGA)-B ..................... Set Breakpoint (AMIGA)-E ..................... Edit Window (AMIGA)-L ..................... Lock Window (AMIGA)-O ..................... Show Other (AMIGA)-P ..................... Printer Dump (AMIGA)-R ..................... Register Set (AMIGA)-S ..................... Split Windows (AMIGA)-T ..................... Change Type (AMIGA)-Z ..................... Zoom Window BREAKPOINTS (AMIGA)-B ..................... Set Breakpoint Help ...................... Show Help and Breakpoints Ctrl-B .................... Set Breakpoint U ......................... Go Until Ctrl-K .................... Kill Breakpoints Ctrl-A .................... Set Breakpoint then Execute Ctrl-X .................... Stop program executing LOADING AND SAVING Ctrl-L .................... Load Executable Program B ......................... Load Binary File S ......................... Save Binary File A ......................... Load ASCII File EXECUTING PROGRAMS Ctrl-R .................... Return to program/Run Ctrl-Z .................... Single-Step Ctrl-Y .................... Single-Step Ctrl-T .................... Interpret an Instruction (Trace) Ctrl-S..................... Skip instruction R ......................... Run (various) SEARCHING MEMORY G ......................... Search Memory (Get a sequence) N ......................... Find Next MISCELLANEOUS Ctrl-C .................... Terminate Ctrl-Q..................... Quit program Ctrl-P .................... Preferences I ......................... Intelligent Copy W ......................... Fill Memory With L ......................... List Labels Ctrl-U..................... Unload symbols P ......................... Disassemble to Printer/Disk M ......................... Modify Address O ......................... Show Other Bases D ......................... Change Drive & Directory H ......................... Show History Buffer V.......................... View other screen DEBUGGING STRATAGEM RESTRICTIONS As it runs as a process MonAm relies on the exec.intuition and graphics libraries. If your program starts destroying memory to which it has no right it is possible for it to fatally corrupt something the system needs so that when monam is entered after an exception the machine will crash. Fortuanely this type of error is rare, usually address errors occur before programs start destroying memory. When a program is invoked from Monam it is set up to look as if it has been run from the CLI, not the workbench. Monam cannot single step or breakpoint any code when executing in supervisor mode. This is because the exec exception handler checks for an execption in supervisor mode, amd will put up a guru alert if this is the case. If not it will enter Monam and work normally. If your program creates another program or task you cannot use monam to breakpoint it or single-step. Monam can only debug the program that was specified when it initially loaded. Don't try and run the standard system programs from within Monam, such as dir. These rely on undocumented registers (particually a5) and memory areas which monam cannot emulate. Due to a hardware feature, a word - or longword-access on odd memory locations 1 to 7 inclusive will cause a complete machine crash. There seems to be nothing we can do to prevent this. BUG HUNTING There are probably as many strategies for finding bugs as there are programmers; there is really no substitute for learning the hard way, by experience. However, there are some hints which we have learnt, the hard way! Firstly, a very good way of finding bugs is to look at the source code and think. The disadvantage of reaching first for the debugger, then second for the source code, is that it gets you into bad habits. You may switch to a machine or programming environment that does not offer low-level debugging, or at least not one as powerful as you are used to. If a program fails in a very detectable way, such as causing an exception, debugging is normally easier than if, say, a program sometimes doesn't quite work exactly as it should. Many bugs are caused by a particular memory location being stepped on. Whether the offending memory location is detectable, by producing a bus error, for example, a conditional breakpoint placed at one or more main subroutines can help greatly. For example, suppose the global variable main_ptr is somehow becoming odd during execution, the conditional expression could be set up as: (main_ptr)&1 Count breakpoints are a good way of tracking down bugs before they occur. For example, suppose a particular subroutine is known to eventually fail but you cannot see why, they you should set a count breakpoint on it, then let the program run. At the point where the program stops, because of an exception say, look at the value of the count breakpoint (using Help). Terminate the program, re-load it, then set a stop breakpoint on the subroutine for that particular value or one before it. Let it run, then you can follow through the sub-routine on the very call that it fails on, to try and work out why. GOOD LUCK! EXCEPTION ANALYSIS When an unexpected exception occurs, it's very useful to be able to work out where and why it occurred and, possibly, to resume execution. BUS ERROR If the PC is in some non-existent area of memory then look at the relevant stack to try and find a return address to give a clue as to the cause, probably an unbalanced stack. If the PC is in a correct area of your program then the bus error must have been caused by a memory access to non-existent or protected memory. Recovering from bus errors and resuming execution is generally not possible. ADDRESS ERROR If the PC is somewhere strange the method above should be used, otherwise the error must have been caused by a program access to an odd address. Correcting a register value may be enough to resume execution, at least temporarily. ILLEGAL INSTRUCTION If the PC is in very low memory, below around $30, it is probable that it was caused by a jump to location 0. If you use MonAM to look here you will normally see various ORI instructions (really longword pointers) and eventually an illegal instruction. PRIVILEGE VIOLATION This is caused by executing a privileged instruction in user mode, normally meaning your program has gone horribly wrong. Bumping the PC past the offending instruction is unlikely to be much help in resuming the program. APPENDIX A: AmigaDOS error codes This appendix details the numeric AmegaDOS errors and their meanings: 103 insufficient free store out of memory 104 task table full limit of 20 cli's 120 argument line invalid or too long when using CLI commands 121 file is not an object module trying to execute a non- executable file 122 invalid resident library during load 202 object in use such as a file by another program 203 object already exists 204 directory not found 205 object not found most commonly a file 206 invalid window in name specification 209 packet request type unknown 210 invalid stream component name name too long or contains control characters 211 invalid object lock 212 object not of required type such as directory name instead of file 213 disk not validated disk is still being validated, or is bad 214 disk write-protected 215 rename across devices attempted 216 directory not empty when trying to delete it 218 device not mounted after specifying a volume name 219 seek error 220 comment too big file comments must be less than 80 221 disk full 222 file is protected from deletion 223 file is protected from writing 224 file is protected from reading 225 not a DOS disk 226 no disk in drive 232 no more enteries in directory APPENDIX B: GenAM error messages Genam can produce a large number of error messages, most of which are pretty self explanatory. This appendix lists them all in alphabetic order, with clarifications for those which require them. Please note that GenAM is continually being improved and list may not agree exactly with the version you have, there may be additional messages not documented here. ERRORS If you get a message beginning with INTERNAL please tell us - you should never see these. .W or .L expected as index size absolute expression MUST evaluate absolute not allowed additional symbol on pass 2 somehow a symbol has appeared during pass 2 that did not appear during pass 1 address register expected addressing mode not allowed addressing mode not recognised BSS or OFFSET cannot contain data OFFSET sections and non-GST BSS sections can only contain DS directives cannot create a binary file could be a bad filename, or a write-protected disk, etc. cannot export symbol cannot import symbol cannot reset MACRO definitions or define in REPTs macro definitions may not be nested or defined within repeat loops cannot nest repeat loops comma expected data register expected data too large division by zero duplicate MODULE name module names must be unique error during listing output listing will be stopped at this point error during writing binary file normally disk full executable code only only executable code may be assembled to memory expression mismatch normally a syntax error within an expression fatally bad conditional there were more ENDCs in a macro than IFs file not found forward reference garbage following instruction illegal BSR.S a BSR.S to the following instruction is not allowed - change it to BSR illegal type combination immediate data expected imported label not allowed include file read error instruction not recognised invalid FORMAT parameter invalid INCDIR You have used more than 500 bytes of directory specifications invalid IF expression, ignored invalid MOVEF addressing mode invalid number invalid numeric expression the symbol is not defined or relative or a syntax error invalid option invalid printer parameter invalid register list invalid section name, TEXT assumed invalid size line malformed linker format restriction the AmigaDOS format is restrictive about where it allows imports local not allowed missing close bracket missing ENDC there were more IFs than ENDCs missing quote misuse of label not yet implemented number too large odd address option must be at start ORG not allowed out of memory phasing error should never happen, look investigate immediately before first such error program buffer full change the program buffer size when assembling to memory register expected relative not allowed relocation not allowed repeated include file each include file may only be included once on each pass source expired prematurely with an IF, MACRO or REPT and the source ran out spurious ENDC spurious ENDM or MEXIT spurious ENDR symbol defined twice symbol expected undefined symbol user error caused by FAIL directive wrong processor XREFs not allowed within brackets WARNINGS 68010 instruction, converted to MOVE SR MOVE CCR, is not a 68000 instruction branch made short by optimising directive ignored invalid LINK displacement if negative or odd offset removed xx(An) form reduce to (An) by optimising relative cannot be relocated short branch converted to NOP sign extended operand data in MOVEQ needed sign extension to fit size should be .W APPENDIX C: CALLING THE OPERATING SYSTEM INTRODUCTION The Amiga operating system is arguably with the exception of OS/2 the most sophisticated of any mass produced computer, and is also the most complicated. The whole machine is based around the concept of libraries, which are essentially groups of subroutones (or functions to C-programmers) indexed off a large jump block. The appendix is intended to explain the basics of calling libraries from assembly language, and to give an idea of what each can be used for. One small Appendix cannot possibly describe the whole operating system, it is only meant as an introduction. Please note that was written with version 1.2 of Kickstart in mind, it is possible subsiquent versions may differ slightly. Any important differances should be detailed in the readme file. LIBRARIES The most basic library is the exec library, which has to be called to open nay other library, among other things. As with all libraries, a library base pointer is required to access it, and this must be loaded into register a6 before calling any function. The exec library is unique as that it dosen't have to be opened to obtain a base pointer - this can be obtained from the longword at location 4 - the only location in the whole machine guaranteed to remain the same in the future. The base pointer so obtained can then be used to open further libraties, to obtain other library base pointers, and so on. Note that most libraries require a6 to be contained in the base pointer for correct operation (as they call the other routines in the same library) though not all do. Parimiters are passed to library routines in requesters, and sa a general rule requesters d0/d1/a0/a1 should be assumed to be corrupted by any call. A large number of include files are supplied with DEVPAC to allow easy access to the various parts of the opearting system. These include files containing macro definitions, library offset symbols, data structure definitions, and bit field symbols. There now follows a library table showing the names of the various components, and where the definitions can be found in the include directory. FILE: this shows the file that contains the macro definitions and _LVO offsets for calling the library. NAME MACRO: this normally consists of a dc.b statement defining the ASCII for the name, ending in a null. BASE POINTER: this is the symbolic name of the longword used for storing the base pointer. It always starts with an underline character, though when used from most C compilers this underline is not shown. CALLING MACRO: this is the name of the macro that calls a particular library. Note that this will corrupt register a6 as it will be loaded with the relevant library base pointer. LIBRARY FILE NAME MACRO BASE POINTER CALLING MACRO diskfont libraries/diskfont_lib.i DISKFONTNAME _DiskfontBase CALLDISKFONT dos libraries/dos_lib.i DOSNAME * _DOSBase CALLDOS exec exec/exec_lib.i EXECNAME _SysBase CALLEXEC expansion libraries/expansion_lib.i EXPANSIONNAME ** _ExpansionBase CALLEXP graphics grapgics/graphics_lib.i GRAFNAME _GfxBase CALLGRAF icon workbench/icon_lib.i ICONNAME _IconBase CALLICON intuition intuition/intuition_lib.i INTNAME _IntuitionBase CALLINT mathffp math/mathffp_lib.i FFPNAME _MathBase CALLFFP mathdouble math/mathieeedoubas_lib.i IEEEDOUBNAME _MathIeeeDouBasBase CALLIEEEDOUB mathtrans math/mathtrans_lib.i MATHTRANSNAME _MathTransBase CALLMATHTRANS translator libraries/translator_lib.i TRANSNAME _TranslatorBase CALLTRANS For example, to call the exec library function OpenLibrary suitable assembler source code would be CALLEXEC OpenLibrary This macro is expanded into move.l (_SysBase).w,a6 jsr _LVOOpenLibrary(a6) * = name macro definition can be found in file libraries/dos.i ** = mane macro can be found in file libraries/expansion.i DISKFONT LIBRARY: This is a library for handling fonts that are normally resident on the disk. FILES: libraries/diskfont.i and diskfont_lib.i DOS LIBRARY: One of the most straightforward of the libraries to use, this handles file i/o (input/output) to devices, including disk and console. It has some slight anomalities, notabily addersses have to be passed in data registers, and many pointers have to be BCPL-type (ie. longword aligned and divided by 4) FILES: libraries/dos.i dos_lib.i and dosextens EXEC LIBRARY: This is the lowest level of library, responsible for things like memory management, library calls, and message passing. The library never has to be opened - its base pointer is contained in location 4. FILES: exec/ables.i alerts.i devices.i errors.i exec.i execbase.i execname.i exec_lib.i funcdef.i initializers.i interrupts.i io.i libraries.i lists.i memory.i nodes.i ports.i resident.i strings.i tasks.i and types.i GRAPHICS LIBRARY: This is responsible for controlling exectly what appears on your monitor, including things like drawing lines, printing text, controlling RastPorts, sprite handling and fonts. FILES: graphics/clip.i copper.i display.i gels.i gfx.i gfxbase.i graphics_lib.i layers.i rastport.i regions.i sprite.i text.i and view.i ICON LIBRARY: This library is responsible for handling the icons displayed by the Workbench. FILES: workbench/icon.i icon_lib.i INTUITION LIBRARY: This library is the lagest and is responsible for the windowing intuition user interface. It has a very large number of functions, including those for window conrtol, screens. gadgets, requesters, and event handling. The main file is large and also includes a large number of other files, so don't be surprised if it takes a little while to read it all. It can be worthwile to create your own specilised version without the less-often used constants, which can reduce the amount of other include files required. FILES: intuition/intuition.o and intuition_lib.i MATHS LIBRARIES: There are three maths libraries, all based on the official Motorola routines. The FFP (Fast Floating Point) library uses an 8-bit exponent, 24-bit mantissa format. The format used was designed for the 68000 series, and is exclusive to Motorola. The IEEE double library offers doublr-precision using IEEE standard formats for numbers, and the Trancendental library is used for FFP trig and other functions. FILES: math/mathffp_lib.i mathieeedoubbas_lib.i and mathtrans_lib.i As a genaral rule you should use GenAm in case sensative mode (the default) when using the supplied include files. note that every include file always includes any others it needs automatically, so you don't need to worry about it. EXAMPLE PROGRAMS To help you get started programming AmigaDOS from assembly language we have provided the source to a few example programs in the examples directory. DEMO.S this is the program used for the tutorial at the beginning of the manual. It uses the DOS library to print a message on the current CLI window. FREEMEM.S This program that uses intuition to create a window in which the system free memory is constantly displayed, until the close gadget is clicked on. To run this concurrently from the CLI use the command: run examples/freemem HELLOWORLD.S This is the assembly language conversion of the C program 'final version of the simple program' described at the beginning of 'intuition - the amiga user interface'. The conversion has not been optimised in any way, for example, the structure assignment for NewScreen would be more efficient using dc.w/dc.l statements, but has been left as MOVE instructions for a more accurate conversion. The program opens up a custom screen and, within it, a simple message. CLI vs WORKBENCH There are two program enviroments on the amiga - the windows & icon driven workbench, and the CLI. Devpac itself runs only under the latter, as do most example programs, the differance being in the startup and exit code. CLI STARTUP When a program is run from the CLI it starts with register a0 containing the address of the command linem and d0 containing its length. The DOS handles returned by input and output can be used for i/o with the console device, and to exit the program should simply RTS. WORKBENCH STARTUP When a program is run from the Workbench it has to wait firstly for a message, and on terminating it has to reply to the message (after doing a forbid call) before RTSing. The DOS functions input and output will not return valid handles, so you need to open a window to perform any console i/o the startup differances are detailed in part 4, chapter 2 of the ROM Kernal Menual Volume 1, together with the assembly language source of the startup code used by C programs. Note that there is a bug in it - the routine openDOS should have a moveq #0,d0 instruction added before the call to OpenLibrary, otherwise a fatal alert can be produced. A skeleton version of this for assembly language programmers can be found in the file misc/easystart.i which is included by the freemem2.s example program. It should be included at the very front of your programs, and handles the message-passing to allow programs to be run from workbench. Of course to do this you will need to create an icon for your program, using iconed. APPENDIX D: USING THE CLI All this section is covered in the Amiga manuals you get with the machine so look them up yourselves! APPENDIX E: CONVERTING FROM OTHER ASSEMBLERS Most 68000 assemblers for the Amiga follow, to one degree or another the Motorola standard. While the instructions themselves are thankfully standard, the syntax rules for labels, comments and directives can, and do, vary. This Appendix covers the changes most likely to be made when converting programs from another assembler, whether they are your old source files or a program listed in a magazine. It does not attempt to detail the differences in user interfaces or options between the different assemblers. AMIGA MACRO ASSEMBLER AND MCC ASSEMBLER: Almost all source code written for assembly under the Amigados Macro Assembler supplied by Commodore and the Metacomco (MCC) assembler should assemble with little or no change under GenAm. The differances are: 1. With GenAm, importing constants using XREF and then accessing them as constants (as opposed to relative addresses) may cause warning messages. Many source programs use XREFs for _LVO labels. To remove these warnings either: change XREF to XREF.l use OPT W- to supress all warnings use OPT T- to suppress type-checking include the relevant _lib.l file and remove the XREF 2. The directive RORG is not supported. The include files with the AmigaDOS Macro Assembler will assemble unchanged by GenAm, but our supplied ones are preferred because they use directives instead of macro calls to define labels and have comments removed to take less disk space and be faster to assemble. The original versions can be found in Appendix E of ROM Kernal Manual Volume 2 and on DEVPAC disk 2. K-SEKA: Colons are not required after labels in GenAm though instructions or directives that start in the label field will need a tab added before them. Several Seka directives default to Byte instead of Word sizes for some reason. Equivalent directives names are: D=DC, BLK=DS, IF=IFNE, ELSE=ELSEIF, ENDIF=ENDC. Macro syntax requires ?s to be changed to \s, except ?0 which should be replaced with \@. NEW COMMODORE INCLUDE FILES Should you obtain new include files from Commodore you should be able to assemble them unchanged with GenAm. however should you wish to convert them to the same form as those supplied by us so that they take less disk space, and assemble faster, we have supplied two tools to convert them for you, 'convertFD' and 'convertI' CONVERTI DETAILS: Converti is supplied on disk 2 and converts Commodore include files to the same compressed form that we supply. The commandline is of the form: ConvertI (source) (destination) <-d> The source and destination file names should have their extension omitted. Teh -d flag indicates that a whole directory is to be converted. For example: ConvertI old/dos new/dos converts the single file old/dos.i to new/dos.i ConvertI old new -d will convert all the standard files in the directory old (of course they must be there first) to the corresponding name in the directory new. CONVERTFD DETAILS: ConvertFD is supplied on disk 2 and converts Commodore FD files into library files with extension _lib.i containing the_LVO offsets for inclusion into your programs. The command-line is of the form: ConvertFD (source) (destination) <-d) The source and destination file names should have their extensions onitted. The -d flag indicates that a whole directory is to be converted. For example: ConvertFD fdfiles/dos new/dos converts the single file fdfiles/dos_lib.fd to new/dos_lib.i ConvertFD fdfiles :include/libraries -d will convert all the fd files in the directory fdfiles (of coures they must be there first) to the corrosponding include file in the directory :include/libraries. APPENDIX F: VERSION 2 IMPROVEMENTS All information is already documented earlier. APPENDIX G: BIBLIOGRAPHY This bibliography contains our suggestions for further reading on the subject of the 68000 and the Amiga. The views expressed are our own and as with all reference books there is no substitute for looking at the books in a good bookshop before making a decision. M68000 Programmer's Reference Manual Published by Prentice-Hall The definitive guide to the instruction set produced by Motorola. the supplied Pocket Guide is a subset of this book. Be sure to get the latest version - at the time of writing the Fifth Edition is the latest. 68000 Assembly Language Programming by Kane, Hawkins & Leventhal Published by Osborne/McGraw-Hill This is large (and expensive) but good, containing lots of examples. Be sure to get the second edition. Not for complete beginners to microprocessors. 68000 Tricks and Traps by Mike Morton BYTE magazine, September 1986 issue By far the best article on 68000 programming we have ever seen. We wish there was a book like this. M68000 Cross Macro Assembler Reference Manual Published by Motorola (M68KXASM) The official definition of 68000 assembly-language syntax on which Genam is based. APPENDIX H: TECHNICAL SUPPORT AND UPGRADES Which is no use to you as your not a registered user!.