Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
tree: 4c0e11e25f
Fetching contributors…

Cannot retrieve contributors at this time

236 lines (153 sloc) 6.488 kb
# cowMachines processor simulator
Copyright (c) 2012 Tamber Penketh <tamber@furryhelix.co.uk>
## Description
The cowMachine is a simple, stack-based design; with two stacks (data
and return), 2 stack counters, program counter, and some program
memory.
It is designed to be relatively easy to experiment with, and tweak.
The word-width of the 'machine' is adjustable by choosing a different
make target.
By default, the word-width is 8 bits. To change this, use the
corresponding argument to make:
8-bit - make
16-bit - make 16
32-bit - make 32
64-bit - make 64
As standard, the cowMachine has 512 kilowords of program memory; and
stacks 5 deep. Both of these can be changed very easily:
To increase the amount of memory available, change `MAIN_MEM_SIZE`
in sim.h. `KILOWORD` and `MEGAWORD` are defined for convenience.
To increase the depth of the stacks, change `DATA_STACK_DEPTH`,
`RET_STACK_DEPTH` and `INTR_STACK_DEPTH` in sim.h
Both of these changes require a recompile.
## Why 'cowMachine'?
Because I had µ (mu) stuck in my brain whilst thinking about
microprocessors, so it got stuck with the name muPU. If you read that
out loud, and you're almost as childish as I am, you'll see a small
issue with it. And so, it became the cowMachine.)
## License
Permission to use, copy, modify, and distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all
copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
# Building the cowMachine
Building the cowMachine, with GCC and GNU Make, is simply a matter of
typing `make` (or `gmake`).
So far, the makefile relies on `gcc` existing. I'll get around to
fixing this to be more considerate of other platforms eventually.
Reports of how well it compiles under other compilers and platforms
(And patches, for strangeness, if possible) are very welcome.
The cowMachine has been tested on:
* amd64 Linux 3.1.4, Binutils 2.21.1, with GCC 4.5.3
* amd64 FreeBSD 8.2-RELEASE, GCC 4.2.1
* i386 Solaris (OpenIndiana) oi_151a3, GCC 3.4.3 (csl-sol210-3_4-20050802)
Theoretically, it should build on any POSIX platform with a c89
compiler. (Including Windows, if you use MinGW.)
Reports of disasters occurring on other platforms, with core files,
etc as appropriate welcomed; patches to fix said disasters even more
welcome!
# Programming the cowMachine
The cowMachine's instruction format is very simple, theoretically
based on Forth; and should be easy to understand if you know that
meta-language.
The Forth program needs to be converted into binary format to be
executable on the cowMachine; a process that, so far, has to be done
manually.
However, this is rather simple, if time consuming; and the binary
executable format is intentionally very simple.
It consists of a 4-byte header, then the machine-code of the program
you want to execute; which is loaded into the program memory. Nothing
more.
To create an executable format file, which is loaded into the
cowMachine by running ./cm -e <path to executable> (or
./cm.<wordwidth>, if you're using a larger cow), one needs to:
1. Add the 4 byte header to the file.
2. Manually convert/assemble your Forth to the binary format.
3. Tear hair out
4. Attempt to run
5. until successful, GOTO 2
## Binary header
Each cowMachine executable has a 4 byte header before the actual
assembled code.
The header format is as follows:
2 octets - signature - 0x4D 0x55 ("MU")
1 octet - target word length
1 octet - 0x00 as padding.
The signature, 'MU', is required; or the loading mechanism will reject
the file.
The target word length octet is, simply put, the hex representation of
the number of bits in a word the author of the .cow file was writing
for.
This is to prevent Bad Things from happening if one was to try run an
executable written for a 64-bit cow, on an 8-bit cow.
The padding byte is there simply to align the header to 32 bits.
**Note**: It is likely that endianness will cause issues when trying
to write/read executable files for >=16-bit cows; if this is the case,
the padding byte *may* be changed to instead indicate version of
executable format, to accommodate extension of the header, to handle
endianness and other features.
## Machine-code
Below are a list of the currently implemented, and planned,
instructions; they are listed with their opcode, name, equivalent
Forth symbol, stack effect and a description.
### 0x00 halt
()
Stops execution of the program.
### 0x01 store
! (n1 addr -- )
Store value n1 at location addr in program memory
### 0x02 fetch
@ (addr -- n1)
Fetch value from location addr in program memory
### 0x03 push
( -- n1)
Two-word instruction. First word is the op-code (0x03); second is the
value to push onto the data stack.
### 0x04 add
+ (n1 n2 -- (n1 + n2))
Add the top two values from the stack together, pushing the result
onto the top of the stack.
### 0x05 subtract
- (n1 n2 -- (n1 - n2))
Subtract the value at the top of the stack, from the value second on
the stack; pushing the result onto the top of the stack in their place.
### 0x06 drop
drop (n1 n2 -- n1)
Discard the value currently at the top of the stack.
### 0x07 dup
dup (n1 -- n1 n1)
Duplicate the value currently at the top of the stack.
### 0x08 over
over (n1 n2 -- n1 n2 n1)
Duplicate the value currently at #2 on the stack to the top of the
stack.
### 0x09 xor
Bitwise XOR of the top two values on data stack
### 0x0A or
Bitwise OR of top two values on data stack
### 0x0B and
Bitwise AND of the top two values on the stack
### 0x0C NOT
Bitwise NOT of the top two values on the stack
### 0x0D LSH
( n1 n2 -- (n1 << n2) )
Logical left shift of top value on stack
### 0x0E RSH
( n1 n2 -- (n1 >> n2) )
Logical right shift of top value on stack
### 0x0F IF
### 0x10 CALL
### 0x11 RET
# Not yet implemented (TODO list)
See ./TODO.
# Bugs
* Lots
* Probably some related to endianness
Jump to Line
Something went wrong with that request. Please try again.