|
@@ -67,7 +67,7 @@ sub parseAssembly
|
|
|
}
|
|
|
elsif($opcodes{$asmInstruction})
|
|
|
{
|
|
|
- parseOpcodeAndParams($opcodes{$asmInstruction}, \@parameters);
|
|
|
+ parseOpcodeAndParams($opcodes{$asmInstruction}, \@parameters, \$instructionNumber);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -76,37 +76,55 @@ sub parseAssembly
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-# TODO
|
|
|
sub parseOpcodeAndParams
|
|
|
{
|
|
|
+ # A reference to the current instruction number
|
|
|
+ # Need to assign first due to usage for opcode index
|
|
|
+ my $instructionNumber = $_[2];
|
|
|
+ # The opcode
|
|
|
my $opcode = $_[0];
|
|
|
+ # Store program index of opcode now because opcode may be modified in the parameter loop
|
|
|
+ my $opcodeIdx = $$instructionNumber++;
|
|
|
+ # Parameters for the opcode
|
|
|
my @parameters = @{ $_[1] };
|
|
|
- my $operand1 = $parameters[0];
|
|
|
- if(isImmediate($parameters[0]))
|
|
|
- {
|
|
|
- $opcode = length($opcode) == 1 ? "10$opcode" : "1$opcode";
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- $operand1 = getAddress($parameters[0])
|
|
|
- }
|
|
|
|
|
|
- my $operand2 = $parameters[1];
|
|
|
- if(isImmediate($parameters[1]))
|
|
|
+ # Store at is usually the last parameter, if there are any parameters
|
|
|
+ my $storeAt = $#parameters > 0 ? getAddress(pop(@parameters)) : -1;
|
|
|
+
|
|
|
+ # The amount of digits the opcode is expected to be when the parameter tries to add its parameter mode
|
|
|
+ my $parameterModeIdx = 2;
|
|
|
+
|
|
|
+ foreach my $param (@parameters)
|
|
|
{
|
|
|
- $opcode = length($opcode) < 3 ? "100$opcode" : "1$opcode";
|
|
|
+ if(isImmediate($param))
|
|
|
+ {
|
|
|
+ if(length($opcode) < $parameterModeIdx)
|
|
|
+ {
|
|
|
+ $opcode = "0$opcode";
|
|
|
+ }
|
|
|
+ $opcode = "1$opcode";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ $param = getAddress($param);
|
|
|
+ }
|
|
|
+ $parameterModeIdx++;
|
|
|
+
|
|
|
+
|
|
|
+ $program[$$instructionNumber++] = $param;
|
|
|
+ if($$instructionNumber == 9)
|
|
|
+ {
|
|
|
+ print "$opcode, $param";
|
|
|
+ die "Overwriting memory!";
|
|
|
+ }
|
|
|
}
|
|
|
- else
|
|
|
+ # Insert opcode back where it belongs
|
|
|
+ $program[$opcodeIdx] = $opcode;
|
|
|
+ if($storeAt > -1)
|
|
|
{
|
|
|
- $operand2 = getAddress($parameters[1])
|
|
|
+ # Add the storeAt address
|
|
|
+ $program[$$instructionNumber++] = $storeAt;
|
|
|
}
|
|
|
-
|
|
|
- my $storeAt = getAddress($parameters[2]);
|
|
|
-
|
|
|
- $program[$instructionNumber++] = $opcode;
|
|
|
- $program[$instructionNumber++] = $operand1;
|
|
|
- $program[$instructionNumber++] = $operand2;
|
|
|
- $program[$instructionNumber++] = $storeAt;
|
|
|
}
|
|
|
|
|
|
# Check if a parameter is Immediate Mode or Position
|