Tim Harig wrote:
I would think that it would be far better to write two translation
functions where implementations specific code would be stored.
Data values are translated to normal C types before any operations
take place. The arithmetic is done normally without having to deal
with any special conditions. Then when the operation is finished, the
C types are handed back to an implementations specific function which
handles overflow, endian issues, sign issues (1s vs 2s compliment), and
hands back the necessary 9-bit representations for storage. It would be
important, however, to keep operations as simple, atomic, single steps,
as performing multiple operations might proceed normally without regard
for the fact that an intermediate operation would have caused an overflow
in the 9-bit representation.
You don't have to deal with 1s vs 2s complement or endianness [SNIP]
There is NO implementation specific code required!
I am assuming that the original poster, in modeling the his hardware
design, will at some point or another want to represent the binary
structure, not just the arithmatic values, of the data inside of the the
hardware that he is trying to simulate. This would be necessary, for
instance, to know what the I/O pins on a microcontroller would be when
outputing the result of a given calculation. The original poster may not
need this.
This still does not need any implementation specific code. You also
don't have to deal with it for the arithmetic, if you need it at all
just write two functions to do the conversion between the targets
representation and the native C representation.
Having conversion functions is exactly what I suggested above.
The conversion to whatever his virtual machine uses would be application
dependant based on his virtual machine. However, Making the conversion
from whatever format is used by his computer will be different based upon
the scheme that his computer/compiler uses. That makes the conversion
implmentation dependant based on his computer architecture. The process
for down casting a 2s complement number down to whatever 9bit format then is
different then the process of downcasting from a 1s complement to the 9bit
format in whatever compliment.
Furthermore, if the computer uses ones complement, then the sign bit
may need to be taken from different places to perform the 9bit casing
depending on the actual size of the C types which are not defined by
standard which also suggests the need for implementation specific code.
None of which requires any implementation specific code.
If his computer is big endian then he will not have to change anything. If
his computer is litte endian then he will have to swap the extra bit
forward during conversion to make the simulated memory layout match
that of the virtual hardare when modeling the virtual hardware's memory.
Otherise, making a memory dump of the virtual hardware will be inaccurate
as the most significant bit will follow the rest of the bits when
being dumped. Once again, this would be different depending on the
processor architecture of the OPs processor; and therefore, implementation
dependant.
Endedness would not have made any difference if we were dealing with
a virtual architecture less then or equal to 8 bits. Had it been less
then or equal to 8 bits; then, it would instead be important to know that
some architectures cannot write on odd byte boundries and two represented
numbers for the virtual machine would need to be added together within
the hosting archetecture to assure that one does not try to write to
an odd byte and to dump the virtual memory without zero bytes between
the numbers. This would have been a problem using 68000 based computers.
The bottom line is that care is required when working with any binary
data if one needs it to be portable across computers.
None of the things you have raised require any implementation specific
code. All of them require application specific code.
Application specific code is required in determining the parameters of the
virtual machine; but, implementation specific code is required dependant
upon the internal representation of numbers on the computer architecture
and compiler of the hosting computer. These differences need to be taken
into account whenever working with binary data if the user wishes to be
cross platform. It is true, that the methods will always be the same if
the user can assume that the hosting computer is a little endian, 2s
complement computer with a compiler that uses an int size of 16 bits.
If he cannot, then he needs to consider other possibilities. I always
try to make as few assumptions as possible. I have worked under conditions
where these assumptions are invalid.
The good news is that all of these variables only need to be considered
for two functions: the one which converts from the virtual format to
the native format and the one which converts from the native format to
the virtual format. But do not be fooled into thinking that these
functions can be the same for all hosting computers.