Skip to content

Instantly share code, notes, and snippets.

@pdobrowolski
Created November 23, 2011 16:45
Show Gist options
  • Save pdobrowolski/1389172 to your computer and use it in GitHub Desktop.
Save pdobrowolski/1389172 to your computer and use it in GitHub Desktop.
Processor
with Tasks; use Tasks;
with Ada.Sequential_IO;
with Ada.Command_Line; use Ada.Command_Line;
procedure procesor is
Exec: Exe_Acc;
package ByteIO is new Ada.Sequential_IO (Byte);
Input: ByteIO.FILE_TYPE;
Exec_Mode: String := Argument(1);
File_name: String := Argument(2);
Mode: Mode_Type;
B: Byte;
begin
if Exec_Mode = "-s" then
Mode := SEQUENTIAL;
elsif Exec_Mode = "-d" then
Mode := DIRECT;
else
-- exit program: bad argument
null;
end if;
-- activate Execute task - read Memory vector and execute commands
Exec := new Execute (Mode);
-- start reading input script, and send it to Memory vector
ByteIO.Open (Input, ByteIO.In_File, File_Name);
loop
exit when ByteIO.End_Of_File (Input);
ByteIO.Read (Input, B);
Memory.Write(B);
end loop;
--write STOP at the end of Memory vector
-- Memory.Write(16#0A#);
ByteIO.Close(Input);
end procesor;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
package body Tasks is
-- task body Load is
-- B: Byte;
-- begin
-- loop
-- exit when ByteIO.End_Of_File (In_File.all);
-- ByteIO.Read (In_File, B);
-- Memory.Write(B);
-- end loop;
-- end;
task body Execute is
Acc: Integer := 0; --Accumulator
I, Z: Integer := 1;
Y, X: Byte;
Output: FILE_TYPE;
begin
-- Set output: When DIRECT to file, when SEQUENTIAL to screen
if Mode = DIRECT then
Create(Output, Out_File, "output");
Set_Output(Output);
end if;
Put(" PC Rozkaz Wartość Rozkaz Wartość Aku"); New_Line;
loop
Memory.Request(I);
Memory.Read(I, X); --get #I command from command array
if X in 2..8 then --if command requires argument
I := I + 1;
Memory.Request(I);
Memory.Read(I, Y); --get #I+1 command from command array
Z := Integer(Y);
end if;
Print (Mode, I, Integer (X), Integer (Y), Acc);
case X is
when 1 => Acc := 0; --ZA
when 2 => Acc := Z; --LA
when 3 => Acc := Acc * Z; --MUL
when 4 => Acc := Acc / Z; --DIV
when 5 => Acc := Acc + Z; --ADD
when 6 => Acc := Acc - Z; --SUB
when 7 => I := I + Z - 2; --JMP
when 8 => if Acc /= 0 then I := I + Z - 2; --JNZ
end if;
when 9 => null; --NOP
when 10 => exit; --STOP
when others => null;
end case;
I := I + 1;
end loop;
Close(Output);
end Execute;
task body Process is
Size: constant Integer := 1000;
type Byte_Vector is array(1..Size) of Byte;
Memory: Byte_Vector;
PC: Integer := 0; --Accumulator
Exe_Pos: Integer := 0; --Process Count
begin
loop
select
accept Request (pos: in Integer) do
Exe_Pos := pos;
--check for end of read;
--return 0 if end of array;
end Request;
or
when Exe_Pos <= PC and PC > 0 =>
accept Read (pos: in Integer; val: out Byte) do
--raise exeption if pos > PC
--raise exeption if pos /= Exe_Pos
val := Memory(pos);
end Read;
or
accept Write (val: in Byte) do
Memory(PC + 1) := val;
PC := PC + 1;
end Write;
or
terminate; --if other task end, terminate Process task
end select;
end loop;
end Process;
procedure Print(mode: Mode_Type; pos: Integer; com: Integer;
val: Integer; acc: Integer) is
subtype Command_Label is String (1..8);
Decode: array (1..10) of Command_Label :=
(" ZA", " LA", " MUL", " DIV", " ADD",
" SUB", " JMP", " JNZ", " NOP", " STOP");
I: Integer := pos;
flag: Boolean := FALSE;
Ch: Character;
begin
if com in 2..8 then
I := I - 1;
flag := TRUE;
end if;
Put(I, Width=>4);
Put(com, Width=>10, Base=>16);
if flag then
Put(val, Width=>8, Base=>16);
else
Put(" ");
end if;
if com in 1..10 then
Put(Decode(com));
else
Put(" ");
end if;
if flag then
Put(val, Width=>4);
else
Put(" ");
end if;
Put(acc, Width=>10);
New_Line;
if mode = SEQUENTIAL then
Get_Immediate(Ch);
end if;
end Print;
end Tasks;
with Ada.Sequential_IO;
package Tasks is
subtype Byte is Short_Short_Integer;
-- package ByteIO is new Ada.Sequential_IO (Byte);
-- type Byte_File is access ByteIO.FILE_TYPE;
-- task type Load (In_File: Byte_File);
type Mode_Type is (SEQUENTIAL, DIRECT);
task type Execute (Mode: Mode_Type);
task type Process is
entry Request (pos: in Integer);
entry Read (pos: in Integer; val: out Byte);
entry Write (val: in Byte);
end Process;
procedure Print (mode: Mode_Type; pos: Integer; com: Integer;
val: Integer; acc: Integer);
Memory: Process; --Global instanse of Process variable
type Exe_Acc is access Execute;
end Tasks;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment