Advertisement
pinkerton5

Why Not Virtual Machine 1.1

Jun 30th, 2021 (edited)
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 5.20 KB | None | 0 0
  1.  program wnVM11;  // Why Not Virtual Machine
  2.                 // The historical date: 2021.07.01. 3:34:10  
  3.  Const
  4.   BASE   = 96;                                       // MEMO merete byte-ban
  5.   PAGES =  6;
  6.   MEMMAX = BASE-1;  
  7.   INITIP = BASE DIV PAGES;                           // kodszegmens kezdocime
  8.   CMAX   = 16384;                                    // max. Ciklusszam  
  9.  Var  
  10.   MEM    : array[0..MEMMAX] of byte;                 // MEMO
  11.   IP     : byte    = 0;                              // MEMO indexe (Instr. Pointer)
  12.   ExIP   : byte    = 0;                              
  13.   ACCU   : byte    = 0;                              // Munkaregiszter
  14.   ORIGIP : byte;                                     // foprogram startcime
  15.   Flag   : byte    = 0;                              // Compare flag
  16.   Cycle  : integer = 0; running: boolean = false;    // ciklusok
  17.  
  18.  Procedure Error(s: string);                         // hiba
  19.  begin
  20.   writeln(s);
  21.   halt;
  22.  end;
  23.  
  24.  Function BinHex(b:  byte):  String;                 // bintohex konverter
  25.  Const
  26.   s:  string = '0123456789ABCDEF';
  27.  Begin
  28.   Binhex[0] := #2; BinHex:= s[(b shr 4)+1]+s[(b and 15)+1];    
  29.  End;
  30.  
  31.  function OpToInstr: string;                     // 'disassembler' fuggv.
  32.  begin
  33.    case MEM[ExIP] of
  34.    $CD : OpToInstr := 'SWAP ACCU-MEM['+BinHex(MEM[ExIP+1])+']';
  35.    $F1 : if (MEM[Exip+1]= 0) then OpToInstr:= 'INC ACCU' else OpToInstr:= 'INC MEM['+BinHex(MEM[ExIP+1])+']';
  36.    $F0 : if (MEM[Exip+1]= 0) then OpToInstr:= 'DEC ACCU' else OpToInstr:= 'DEC MEM['+BinHex(MEM[ExIP+1])+']';  
  37.    $AD : OpToInstr := 'ADD '+BinHex(MEM[MEM[ExIP+1]])+'h to ACCU';
  38.    $AA : OpToInstr := 'SUB '+BinHex(MEM[MEM[ExIP+1]])+'h from ACCU';
  39.    $C0 : OpToInstr := 'CMP ACCU-MEM['+BinHex(MEM[ExIP+1])+']';
  40.    $EA : if MEM[ExIP+1]>0 then OpToInstr:='JMP to '+BinHex(MEM[ExIP+1]) else OpToInstr:='JMP to '+BinHex(ORIGIP);
  41.    $E0 : OpToInstr := 'JMP '+BinHex(MEM[ExIP+1])+' if FLG';
  42.    $AB : OpToInstr := 'ACCU <- MEM['+BinHex(MEM[ExIP+1])+']';
  43.    $BA : OpToInstr := 'ACCU -> MEM['+BinHex(MEM[ExIP+1])+']';
  44.    $00 : OpToInstr := 'PROCESS HALTED';
  45.    $FF : OpToInstr := 'RETURN to '+BinHex(MEM[00]);
  46.    else OpToInstr := 'ERROR';
  47.    end;
  48.  end;
  49.  
  50.  procedure DrawScreen;                               // state documentator ;)    
  51.  Var
  52.   i, j: byte;
  53.      s: string;
  54.  begin
  55.   writeln('    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F');
  56.   writeln();
  57.   j:= 0;
  58.   s:= BinHex(0);
  59.   s:= s[1]+'  ';    
  60.   for i:= 0 to MEMMAX do
  61.   begin
  62.    s:= s+BinHex(MEM[i])+' ';  
  63.    inc(j);  
  64.    if j = 16 then
  65.     begin
  66.     writeln(s);
  67.     j:=0;
  68.     s:= BinHex(i+1 mod 16);
  69.     s:= s[1]+'  ';  
  70.     end;
  71.   end;  
  72.   writeln();
  73.   write('   Accu: ',BinHex(ACCU),'  Ip: ',BinHex(ExIP));
  74.   write('  Flg: ',flag,'   I: ',OpToInstr,#13,#10);
  75.   writeln('---------------------------------------------------| ',Cycle+1);
  76.  end;
  77.  
  78.  procedure OneStep;                                    // soft - CPU
  79.  var
  80.  TMP: byte;
  81.  begin
  82.   ExIP := IP;
  83.   Case MEM[IP] of
  84.    $CD: {SWP} Begin TMP:= ACCU;  ACCU := MEM[MEM[IP+1]];  MEM[MEM[IP+1]]:= TMP;          inc(IP,2); end;
  85.    $F1: {inc} Begin TMP := MEM[IP+1]; if TMP > 0 then Inc(MEM[MEM[TMP]]) else Inc(ACCU); inc(IP,2); end;
  86.    $F0: {dec} Begin TMP := MEM[IP+1]; if TMP > 0 then dec(MEM[MEM[TMP]]) else dec(ACCU); inc(IP,2); end;
  87.  
  88.    $00: {HLT} begin running := false; end;
  89.    $AA: {SUB} begin ACCU := byte(ACCU-MEM[MEM[IP+1]]); inc(IP,2); end;
  90.    $AD: {ADD} begin ACCU := byte(ACCU+MEM[MEM[IP+1]]); inc(IP,2); end;
  91.    $C0: {CMP} begin if (ACCU = MEM[MEM[IP+1]]) then Flag:= 1 else Flag:= 0; inc(IP,2); end;
  92.    $EA: {JMP} begin
  93.                     if (MEM[IP+1] = 0) then IP := ORIGIP
  94.                     else
  95.                     begin MEM[$00]:= IP+2; IP := MEM[IP+1]; end;
  96.                     end;
  97.    $E0: {JZR} begin if (Flag = 1) then
  98.                     begin
  99.                     MEM[$00]:= IP+2; IP:= MEM[IP+1];
  100.                     Flag := 0;        
  101.                     end  else inc(IP,2); end;                          
  102.    $AB: {LDA} begin ACCU := MEM[MEM[IP+1]]; inc(IP,2); end;
  103.    $BA: {STA} begin MEM[MEM[IP+1]] := ACCU; inc(IP,2); end;
  104.    $FF: {RET} IP := MEM[$00];
  105.    else  
  106.     begin write('Unknown instruction: ',MEM[IP]); running:= false; end;
  107.   end; { case }
  108.  
  109. //  if running then        {<--- decomment it, if You dont need the last state of the CPU}
  110.   DrawScreen;  
  111.   if (Cycle < CMAX) then Inc(Cycle) else Running := false;
  112.  end;
  113.  
  114.  procedure Executor;                        //  
  115.  begin
  116.   IP := ORIGIP;                             // Dreams comes true, from here ..  
  117.   running := true;
  118.   while running do OneStep;
  119.  end;
  120.  
  121.  procedure LoadToMem(s: string);            // program betolto
  122.  var
  123.   i    : byte;  
  124.   ifile: file of byte;
  125.  begin
  126.   assign(ifile,paramstr(1));
  127.   reset(ifile,1);  
  128.   for i:= 0 to MEMMAX do read(ifile,MEM[i]);
  129.   ORIGIP := MEM[00];                        // Yes, now, We have a starting address
  130.   MEM[00]:= 0;                              // First time, clear the STACK segment, Dude!
  131.   close(ifile);
  132.  end;
  133.  
  134.  begin
  135.   if paramstr(1) <> '' then LoadToMem(paramstr(1))
  136.   else
  137.   begin writeln('Usage: wnVM.exe input.bin >output.txt'); exit; end;  
  138.   Executor;
  139.  end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement