english
version "1.0"
identify "xyz"

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

module opcodes


#: Some routines for constructing expressions:

procedure bit
    takes
	xregister expression
	bit_number unsigned
    returns expression

    #: This procedure will create and return a bit address expression
    #, consisting of {xregister} 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
    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 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 reg
    takes
	xregister unsigned
    returns expression

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

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
	left expression
	right expression
    returns expression

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


procedure buffer_append@expression
    takes
	expression expression
	buffer string
    returns_nothing

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


procedure create@expression
    takes_nothing
    returns expression

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


procedure divide@expression
    takes
	left expression
	right expression
    returns expression

    #: This procedure will return an expression that represents the
    #, division of {left} by {right}.


procedure format@expression
    takes
	expression expression
	out_stream out_stream
	format_string string
	offset unsigned
    returns_nothing

    #: This procedure will output {expression} to {out_stream}.


procedure multipy@expression
    takes
	left expression
	right expression
    returns expression

    #: This procedure will return an expression that represents the
    #, multiplication of {left} by {right}.


procedure value_get@expression
    takes
	expression expression
    returns value

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


procedure subtract@expression
    takes
	left expression
	right expression
    returns expression

    #: This procedure will return an expression that represents the
    #, subtraction of {left} from {right}.


#: {assembler} procedures:

procedure address_equate_process@assembler
    takes
	assembler assembler
	address_equate_binary binary
    returns_nothing

    #: This procedure will process define {constant_name} to be
    #, equivalent to {constant_number}.


procedure binary_opcode_process@assembler
    takes
	assembler assembler
	opcode12 unsigned
	opcode14 unsigned
	binary_opcode binary_opcode
    returns_nothing

    #: This procedure will process a binary assembler opcode.


procedure bit_address_process@assembler
    takes
	assembler assembler
	opcode12 unsigned
	opcode14 unsigned
	bit_address_expression expression
    returns_nothing

    #: This procedure will process a bit address assembler opcode.


procedure bit_address_define_process@assembler
    takes
	assembler assembler
	bit_address_trinary trinary
    returns_nothing

    #: This procedure will process define {bit_name} to be the
    #, {bit_number}'th bit of register {regester_name}.


procedure code_address_process@assembler
    takes
	assembler assembler
	opcode12 unsigned
	opcode14 unsigned
	expression expression
    returns_nothing

    #: This procedure will process a code address assembler opcode.


procedure configure_process@assembler
    takes
	assembler assembler
	configure configure
    returns_nothing

    #: This procedure will process a configure assembler opcode.


procedure constant_equate_process@assembler
    takes
	assembler assembler
	constant_equate_binary binary
    returns_nothing

    #: This procedure will process define {constant_name} to be
    #, equivalent to {constant_number}.


procedure create@assembler
    takes
	standard_out out_stream
	error_stream out_stream
	pic_type pic_type
    returns assembler

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


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
	count unsigned
    returns_nothing

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


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
	opcode12 unsigned
	opcode14 unsigned
	expression expression
    returns_nothing

    #: This procedure will process an immeidate literal assembler opcode.


procedure instruction_process@assembler
    takes
	assembler assembler
	instruction12 unsigned
	instruction14 unsigned
    returns_nothing

    #: This procedure will output {instruction} to {assembler}.


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 register_process@assembler
    takes
	assembler assembler
	opcode12 unsigned
	opcode14 unsigned
	expression expression
    returns_nothing

    #: This procedure will process a register assembler opcode.


procedure register_equate_process@assembler
    takes
	assembler assembler
	register_equate_binary binary
    returns_nothing

    #: This procedure will process define {register_name} to be
    #, equivalent to {register_number}.


procedure statement_process@assembler
    takes
	assembler assembler
	statement statement
    returns_nothing

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


procedure tris_process@assembler
    takes
	assembler assembler
	expression expression
    returns_nothing

    #: This procedure will process a register assembler opcode.


#: {binary} routines:

procedure buffer_append@binary
    takes
	binary binary
	buffer string
    returns_nothing

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


procedure create@binary
    takes
	left expression
	right expression
    returns binary

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


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}.


#: {binary_opcode} procedures:

procedure create@binary_opcode
    takes
	source expression
	destination destination
    returns binary_opcode

    #: This procedure will create and return a {binary_opcode} object
    #, containing {source} and {destination}.


#: {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
	xregister unsigned
	bit_number unsigned
    returns bit_address

    #: This procedure will create and return a {bit_address} object
    #, that contains {xregister} and {bit_number}.


#: {configure} routines:

procedure create@configure
    takes
	oscillator oscillator
	watch_dog_timer_enable logical
	power_up_timer_enable logical
	code_protect logical
	mclr_enable logical
	brown_out_enable logical
    returns configure

    #: This procedure will create and return a {configure} object
    #, containting the arguments.


#: {opcode} procedures;

procedure binary_opcode_buffer_append@opcode
    takes
	opcode_string string
	binary_opcode binary_opcode
	buffer string
    returns_nothing

    #: This procedure will append {opcode_string} and {binary_opcode}
    #, to {buffer}.


procedure buffer_append@opcode
    takes
	opcode opcode
	buffer string
	assembler assembler
    returns_nothing

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


procedure create@opcode
    takes_nothing
    returns opcode

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


procedure configure_append@opcode
    takes
	configure configure
	buffer string
	assembler assembler
    returns_nothing

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


procedure expression_buffer_append@opcode
    takes
	opcode_string string
	expression expression
	buffer string
    returns_nothing

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


procedure instruction_buffer_append@opcode
    takes
	opcode_string string
	buffer string
    returns_nothing

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


procedure processor_append@opcode
    takes
	processor processor
	buffer string
    returns_nothing

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


#: {processor} routines:

procedure create@processor
    takes
	pic_type pic_type
    returns processor

    #: This procedure will create and return a {processor} object
    #, containting {pic_type}.


#: {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 output@memory_image
    takes
	memory_image memory_image
	hex_stream out_stream
    returns_nothing

    #: This procedure will output {memory_image} to {hex_stream}
    #, as an Intel Hex8 format file.


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} procedures:

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
	listing logical
	assembler assembler
    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
	xregister unsigned
	bit_number unsigned
    returns_nothing

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


procedure create@symbol_table
    takes_nothing
    returns symbol_table

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


procedure constant_insert@symbol_table
    takes
	symbol_table symbol_table
	name string
	new_constant unsigned
	assembler assembler
    returns_nothing

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


procedure register_insert@symbol_table
    takes
	symbol_table symbol_table
	name string
	new_xregister unsigned
	assembler assembler
    returns_nothing

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


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.


procedure create@trinary
    takes
	left expression
	middle expression
	right expression
    returns trinary

    #: This procedure will create and return a {trinary} object
    #, containing {left, {middle}, and {right}.


#: {value} procedures:

procedure bit_address_create@value
    takes
	bit_address bit_address
    returns value

    #: This procedure will create and return a {value} object that is of type
    #, bit address and contains {bit_address}.


procedure code_address_create@value
    takes
	code_address unsigned
    returns value

    #: This procedure will create and return a {value} object that is of type
    #, code address and contains {code_address}.


procedure constant_create@value
    takes
	constant unsigned
    returns value

    #: This procedure will create and return a {value} object that is of type
    #, constant and contains {constant}.


procedure create@value
    takes_nothing
    returns value

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


procedure register_create@value
    takes
	register_number unsigned
    returns value

    #: This procedure will create and return a {value} object that is of
    #, type register and contains {register_number}.


procedure string_create@value
    takes
	text string
    returns value

    #: This procedure will create and return a {value} object that is of type
    #, string and contains {text}.


#: Some stand-alone procedures:

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.