english
version "1.0"
identify "xyz"

#: This module implements a microcontroller assembler op:odes.

module opcodes


#: Some routines for constructing expressions:

procedure bit_addr
    takes
	data_address expression
	bit_number unsigned
    returns expression

    #: This procedure will create and return a bit address expression
    #, consisting of {data_address} and {bit_number}.


procedure chr
    takes
	character string
    returns expression

    #: This procedure will create and return a character expression
    #, containing the first character of {character}.


procedure code_addr
    takes
	code_address unsigned
    returns expression

    #: This procedure will create and return an address expression
    #, containing {code_address}.
    

procedure d
    takes
	decimal unsigned
    returns expression

    #: This procedure will create and return a decimal expression
    #, containing {decimal}.


procedure data_addr
    takes
	data_address unsigned
    returns expression

    #: This procedure will create and return an address expression
    #, containing {data_address}.
    

procedure h
    takes
	hexadecimal unsigned
    returns expression

    #: This procedure will create and return a hexadecimal expression
    #, containing {hexadecimal}.


procedure o
    takes
	octal unsigned
    returns expression

    #: This procedure will create and return a hexadecimal expression
    #, containing {octal}.


procedure s
    takes
	symbol_name string
    returns expression

    #: This procedure will create and return a symbol expression
    #, containing the symbol named {symbol_name}.


#: {expression} routines:

procedure add@expression
    takes
	expression1 expression
	expression2 expression
    returns expression

    #: This procedure will return an expression that represents the
    #, addition of {expression1} to {expression2}.


procedure value_get@expression
    takes
	expression expression
    returns value

    #: This procedure will return the {value} of {expression}.


procedure buffer_append@expression
    takes
	expression expression
	buffer string
    returns_nothing

    #: This procedure will append {expression} to {buffer}.


procedure subtract@expression
    takes
	expression1 expression
	expression2 expression
    returns expression

    #: This procedure will return an expression that represents the
    #, addition of {expression1} to {expression2}.


#: {assembler} routines:

procedure address_process@assembler
    takes
	assembler assembler
	address expression
    returns_nothing

    #: This procedure will process emit a 2-bytes of 16-bit address.


procedure absolute_process@assembler
    takes
	assembler assembler
	opcode_value unsigned
	address expression
    returns_nothing

    #: This procedure will process emit a 2-byte instruction with
    #, an 11-bit address


procedure arithmetic_process@assembler
    takes
	assembler assembler
	expression expression
	opcode_base unsigned
    returns_nothing

    #: This procedure will process an arithmetic opcode using {assembler}
    #, with a base of {opcode_base} and an expression of {expression}


procedure bit_process@assembler
    takes
	assembler assembler
	bit expression
    returns_nothing

    #: This procedure will process emit {bit} using {assembler}.


procedure byte_process@assembler
    takes
	assembler assembler
	byte unsigned
    returns_nothing

    #: This procedure will process emit {byte} using {assembler}.


procedure constant_process@assembler
    takes
	assembler assembler
	constant unsigned
    returns_nothing

    #: This procedure will process emit {constant} as an 8-bit constant
    #, using {assembler}.


procedure create@assembler
    takes
	standard_out out_stream
	error_stream out_stream
    returns assembler

    #: This procedure will create and return a new {assembler} object.


procedure data_address_process@assembler
    takes
	assembler assembler
	data_address unsigned
    returns_nothing

    #: This procedure will process emit a 1 byte 8-bit address.


procedure direct_process@assembler
    takes
	assembler assembler
	address expression
    returns_nothing

    #: This procedure will process emit a 1 byte 8-bit address.


procedure error@assembler
    takes
	assembler assembler
	bytes unsigned
	message string
    returns_nothing

    #: This procedure will output an error message of {message} for
    #, using {assembler}.  {bytes} specifies how many bytes long
    #, the instruction is; use 0 if the error is not instruction
    #, specific.


procedure error_pad@assembler
    takes
	assembler assembler
	bytes unsigned
    returns_nothing

    #: This procedure will pad the output stream with {bytes} bytes.


procedure error_announce@assembler
    takes
	assembler assembler
    returns_nothing

    #: This procedure will will generate an error announce header
    #, for the current {statement} in {assembler}.


procedure immediate_process@assembler
    takes
	assembler assembler
	expression expression
    returns_nothing

    #: This procedure will process {expression} as an immediate
    #, (constant) byte value and output it.


procedure immediate16_process@assembler
    takes
	assembler assembler
	expression expression
    returns_nothing

    #: This procedure will process {expression} as an immediate
    #, (constant) byte value and output it.


procedure logical_process@assembler
    takes
	assembler assembler
	binary binary
	opcode_base unsigned
	bit_opcode unsigned
    returns_nothing

    #: This procedure will process an arithmetic opcode using {assembler}
    #, with a base of {opcode_base} and {binary} for expressions.  If
    #, {bit_opcode} is non-zero, it is used for the "op C,bit" insturction
    #, opcode.  Otherwise, it is an XOR which does not have a bit operation.


procedure move_process@assembler
    takes
	assembler assembler
	binary binary
    returns_nothing

    #: This procedure will process a move opcode using {assembler}
    #, {binary} for expressions.


procedure output_close@assembler
    takes
	assembler assembler
	out_stream out_stream
    returns_nothing

    #: This procedure will ensure that {out_stream} is properly
    #, closed (for a file) or flushed (for standard output.)


procedure output_open@assembler
    takes
	assembler assembler
	file_name string
	file_type string
    returns out_stream

    #: This procedure will output an output file named {file_name}.
    #, If {file_name} is the empty string, ??@{out_stream} is returned.
    #, If {file_name} is a single hyphe (-), standard output is returned.
    #, In all other cases, an attempt is made to open {file_name} for
    #, writing.  If the file  is not successfully opened, an error
    #, message is generated that contains {file_type} in it and
    #, ??@{out_stream} is returned.


procedure opcode_process@assembler
    takes
	assembler assembler
	opcode opcode
    returns_nothing

    #: This procedure will process {opcode} for {assembler}.


procedure process@assembler
    takes
	assembler assembler
	program program
	pass unsigned
	listing_stream out_stream
    returns_nothing

    #: This procedure will produce a listing of {program} to {listing_stream}
    #, using {program}.


procedure relative_process@assembler
    takes
	assembler assembler
	address expression
    returns_nothing

    #: This procedure will emit a relative address byte for {address}
    #, using {assembler}.


procedure statement_process@assembler
    takes
	assembler assembler
	statement statement
    returns_nothing

    #: This procedure will process {statement} using {assembler}.


#: {binary} routines:

procedure buffer_append@binary
    takes
	binary binary
	buffer string
    returns_nothing

    #: This procedure will append {binary} to {buffer}.


procedure create@binary
    takes
	expression1 expression
	expression2 expression
    returns binary

    #: This procedure will create and return a {binary} object
    #, containing {expression1} and {expression2}.


procedure operator_buffer_append@binary
    takes
	binary binary
	operator string
	buffer string
    returns_nothing

    #: This procedure will append {binary} to {bufer} as two
    #, expressions separated by {operator}.


#: {assembler1} routines:

procedure error@assembler1[type1]
    takes
	assembler assembler
	bytes unsigned
	message string
	expression1 type1
    returns_nothing
    needs
	procedure format@type1
	    takes type1, out_stream, string, unsigned
	    returns_nothing

    #: This procedure will output an error message of {message} for
    #, using {assembler}.  {message} is formatted to contain {expression1}.
    #, {bytes} is the number bytes for the instruction; use 0 if the
    #, error is not instruction specific.


#: {assembler2} routines:

procedure error@assembler2[type1, type2]
    takes
	assembler assembler
	bytes unsigned
	message string
	expression1 type1
	expression2 type2
    returns_nothing
    needs
	procedure format@type1
	    takes type1, out_stream, string, unsigned
	    returns_nothing
	procedure format@type2
	    takes type2, out_stream, string, unsigned
	    returns_nothing

    #: This procedure will output an error message of {message}
    #, using {assembler}.  {message} is formatted to contain
    #, {expression1} and {expression2}.  {bytes} is the number
    #, bytes for the instruction; use 0 if the error is not
    #, instruction specific.


#: {assembler3} routines:

procedure error@assembler3[type1, type2, type3]
    takes
	assembler assembler
	bytes unsigned
	message string
	expression1 type1
	expression2 type2
	expression3 type3
    returns_nothing
    needs
	procedure format@type1
	    takes type1, out_stream, string, unsigned
	    returns_nothing
	procedure format@type2
	    takes type2, out_stream, string, unsigned
	    returns_nothing
	procedure format@type3
	    takes type3, out_stream, string, unsigned
	    returns_nothing

    #: This procedure will output an error message of {message}
    #, using {assembler}.  {message} is formatted to contain
    #, {expression1}, {expression2}, and {expression3}.  {bytes} is
    #, the number bytes for the instruction; use 0 if the error is
    #, not instruction specific.


#: {bit_address} routines:

procedure create@bit_address
    takes
	data_address unsigned
	bit_number unsigned
    returns bit_address


#: {opcode} routines:

procedure buffer_append@opcode
    takes
	opcode opcode
	buffer string
    returns_nothing

    #: This procedure will append {opcode} to {buffer}.


#: {memory_image} routines:

procedure clear@memory_image
    takes
	memory_image memory_image
    returns_nothing

    #: This procedure will clear out the contents of {memory_image}.


procedure create@memory_image
    takes_nothing
    returns memory_image

    #: This procedure will create and return an empty {memory} object.


procedure fetch1@memory_image
    takes
	memory_image memory_image
	index unsigned
    returns unsigned

    #: This procedure will the {index}'th byte of {memory_image}.
    #, 0xffffffff  is returned if the memory_image location was never
    #, initialized.


procedure store1@memory_image
    takes
	memory_image memory_image
	index unsigned
	value unsigned
    returns_nothing

    #: This procedure will store {value} into the {index}'th byte of
    #, {memory_image}.


#: {statement} routines:

procedure create@statement
    takes
	line_number unsigned
	opcode opcode
	comment string
    returns statement

    #: This procedure will create and return a new {statement} object
    #, that contains {line_number}, {label}, {opcode}, and {comment}.


procedure buffer_append@statement
    takes
	statement statement
	buffer string
    returns_nothing

    #: This procedure will output {statement} to {buffer}.


#: {symbol} routines:

procedure buffer_append@symbol
    takes
	symbol symbol
	buffer string
    returns_nothing

    #: This procedure will append {symbol} to {buffer}.


procedure create@symbol
    takes
	name string
    returns symbol

    #: This procedure will create and return a new {symbol} object.


procedure equal@symbol
    takes
	symbol1 symbol
	symbol2 symbol
    returns logical

    #: This proceudre will return {true} if {symbol1} has the same name
    #, as {symbol2}.


procedure hash@symbol
    takes
	symbol symbol
    returns unsigned

    #: This procudure will return a hash value for {symbol}.


#: {symbol_table} routines:

procedure bit_address_insert@symbol_table
    takes
	symbol_table symbol_table
	name string
	address unsigned
	number unsigned
    returns_nothing

    #: This procedure will insert {name} into {symbol_table} as a bit
    #, address with data address of {address} and a bit number of {number}.


procedure create@symbol_table
    takes_nothing
    returns symbol_table

    #: This procedure will create and return a new {symbol_table} object.


procedure data_address_insert@symbol_table
    takes
	symbol_table symbol_table
	name string
	address unsigned
    returns_nothing

    #: This procedure will insert {name} into {symbol_table} as a
    #, data address with a value of {address}.


procedure fetch1@symbol_table
    takes
	symbol_table symbol_table
	name string
    returns symbol

    #: This procedure will return the symbol associated with {name}
    #, from {symbol_table}.   A new symbol is created if {name} is
    #, not already in {symbol_table}.  {name} is assumed to be
    #, immutable; if it is not, a fresh immutable copy needs to
    #, be created by the caller and passed in.


#: {trinary} routines:

procedure buffer_append@trinary
    takes
	trinary trinary
	buffer string
    returns_nothing

    #: This procedure will append {trinary} to {buffer}.


procedure create@trinary
    takes
	expression1 expression
	expression2 expression
	expression3 expression
    returns trinary

    #: This procedure will create and return a {trinary} object
    #, containing {expression1}, {expression2}, and {expression3}


#: Some stand-alone routines:

procedure opcode_name_append
    takes
	opcode_name string
	buffer string
    returns_nothing

    #: This procedure wil append {opcode_name} to {buffer} and
    #, pad it will enough extra spaces so that a total of 8
    #, spaces are appended.