TMS-7000 Assembler Program Version 2.1 This program takes ASCII source code files for the Texas Instruments' TMS-7000 series microprocessors and assembles them into executable object code files ready to be burned into an EPROM. The Assembler can operate with several different types of input source files. The length of the source file is limited only by the amount of memory in your PC. The maximum length of the assembled object code file is 64K. This assembler is fast, but achieves this speed by hogging memory. It allocates 1 64K segment for itself and the Symbol Table, 1 64K segment for the assembled object code file, and the remainder of memory for the source file. I assembled a 271K source file into a 16K object file in 16 seconds on an 8 MHz PC-XT Clone with 640K. The TMS-7000 Assembler has a number of features for the VCII software experimenter. I have included a pseudo-op for assembling packed strings for display using the VCII U6 chip. The "DM" pseudo-op takes all text inside quotation marks and converts it into the equivalent U6 packed character set. In addition, the Define Word "DW" and the Define Byte "DB" pseudo-ops can perform limited math functions to locate addresses based on the values of symbols. This is release 2.1 of this assembler and most of the rough spots have been worked out. Several bugs were fixed and some enhancements added to make the Assembler easier to use. I would appreciate any comments you may have regarding its ease of use and functionality. The following sections describe the features of the Assembler. Send comments or suggestions to - Bill Meeks 1918 Tap Road Vidalia, GA 30474 NEW FEATURES OF THE ASM7000 TMS-7000 ASSEMBLER Several new features have been added with release 2.1 of the Assembler. These are explained below. 1) The Assembler can now take the Source and Object Code filenames directly from the command invocation line. The filenames must be separated by a space and must be a valid MS-DOS pathname/filename. The Syntax from the DOS prompt is as follows -- C:> ASM7000 sourcefile.ext objectfile.ext where sourcefile.ext is the Source Code Filename and objectfile.ext is the Object Code Filename. If no filenames are given on the command invocation line, the Assembler will prompt you for them as before. 2) The Assembler also has been given a much expanded error reporting routine, with more detailed Error Messages and the offending line of source code is displayed on the screen so that the error is more easily identified. For SYMBOLS/LABELS, the name of the referenced symbol or label is printed whenever an error is encountered involving it. 3) The Assembler will now take up to 10 characters in a SYMBOL/LABEL name. This 10 character count does not include the Symbol/Label identifier (a, d, or L). The requirement for an identifier was retained in this release to insure compatability with most of the disassemblers. 4) The sorting routine for sorting the Symbol Table prior to beginning the second assembly pass has been greatly improved for speed. The routine now uses a Shell/Metzner sort algorithm and completes the sort in about 1/5 of the time of the old Bubble Sort algorithm. KNOWN BUGS REPAIRED IN RELEASE 2.1 1) Release 1.0 had a potential bug in the loading of Source Code files of over 64K in length. The bug was intermittent in that only occassionaly would it cause an assembly error. The cause has been identified and corrected in release 2.1. 2) The Assembler now correctly recognizes PUSHST or POPST as the same instruction as PUSH ST or POP ST. Release 1.0 reported an error with the PUSH ST or POP ST form of the instruction. 3) Release 1.0 would go ahead and create the object code file on the disk with a length of 0 bytes before actually doing the assembly. The file would be written at the end of the assembly process. Errors during assembly resulted in the file being left on the disk with a 0 length. Release 2.1 only checks to see if the object code filename already exists on the disk and reports if it does. It does not actually create the file until after assembly when it is ready to write to it. This eliminates the 0 file length bug. PSEUDO-OPS --- RADIX -- The Radix pseudo-op establishes the default base for CPU register numbers. It is a required statement in all source files and must come before any Instruction Mnemonics. The only valid arguments for Radix are 10 and 16 for decimal and hexadecimal bases respectively. Example - RADIX 10 ;sets base to 10 RADIX 16 ;sets base to hex ORG -- The Origin pseudo-op establishes the beginning address for the assembled object code. Multiple ORG statements are allowed, however; in release 2.1, ORG statements with an address below the current assembly address are ignored. Example - ORG >F000 ;sets address to F000 ORG >FFD0 ;sets address to FFD0 The ">" sign is optional and denotes a hex number follows. In release 2.1, only hexadecimal addresses are allowed. EQU -- The Equate pseudo-op sets a value for a symbol. Subsequent references to that symbol cause the value given by EQU to be substituted. Example - APORT: EQU >0104 Subsequent references to APORT cause the assembler to return the value 0104. DB -- The Define Byte (DB) pseudo-op converts the value following the DB statement into a hexadecimal byte. Special cases allow the 2 arithmetic operators "/" and "MOD" when used with Symbols. Example - DB >4D ;causes 4D to be stored at ;current address DB aDPORT/256 ;causes the value ;of DPORT to be ;divided by 256 and ;the high byte saved ;at the current ;address DB aDPORT MOD 256 ;causes the ;value of DPORT ;to be divided ;by 256 and the ;low byte saved ;at the current ;address DM -- The Define Message (DM) psuedo-op generates VCII packed strings from the ASCII string following the statement. The text string must be delimited by quotation marks. Example - DM " DIAGNOSTIC DATA " causes the assembler to generate the following 15 byte sequence in the object code segment - BA EB 83 20 01 90 45 55 88 0A E0 C0 58 0B AE All strings must be an even multiple of 4 characters, such as 4, 20, 160, etc. Only valid U6 characters will be assembled. Invalid U6 characters will be treated as spaces. DW -- The Define Word (DW) psuedo-op causes the value following the DW statement to be converted into a 16-Bit word value and inserted into the object code at the current address. Example - DW >CCD7 ;CCD7 is converted to a hex ;word and stored at the current ;object code address DW dHERE1 ;the hex value of HERE1 is ;stored at the current object ;code address END -- The END psuedo-op is an optional parameter that tells the assembler it is at the end of the source file. This is an optional statement however. The TMS-7000 Assembler is smart enough to know it is at the end of the source file. The END psuedo-op has no arguments. NOTES -- The TMS-7000 Assembler assembles the entire instruction set of the TMS-7000 series CPU's. Because I wrote the assembler to directly take the output of a disassembler, I wrote it so that it can sort through the address field and op-code field and locate the symbols and instructions. There are a couple of catches, however. Example -- F0E3 88 62 47 35 MOVD %>6247,R35 ;put 6247 in R35 In this line from a typical disassembler, F0E3 is the address and "88 62 47 35" is the op-code sequence. My assembler will skip everything until it detects a valid instruction sequence, such as the MOVD. This does leave the assembler vulnerable to some loopholes from time to time. First, ALL instructions must have a space between the instruction mnemonic and the operands for the instruction. Second, some lines of source may have to be modified to delete the address field if it happens to contain an instruction mnemonic. For example the line below would generate an assembler error. FADC 88 62 47 35 MOVD %>6247,R35 The error comes from the F (ADC) part of the address field because ADC is a valid TMS-7000 instruction. This line in the source would have to have the FADC part deleted. There are several other combinations that will confuse the assembler, all involving the address field hex numbers matching instructions, such as FDEC (DEC), CDAC (DAC), etc. There is one other requirement that is peculiar to this assembler. It requires that all labels and or symbols be preceeded by either an "a", "d", or "L". This is necessary so the assembler can pick labels from the other data on the line from typical disassemblers. The only time the "a", "d" or "L" designator is not needed is when the symbol is referenced in the Peripheral File instructions, such as MOVP, ANDP, BTJZP, etc. Also, the assembler treats all memory references less than C000 as absolute values regardless of the preceeding symbol designator. For example, LDA @a6247 would be assembled as 8A 62 47 even though the "a" character denoted a symbol. Labels and Symbols may end either with a space or with the ":" character. The maximum length for labels and symbols is 10 characters. The assembler has a symbol table large enough for approximately 3500 symbols, which should satisfy all requirements.