init_registers()
init_memory(<size>)
init_code(<mem_aref>)
loadbin(<mem_aref>, <bin_aref>)
assemble(<coderef>, <binref>, <errorref>)
disassemble(<mem_aref>, <code_aref>, [<changed_mem_href>])
step(<mem_aref>, <reg_aref>, <changed_mem_href>)
NICE - a module to emulate, assemble and disassemble code for the NICE processor (NICE Is Charmingly Elegant)
This documentation describes the first fully functional version 0.4.
# load module, import all functions use NICE qw/:all/;
# some code as line array my @code = split /\n/, qq{ MOVE R1 R0 MOVE R1 0x125690CD HALT };
# arrays for results, passed by reference my @bin = (); my @errors = ();
# assemble if ( assemble(\@code, \@bin, \@errors) ) { print "$_\n" for @bin; } else { print "$_->{level}: $_->{text} line $_->{line}\n" for @errors; }
# init memory and registers my $mem = init_memory(0x800); my $reg = init_registers(); my $changed = {};
# load assembled code into memory loadbin($mem, \@bin);
# run program, dump data do { printf "%08X %08X\n", $_, $reg->[$_] for @$reg; print "\n"; printf "%08X %08X\n", $_, $changed->{$_} for sort keys(%$changed); } until ( ! step($mem, $reg, $changed) );
# disassemble from memory my @dcode = init_code($mem); disassemble($mem, \@dcode);
printf "%08X %08X\n", $_, $dcode->[$_] for 0..$#{$mem};
The NICE module provides functions to assemble, disassemble and run programs written for the NICE processor, an experimental processor designed by Bernd Ulmann <http://www.vaxman.de>.
An overview of the properties can be found at:
http://www.vaxman.de/projects/nice/nice.html
init_registers()
Initializes an array with the 16 32-bit registers of the NICE processor (implemented as Bit::Vector objects). You will need them for executing instructions with the step function.
The return value is a reference to the registers array.
init_memory(<size>)
Initializes a memory array (an array of Bit::Vector objects) for subsequent use with the step or disassembler function. Size is the number of 32bit words to inlitialize.
The return value is a reference to the memory array.
init_code(<mem_aref>)
Initializes an array for storing disassembled code in. By passing it the array reference pointing at the memory, you will get an array with the same number of elements.
The return value is a reference to the code array.
loadbin(<mem_aref>, <bin_aref>)
Loads the binary data from the array referenced by bin_aref into the memory array referenced by mem_aref.
assemble(<coderef>, <binref>, <errorref>)
The assemble function assembles (Surprise, Surprise!) the NICE assembler code given in an array of lines. The result will be put in two corresponding arrays for the resulting binary (if the code could be assembled correctly) and the errors encountered.
The array elements of the binary array will contain one instruction or data word in NICE binary format. This is a simple string with a memory address and the instruction (8 hex nibbles each) separated by a space.
The array elements of the error array will be hashrefs referencing a hash with the structure:
{ level => <the errorlevel: 'error', 'warning' or 'info'>, text => <the error description>, line => <the line number, where the error occured>, }
In case of failure (one ore more errors with level 'error') the function will return undef and the code array will not be filled. Otherwise it will return a true value.
disassemble(<mem_aref>, <code_aref>, [<changed_mem_href>])
Disassembles code located in a memory array to a corresponding code array. You can disassemble instructions from specific memory locations by suppliying an additional hash with the memory addresses as keys.
This is escpecially useful in combination with the step function, that fills a reference to a hash with the memory addresses as keys and their instructions as values containig only those addresses changed by the last executing cycle.
step(<mem_aref>, <reg_aref>, <changed_mem_href>)
The step function executes (makes the appropriate changes to registers and memory for) the one instruction pointed to by the contents of the program counter in register 15.
If memory data is changed, the addresses and their values are put into the hash referenced by the third parameter. This is useful for displying data without the need for unnessesary refreshing (see disassemble).
It will return a false value if the instruction was a HALT instruction. Otherwise it will return a true value.
There is no schedule for implementation
Error checking in case of buggy or malformed data could be better.
Bernd Ulmann <ulmann@vaxman.de>, Thomas Kratz <tkr@gnlpf.de>
Copyright (c) 2004 Bernd Ulmann & Thomas Kratz. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.