TR.COM - An inter-active disassembler for Z80 code using Intel type mnemonics, by Alan W Warren Derived from an early version of Ward Christensens' RESOURCE.COM, TR.COM supports most of the same features plus several others, and can disassemble Z80 code using the same mnemonics used by TA.COM and TD.COM, the matching assembler and debugger. The added features a command interpreter that is a bit less fussy about token delimiters (it will accept dots, commas, colins, semi-colins and spaces), and does not require the use of a dot in front of symbolic names. Another feature is a chain read/save option, that will read or save the four file types one after the other. The build command uses different letters to prefix labels which are referenced by different types of codes (L is for destination addresses of Calls, Jumps, and Address tables; M is for addresses of LHLD & SHLD codes; N is for addresses of LDA & STA codes; P is for addresses of LXI codes; a minus sign is used when the address is above the top of the TPA, and the negative value is used for the rest of the symbol). Additional commands include a poke feature that allows for any byte in RAM to be changed, and a mathmatics command that prints the sum, difference, product, etc. TR.COM types an "*" prompt when it is loaded. You may then enter any of the following commands. Each command is a single letter followed by operands. Commas are shown as the delimiter, but a space will also work, as will colins, semi-colins and dots. ---------------- ---------------- ; Put comments into the program. (must execute 'u' command first, to assign area for comments to be placed) ;addr,comment enter a comment ;addr lists existing comment ; lists entire comments table ;addr, deletes existing comment note that '\' is treated as a new line, i.e. \test\ will be formatted: ; ;TEST ; ---------------- Attempt to find DB's while listing the program. - This command works just like 'L', but attempts to find DB's of 8 chars or longer. (see 'L' command for operand formats) Build default sym tbl (LXXXX) labels for each - 2 byte operand encountered. Note 'B' is identical to 'L' except labels are built. (see 'L' command for operand formats) ---------------- Control table usage: - C Dump control table CNNNN Dump from starting CNNNN,X Define format from NNNN to next entry. Values of x: B = DB (attempts ASCII printable, 0DH, 0AH, 0) W = DW (attempts label) S = DW to next ctl entry I = instructions K = kill this ctl entry E = end of disassembly NOTE every control entry causes a "control break" (NO, TR.COM was NOT written in RPG) which means a new line will be started. Thus if you have a string in memory which disassembles as: DB 'Invalid operand',0DH DB 0AH You might want to change it putting the 0DH,0AH together on the second line - just enter a "B" control entry for the address of the 0DH. The same technique could be used to make DB 'TYPESAVEDIR ERA REN ' appear as DB 'TYPE' DB 'SAVE' DB 'DIR ' DB 'ERA ' DB 'REN ' DUMP: - DXXXX Dumps 80H from XXXX on DAAAA,BBBB Dumps from AAAA thru BBBB D,BBBB Continues, thru BBBB D Continues, 80H more NOTE 80H is the default dump length. If you have a larger display, you can change the default via: D=NN NN is the HEX new default. For example, a 24 line tube could display 100H: D=100 or.. D=100,200 Defaults to 100, dumps 200-2ff ---------------- ENTER SYMBOL: - ENNNN,SYMBOL Symbol may be of any length, and contain any char A-Z or 0-9, or "+" or "-". This allows: E5D,FCB+1. Note the "+" is not checked, i.e. E5D,.FCB+2 would be wrong (assuming FCB is at 5C) but would be allowed to be entered. Note if you enter two symbols for the same address, whichever one is first alphabetically will show up on the disassembled listing. If you have a label which has the wrong address, you need not explicitly kill the old one before entering the new. A label which is spelled exactly the same as an existing one will replace the existing one even if the addresses are different. ---------------- Find occurrence of address or label. Note this function - runs until interrupted (press any key). FNNNN,SSSS Find address NNNN in memory. Start the search at SSSS. Runs forever. Press any key to stop. F Continue previous find command FNNNN Find NNNN starting at address you last stopped at in the f command ---------------- KILL SYMBOL from table - K SYMBOL List (disassemble). This command is used to list the - file, or to list it to disk after enabling the .ASM file save via 'SFILENAME.ASM' command L Lists 10 lines from prev pc LSSSS,EEEE Lists from SSSS to EEEE L,EEEE Lists from current pc to EEEE LSSSS Lists 10 lines at SSSS Note that if you have a control 'e' entry, then the list will stop when that address is found. This allows you to 'LSTART,FFFF'. The 10 line default may be changed via: L=NN Where NN is a HEX line count, e.g. L=14 set to 20 lines/screen You can change the default and list, e.g. L=9,100 Dflt to 9 lines, list at 100. NOTE when using L to list the .ASM program to disk, you should either list the entire program at once using: LSSSS,EEEE or, you can list small pieces at a time. As long as you list again without specifying a starting address, (L or L,NNNN) then the output file will continue uninterrupted. You may do dump commands, and others, without affecting what is being written to disk. ---------------- Offset for Disassembly - O Print current offset ONNNN Establish new offset (Note the offset is always added to any address specified in an A, B, D or L command. to dump real memory, the offset must be reset to 0 (O0) before the dump.) ---------------- Prolog Generation - This routine generates an - ORG instruction, and equates for any label outside of a given low-hi address pair. (the start and end addresses of your program). e.g. if disassembling from 100 to 3FF, it will generate 'FCB EQU 5CH' if FCB is in the symbol table. In typical use, you would 'SFILENAME.ASM' then use the P command to write the prolog, then the L command to write the program itself. PSTART ADDR,END ADDR Quiet command: any command which is preceeded by a q - will be done 'quietly'. For example, to save a .ASM program, you could just do: QL100,3FF or QL100,FFFF if you have set the 'E' control in the control table. Another use is to build a default symbol table by taking a pass thru the program: QB100,XXXX ---------------- Read .COM, .CTL, .SYM, or .DOC file - RFILENAME.COM Reads in at offset+100h RFILENAME.CTL Loads the ctl table RFILENAME.SYM Loads the sym file RFILENAME.DOC Loads the comments table (note 'U' command must have been issued) RFILENAME.* Loads the all of the files above in the order shown. If the offset for is set too low, it will be reset higher as will the base of the comment table. ---------------- Save .ASM, .CTL, .SYM, or .DOC file - SFILENAME.CTL Saves the CTL table SFILENAME.SYM Saves the sym file SFILENAME.DOC Saves the comments table SFILENAME.ASM Use 'L' command to write, 'Z' to end SFILENAME.ASM Save files as above and enables .ASM save. ---------------- Use area of memory for comments table - UNNNN Such as UD000 if you had an open board at 0D000h ---------------- Purge symbol table and control table X - ---------------- Close .ASM file (note that a preferred way to close the .ASM file is to have specified a control entry for the end address (e.g. C1FF,E)) Z - ---------------- If you entered a label in the symbol table but now want to get rid of it: K SYMBOL NOTE: To rename a symbol, such as when you had a system-assigned LNNNN label but now want to make it meaningful: K L0334 E334,TYPE you could even: EL0334 TYPE KL0334 but that takes more typing. ? Prints statistics on symbol and control table usage, etc. C Prints the entire control table NNNN Prints the control table starting at address NNNN DS Dumps the symbol table. Interrupt it by typing any key. DS SYMBOL Symbol starts dumping at the specified symbol, or the nearest symbol. thus "ds.f" starts the dump at the first label starting with the letter 'f'. -------------------------------------------- ---- WATCH FOR ---- * Symbols overflowing into the .COM. (Use ? command to see how full symbol table is) * Control entries overflowing into .SYM (although it's hard to believe anyone will have a program with more than 512 control entries!!!) * Using an offset which is not in free memory and overlaying BDOS or whatever. * The B(uild) command gobbling up too much when building a DB: "B" will take a DB 'GOBBELDY GOOK' followed by LXI H,FOO and take the LXI as a '!' (21H) so you'll have to manually stick a new "I" control entry in at the address of the LXI. You might also delete the incorrect "I" entry which TR.COM stuck in (typically at the second byte of the LXI) * Trying to dump real memory without setting the offset back to 0. (then forgetting to set it back to its proper value) * Forgetting how big the .COM file you are disassembling was. * Using TR.COM to rip off software (yes, I know, you heard that before, but only 3 in 100 needed to be told, and 2 in 100 needs to be told again, and 1 in 100 doesn't give a rat's fuzzy behind anyway!!) * Forgetting to take checkpoints when disassembling large files. You may even want to rotate the names under which things are saved: STEMP1.SYM STEMP1.CTL STEMP1.DOC * Missing a label: Suppose you have a control entry for a DW, resulting in: DFLT: ;172C DW 100H but somewhere in the program, the following exists: LDA 172DH Even if you did a B and have a label L172D, it won't show up since it's in the middle of a DW. Instead, do this: KL172D Kill the old label E172D,DFLT+1 Put in the new label as a displacement off the beginning. * improperly disassembling DW's (see previous item). You might be tempted to make DFLT a DB so that DFLT: ;172C DB 0 L172D: ;172D DB 1 Note that while this disassembles and reassembles properly, it is not "as correct" as the technique used in the previous item. * Having the "B" command overlay your "E" control entry. What? Well, "B"uild is pretty dumb. If he finds 8 DB type characters in a row, he fires off a DB from then on until he runs out of those characters. Suppose your program was 200 long (ended at 3FF), and you had zeroed (aha! Nice DB candidates) memory there (there meaning at your offset address + whatever). Then you QB100,400 and viola!! TR.COM overlaid your "E" control with a "B". ---------------- TR.COM is relatively complete. (well, actually, the phrase "rampant featureitis" has been "mentioned")....But there's always another day, and another K... SO... Here's a "wish list" of things that may be included in a future version...it might save you telling me YOU think such-and-such would be nice... * E5C,.FCB followed by E6C,.FCB+ should automatically calculate the appropriate displacement, and put it in the symbol table. * The comments facility should be enhanced to allow total SUBSTITUTION of entire line(s) of the code, i.e. at address such-and-such, replace the next 3 bytes with the following arbitrary line. This would help those "how do I explain what was being done" cases such as: LXI H,BUFFER AND 0FF00H * Add the ability to, in one instruction, rename a default (LXXXX) label to a meaningful name. * Include labels that are imbedded within instruction codes. CALL 0 which has a label imbedded in the address of the call would show as: CALL 0 TYPADD: EQU $-2 ---------------- .HE EXAMPLE OF TR.COM USAGE Given: a COM file (lets say TEST.COM) which runs at 100 (as any good COM file should), and goes thru 2FF. Lines preceeded with ---> are typed by you. ---> TR.COM ---> O2200 Set the offset to 2200, which means the program will read into 2200 + 100 = 2300. ---> RTEST.COM Reads the .COM file into memory. System says: 2500 0300 which is the actual hi load addr, (2500) and the original hi load addr (300) REMEMBER this address (300) because you might want to put a "E" (end of assembly) control entry there. <<<>>> That all 'L' (disassembly list) and 'D' (dump) commands work with the offset added. Thus, you should learn to forget that the disassembler is in memory, and think of it as if your program were actually at 100. D100 will dump your program. ALSO: If the program being disassembled will have a fairly large symbol table, then you will have to set the offset higher: 02F00 or some such. (The ? command will show symbol table usage: if your symbol table is nearing the .COM file, then just set a new offset (higher) and re-load the .COM) If you want to dump R-E-A-L memory, you would have to reset the offset to 0: o0 (but don't forget to reset it to 1F00 before continuing with your program.) If you are disassembling something which is in memory at it's correct address (such as looking at CCP) then don't set the offset. It defaults to 0 when TR is first loaded. ---> L100 List your program - lists "about" 10 lines. ---> D100 Do a dump of your program. NOTE: That typically here are the steps to disassembling a program which has just been read into memory: Use the dump command to find the ASCII DB areas. Note that the 'A' command may be used to automatically find the db's, but you must then check them to insure that they don't extend too far. All printable characters, 0DH, 0AH, 09H, & 00H are considered candidates for ASCII db's. At least 8 characters in a row must be found to make sure that long sequences of mov instructions won't be taken as db's. Use the CNNNN,K command to kill erronious entries put in the control table by the a command, but then immediately put in the right address, such as via CNNNN,I If you wanted to scan the program for ASCII db's yourself, use the 'C' (control) command to set the beginning and end of ASCII areas. For example, a program which starts out: 0100 JMP START 0103 DB 'COPYRIGHT .....' 0117 START: would show up in the dump as: 0100 C3170144 4F50xxxx xxxxxxxx xxxxxxxx *...COPYR IGHT....* 0110 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx *xxxxxxxx ........* Thus you would want to instruct the disassembler to switch to db mode at 103, and back to instruction mode at 117, thus: C103,B C117,I Continue doing this, bracketing every ASCII db which is in the middle of instructions, by a b control instruction and an I control instruction. Note that multiple db's in a row need not have separate CNNNN,B instructions, but that these do cause a 'line break', i.e. if you have a table of ASCII commands, for example: 02E5 db 'load' 02E9 db 'save' the disassembler would disassemble these as: 02E4 db 'loadsave' You could put in an additional control entry: C2E9,B, which would cause the disassembler to generate: 02E4 db 'load' 02E8 db 'save' which is much more readable and realistic. Note that before generating each byte of a db, a symbol table lookup is done to determine if there is a label at that location, and if so, a new line is started. Thus if 'LOADLIT' and 'SAVELIT' were in the symbol table, as the labels on the 'load' and 'save' above, no separate 'B' control instruction would be required as the label would cause the break. <<<>>> Automatic label checking is N-O-T done for ds instructions. Make sure that each ds instrucion references only up to the next label. This means that multiple ds's in a row must each be explicitly entered into the control table. Presence of a label is not sufficient. After building the control entries with cNNNN,b and cNNNN,i put in a control entry CNNNN,E which defines the address of the end of your program. The L command will then automatically stop there, and in addition, if you are in 'SAVE XXX.ASM' mode, the output .ASM file will be closed. If you do mot define a control 'E' entry, then you will have to use the break facility to stop the L command (don't use control-c as that will re-boot CP/M). If you were writing an .ASM file, you would have to user the Z command to close the file. Next, you would list your program to determine how it looks. When you recognize a routine by it's function, insert a label. For example, if you saw that location 7EF was a character out routine (type) then enter a label into the symbol table: E7EF TYPE NOTE that if you want the disassembler to make default labels for you, use B (for build labels) instead of L (for list program). The B commands causes LNNNN default labels to be inserted in the symbol table for every 2 byte operand encountered (LXI, SHLD, JMP, etc). It will undoubtedly make some you don't want, such as L0000. You will have to: K L0000 Kill label L0000 from the table. When you encounter data reference instructions, try to determine what type of area the instruction points to. Typically,, LXI instructions may point to a work area which should be defined as a DS, or to an ASCII string, in which case we will have already made it a 'B' control instruction. Operands of LHLD and SHLD instructions should be made DW instructions. For example if you encounter LHLD 0534H, then issue a control instruction: C534,W NOTE that whatever mode you are last in will remain in effect. Therefore if 534,W is the last entry in the control table, all data from there on will be taken to be DW's. Suppose that you determine that address 7CF is a 128 byte buffer for disk I/O. You want it to disassemble to: DISKKBUF: ;07CF DS 80H You do this as follows: C7CF,S To start the DS C84F,B To define it's end, and E7CF,DISKKBUF To put the symbol in the table. Continue, iteratively using the 'L' command and the 'C' and 'E' commands until you have the listing in a nice format. You will then probably want to save the control symbol, and comments tables. Or, you could have been saving them at checkpoint times (so if you make a major mistake you could go back to a previous one). To save a control file: SFILENAME.CTL (Any filename, may include A: or B:) To save a symbol file: SFILENAME.SYM To save a comments file: SFILENAME.DOC (not ".COM" of course) NOTE that the filetypes must be used as shown, but that any legal filename (or disk:FILENAME such as B:XXXX.CTL) may be used. You could now control-c to return to CP/M, and come back later to resume your disassembly: ---> TR ---> O2200 ---> RTEMP.COM ---> RTEMP.SYM ---> RTEMP.CTL ---> UXXXX (such as U4000) ---> RTEMP.DOC This will take you back exactly where you left off. Or you could use the default type load: ---> TR ---> RTEMP.* .CTL .SYM SETTING OFFSET = 4000 .COM SETTING COMMENT TABLE = 5700 .DOC If you want to save a .ASM file out to disk, do the following: Make sure that there is a control entry defining the end of the program (such as c200,e) or else you will have to specify the ending address and manually type a z command to close the file. SFILENAME.ASM A message will indicate that the file is opened. Any subsequent A, B, or L command will have whatever is listed written to disk. Encountering a 'E' control, or typing a 'Z' command will then close the .ASM file. The listing may be interrupted, and continued. Since the L command types only 10 lines, use LADDR,FFFF to list thru the end of the assembly. If this is the 'final' save of the .ASM file, you will probably want to put an 'ORG' at the beginning of the output file, as well as generate EQU instructions for any references outside of the program. For example, a typical CP/M program will have references to: BDOS at 5 FCB at 5Ch TBUFF at 80h The 'P' (for prologue) command generates the ORG, then scans the symbol table and generates equates: BDOS EQU 05H FCB EQU 05CH (etc.) If you have an 'E' control entry in your file, you can list as follows: LADDR,FFFF - the listing will continue until the 'E' control entry is found Now lets try a more complete example, this time we'll work on a program named TODOC. For the sake of identification, commands entered from the console are shown in lowercase only, and are terminated with a return. Comments not entered by the disassembler are shown on the right side... A>tr ;Call TR from CP/M TR.COM ;Signs on *rtodoc.* ;Tell it to Read TODOC.* ** TR REPLIES ** .CTL <-- FILE NOT FOUND .SYM -> SETTING OFFSET = 3600 .COM 3980 0380 -> SETTING COMMENT TABLE = 3A00 .DOC SYMBOL TABLE = 3000 314B CURRENT PC = 0100 PROGRAM OFFSET = 3600 COMMENT TABLE = 3A00 3C5B CONTROL TABLE = 2A00 2A03 Memory open to DE05 ** WHAT HAPPENED & WHAT ITS TELLING YOU ** .CTL <-- FILE NOT FOUND It was not able to find TODOC.CTL on the disk .SYM -> SETTING OFFSET = 3600 It found and read TODOC.SYM, but the offset for reading the .COM file was to low, so it reset the offset at 3600H. .COM 3980 0380 -> SETTING COMMENT TABLE = 3A00 It found and read TODOC.COM, the last address used was 0380H, which is offset to 3980H. The base address for the comment table was to low so it reset the table to 3A00, just above the .COM file. .DOC It found and read TODOC.DOC with no problems. SYMBOL TABLE = 3000 314B ;Table starts at 3000h, ends at 314B CURRENT PC = 0100 ;The next address to be listed is 0100H PROGRAM OFFSET = 3600 ;The .COM file offset is 3600H COMMENT TABLE = 3A00 3C5B ;Table runs from 3A00H to 3C5BH CONTROL TABLE = 2A00 2A03 ;Table runs from 2A00H to 2A03H Memory open to DE05 ;The top of the TPA is 0DE05H *qa100,380 ;Quietly Attempt to find DB's *l100 ;List code starting at 100h ;SET STACK & CHECK FOR NAME 0100 LXI SP,0FEH ;No label is symbol table for 0103 LDA 5DH ;either of these two addresses 0106 CPI '!' 0108 LXI D,NONAME 010B JZ FINIS ;COPY FILENAME 010E LXI H,FCB 0111 LXI D,OFCB 0114 MVI C,9 *m65 5c ;math check for 065H and 05CH + = 0C1H ;065H + 05CH = 0C1H - = 9 ;065H - 05CH = 9 ;(65H is address of CP/M default file type) * = 244CH ;065H * 05CH = 244CH / = 1 ;065H / 05CH = 1 MOD = 9 ;065H MOD 05CH = 9 AND = 44H ;065H AND 05CH = 44H OR = 7DH ;065H OR 05CH = 7DH XOR = 39H ;065H XOR 05CH = 39H *e65 filetype ;Enter a label named FILETYPE at 065H *e7c fcb+32 ;Enter a label named FCB+32 at 07CH *e5d,filename ;Enter a label named FILENAME at 05DH *l ;Continue listing MVFN: 0116 MOV A,M 0117 STAX D 0118 INX H 0119 INX D 011A DCR C 011B JNZ MVFN ;FORCE SOURCE TO .PRN 011E DB '!e',0,'6P#6R#6N' <-- Doesn't look like a string ;OPEN SOURCE 0129 XRA A 012A STA FCB+32 012D LXI D,FCB 0130 MVI C,0FH *kc11b,12a ;Kill all control table entries between ;011Bh and 012Ah CONTROL TABLE = 2A00 2A0C ;Latest control table beginning & end Memory open to DE05 ;TPA hasn't moved *l11b ;List starting at 011BH to see what ;removing entries did ;FORCE SOURCE TO .PRN 011E LXI H,FILETYPE 0121 MVI M,'P' 0123 INX H 0124 MVI M,'R' 0126 INX H 0127 MVI M,'N' ;Obviously the string was the ;code shown here ;OPEN SOURCE 0129 XRA A *l306,360 ;List code from 0306H thru 0360H 0306 'file',0DH,0AH,'$' ;VARIABLES ;This comment is a give away IPTR: 030D RST 7 ;Must not be code 0310 MVI B,0 OFCB: 0312 DB 0,'FILENAMEDOC',0,0,0,0,0 0323 DB 0,0,0,0,0,0,0,0,0,0,0,0,0 0330 DB 0,0,0,0,0,0,0,0,0,0,0,0,0 033D DB 0,0,0,0,0,0,0,0,0,0,0,0,0 OLDNO: 034B DB ' ' NUNUM: 034C DB 0,0,0,0,0,0,0,0,0,0,0,0,0 0359 DB 0,0 CMTCHR: 035B DB 0,0,0,0,0 *kc306,360 ;Removing all control entries ;between 0306h and 0360h CONTROL TABLE = 2A00 2A06 ;New table ends Memory open to DE05 ;Same memory top *c30d,w ;Code after 30DH is words *c310,b ;Code after 310H is bytes *c320,s ;Code after 320H is space *c346,b ;Code after 346H is bytes *c34c,s ;Code after 34CH is space *c35b,s ;Code after 35BH is space *l306,360 ;List code again 0306 DB 'file',0DH,0AH,'$' ;VARIABLES IPTR: 030D DW 05FFH ;New listing shows an address OPTR: ;A new address that didn't show before 030F DW OBFR CURCHR: 0310 DB 0 OFCB: 0312 DB 0,'FILENAMEDOC',0,0 0320 DS 0026H ;Space instead of zeros OLDNO: 034B DB ' ' LINE: 034B DB 0 NUNUM: 034C DS 000FH ;Spaces instead of zeros CMTCHR: 035B DS 0025H *c380,e ;Set end of program *stodok.* ;Save all files under new name .CTL ;Saving TODOK.CTL .SYM ;Saving TODOK.SYM .DOC ;Saving TODOK.DOC .ASM ++WRITING .ASM ENABLED ;Saving TODOK.ASM ENABLED USE Z COMMAND OR E CONTROL TO CLOSE FILE++ *** At this point we will need to include the program *** *** origin and all of the labels that are not contianed *** *** within the program itself. No other read or writes *** *** can occur until the .ASM file is closed. *** *p100,37f ;Prolog with all labels out ; ;side of the range 0100H and 037FH ;DISASSEMBLY OF: ; TODOC.COM ; ORG 0100H BDOS: EQU 05H FCB: EQU 5CH FILENAME: EQU 5DH FILETYPE: EQU 65H IBFR: EQU 0500H OBFR: EQU 0600H ;Last line of prolog *ql100,400 ;Quietly list 100H thru 400H ;which sends data to .ASM file 0380 END ;It got the end of file control ++ASM FILE CLOSED++ ;and closes the file itself *^C ;Control-C exits back to CP/M A> .HECOMMAND SUMMARIES FOR TR.COM - VERSION OF 11/16/85 SHORT COMMAND SUMMARY ===================== ; Dump comments table L List (Disassemble) ? List memory settings M Mathmatics functions ^ Poke address with byte N No address toggle A Attempt to find DB O Show current offset B Build dflt syms P Prolog for ORG & EQU's C Alter control table Q Quiet mode (no console out) D Dump memory R Read file E Enter symbol into table S Save file F Find next occurrence U Use addr for comments Hx Help with command "x" X Purge symbols and control I Increment symbols Z Close .ASM file DETAILED COMMAND SUMMARY ======================== Addr Means a hex address, or a symbol [xx] Means an optional operand. Multiple addresses must be separated by either comma's, spaces, dots, colins, or semi-colins. ; Dump comments table ;addr,COMMENT Put in comment ;addr, Delete comment ? List memory manager settings ^addr,byte Poke addr with value of byte A[addr][,addr] Attempt to find DB B[addr][,addr] Build dflt syms Caddr Dump ctl from addr Caddr,K Kill ctl entry Caddr,type Add ctl entry: B = Byte E = End H = Hex byte I = Instructions S = Space W = Word D[addr][,addr] Dump memory D=nn Change default dump size DS[SYMBOL] Dump symbol table Eaddr,.SYMbol Enter/replace symbol into table F Find next occurrence Faddr[,strtadr] Find occurrence of address following start H Help with commands Hx Help with command "x" Iaddr,offset Increment every symbol from addr on, by "offset" K SYMBOL Kill symbol entry KCaddr,addr Kill all control entries between addresses L[addr][,addr] List (Disassemble) L=nn Change default # lines in list M addr,addr Mathmatics operations on addresses N No address comments toggle O Show current offset Oaddr Set offset for disassembly Paddr,addr Prolog: ORG first addr, EQU's for all "outside" symbols Q any command Quiet mode (no console out) RFILENAME.typ Read .COM, .DOC, .CTL, or .SYM file RFILENAME.* Read .COM, .DOC, .CTL, and .SYM file sequentially and automatically set offset and comment base if needed. SFILENAME.typ Save .ASM, .DOC, .CTL, or .SYM file SFILENAME.* Save .ASM, .DOC, .CTL, and .SYM files sequentially Uaddr Use addr for comments table X Purge all symbols and control Z Close .ASM file