quantumdisaster quantumdisaster - 7 months ago 16
Perl Question

How can I process opcodes stored in a binary file in Perl?

Creating Your Own Abstract Processor is a quick paper on what I am trying to do.

http://malcon.org/ctm.rar is the exact specifications on what the emulator should be.

I am writing a sort of an emulator in Perl. This program will read in a binary file and process the hex of the binary into actions, how a processor works, but software based with different opcodes. Just a challenge thing.

Anyhow, I am not entirely sure how to read the binary file into an array and then assign the hex from the array to the opcodes. This is part of my code:

my $opcode='';
my $file= "path/to/file";
my $IP=0;
my $SP=0;
my $FLAG=0;
my $A=0;
my $B=0;
my $X=0;
my @STACK=(0);

open(F, "<".$file) || die("Could not open file");
binmode(F);
my @ROM = <F>;
close(F);

while($IP >= 0)
{
$opcode="$ROM[$IP]";
if ($opcode eq 11) {
$A = $STACK[$SP];
$IP++;
}
if ($opcode eq 12) {
$B = $STACK[$SP];
$IP++;
}
if ($opcode eq 13) {
$A = $B;
$IP++;
}
if ($opcode eq 14) {
$B = $A;
$IP++;
}


This is just the part of the code I need help with. If you need to see more of it for some reason, just let me know.

So I changed my code to reflect an answer above, my code now looks like this:

my $opcode='';
my $file= "CTM-bootrom";
my $IP=0;
my $SP=0;
my $FLAG=0;
my $A=0;
my $B=0;
my $X=0;
my @STACK=(0);

open my $ROM, '<:raw', $file or die "Cannot open '$file': $!";

{
local $/ = \1; # Read one byte at a time
while (my $byte = <$ROM>){
while($IP >= 0)
{
$opcode=$ROM[$IP];
if ($opcode eq 11) {
$A = $STACK[$SP];
$IP++;
}
if ($opcode eq 12) {
$B = $STACK[$SP];
$IP++;
}
if ($opcode eq 13) {
$A = $B;
$IP++;
}


But now I get an error:


Use of uninitialized value $opcode in string eq at Aod8.pl line 73,


<$ROM> to me it looks like opcode is initialized... How can I fix this problem?

Answer

I got it now...everything is now working like needed:

my $IP=0;
my $FLAG=0;
my $SP=0;
my $A=0;
my $B=0;
my @STACK=(0);
my $byte=0;
$| = 1;

open(BOOTROM, "<bootrom.txt");
binmode(BOOTROM);

my (@ROM, $instruction);
while ((read BOOTROM, $instruction, 1) != 0) {
    @ROM[$IP] = $instruction;
    $IP++;
}
close(BOOTROM);

$IP = 0;
while ($IP >= 0 && $byte != 0x3C) {
    $byte = ord(@ROM[$IP]);

    if ($byte == 0x11) {
        $A = (@STACK[$SP]);
        $IP++;
    }
    elsif ($byte == 0x12) {
        $B = (@STACK[$SP]);
        $IP++;
    }
    elsif ($byte == 0x13) {
        $A = $B;
        $IP++;
    }
    elsif ($byte == 0x14) {
        $B = $A;
        $IP++;
    }