#ifndef __LC3_H__ #define __LC3_H__ /* * "Copyright (c) 2014 by Fritz Sieker." * based on ideas/code by Steven S. Lumetta * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written * agreement is hereby granted, provided that the above copyright notice * and the following two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHOR * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" * BASIS, AND THE AUTHOR NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, * UPDATES, ENHANCEMENTS, OR MODIFICATIONS." */ /** @file lc3.h * @brief definitions of the LC3 instruction set architecture (ISA) (do not modify) * @details This defines the details of the LC3 instruction set architecture * (ISA). It is a separate file so that it can be shared by both an assembler * and a simulator. It also include various utility routines. *
* @author Fritz Sieker
*/
#include
* To determine the number of operands an instruction has, simply count the
* 1 bits in the word.
* Here is an algorithum by Brian Kernigan, one of the developers of Unix,
* and co-author of the famous book "The C Programing Language (known as K&R)".
*/
typedef enum operands {
FMT_ = 0,
FMT_RRR = (FMT_R1 | FMT_R2 | FMT_R3),
FMT_RRI5 = (FMT_R1 | FMT_R2 | FMT_IMM5),
FMT_L = FMT_PCO9,
FMT_R = FMT_R2,
FMT_I11 = FMT_PCO11,
FMT_RL = (FMT_R1 | FMT_PCO9),
FMT_RRI6 = (FMT_R1 | FMT_R2 | FMT_IMM6),
FMT_RR = (FMT_R1 | FMT_R2),
FMT_V = FMT_VEC8,
FMT_A = FMT_ASC8,
FMT_16 = FMT_IMM16,
FMT_S = FMT_STR
} operands_t;
/** This structure stores the information for one form of an instruction.
* Several instructions have multiple forms, but most have only one.
*/
typedef struct inst_format {
char* name; /**< human readable name (e.g. "ADD") */
operands_t operands; /**< operands for this operation (e.g. FMT_RRR) */
int prototype; /**< bits that are constant in this instruction */
} inst_format_t;
/** This structure stores the information about a single instruction.
* See the usage in lc3.c where the information for each LC3 instruction
* is defined. The name of the seond form will be NULL
unless
* the instruction actually has two forms.
*/
typedef struct LC3_inst {
int formBit; /**< -1 if instruction has only one format,
else bit that differentiates format. */
inst_format_t forms[2]; /**< syntax for both possible forms */
} LC3_inst_t;
/** Convert an escape sequence to a single character
* @param c the character after the escape character (the back-slash)
* @return the ascaped value of the character
*/
char lc3_escaped_char (char c);
/** Get the information for an instruction, given its opcode This is simply
* an access into an array of values initialized with the information for
* each of the LC3's sixteen instructions and additional pseudo-ops.
* @param opcode - the opcode of the instruction/pseudo-op of interest
* @return - a pointer to the sytax information for this instruction or NULL
*/
LC3_inst_t* lc3_get_inst_info (opcode_t opcode);
/** Convert a operands_t to a "name"
* @param format - the value to convert
* @return - a human readable name
*/
const char* lc3_get_format_name (operands_t format);
/** convert an opcode_t
to a name
* @param op - the opcode to convert
* @return - a human readable name
*/
const char* lc3_get_opcode_name (opcode_t op);
/** convert operand type to a "name"
* @param operand - the type of operand
* @return a human readable name
*/
const char* lc3_get_operand_name (operand_t operand);
/** Read an LC3 word (16 bits) from a file and return the value
* @param f - the object file
* @return the value, or -1 on EOF
*/
int lc3_read_LC3_word (FILE *f);
/** Read the symbol table file and populate the global lc3_sym_tab
* No error checking is performed. It is assumbed the file is in the correct
* format.
* @param sym_file, the file containing the symbol table
*/
void lc3_read_sym_table (FILE* sym_file);
/** Write an LC3 word to a file in binary or hex
* @param f - the file to write to
* @param value - the value to write
*/
void lc3_write_LC3_word (FILE* f, int value);
/** Write the symbol table to a file
* @param sym_file - the file in which the symbol table is written
*/
void lc3_write_sym_table (FILE* sym_file);
/** Convert a string to an integer using either the LC3 syntax, or the
* standard C syntax for a number. The LC3 format assumes hex unless
* the string is preceeded by a # sign. The initial x/X for hex values
* is optional. The C syntac is [+/-] digit [x/X] digit*
* @param token - the string to be converted
* @param value - pointer to where value will be stored
* @return 1 on success, 0 on failure
*/
int lc3_get_int (char* token, int* value);
/** Convert a string to an address. The sting is assumed to be a symbol. If
* it is found in the symbol table, the address is returned via the pointer.
* Otherwise call lc3_get_int() to convert the "number" to an address.
* @param token - the string to be converted
* @param value - pointer to where the address will be stored
* @return 1 on success, 0 on failure
*/
int lc3_get_address (char* token, int* value);
#endif /* __LC3_H__ */