Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?PHP
- if ($argc != 2)
- {
- echo "Need a file parameter.\n";
- exit ();
- }
- class x86VM
- {
- // Some registers.
- private $ax, $bx, $cx, $dx;
- private $ah, $bh, $ch, $dh;
- private $al, $bl, $cl, $dl;
- private $sp;
- private $mode = ".CODE";
- private $data = array ();
- private $dataAddressesByObject = array();
- private $dataAddressesByAddress = array();
- private $dataAddressesOffset = 0;
- private $debugMode = false;
- public function dEcho ($text)
- {
- if ($this -> debugMode)
- {
- echo $text;
- }
- }
- public function __construct ()
- {
- $this -> ax = $this -> bx = $this -> cx = $this -> dx = 0;
- $this -> refresh ();
- $this -> sp = 0;
- }
- public function refresh ()
- {
- $this -> ah = ($this -> ax) >> 8;
- $this -> al = ($this -> ax) - ($this -> ah * 256);
- $this -> bh = ($this -> bx) >> 8;
- $this -> bl = ($this -> bx) - ($this -> bh * 256);
- $this -> ch = ($this -> cx) >> 8;
- $this -> cl = ($this -> cx) - ($this -> ch * 256);
- $this -> dh = ($this -> dx) >> 8;
- $this -> dl = ($this -> dx) - ($this -> dh * 256);
- $vars = array ("ax", "ah", "al", "bx", "bh", "bl", "cx", "ch", "cl", "dx", "dh", "dl");
- foreach ($vars as $thisvar)
- {
- $this -> dEcho ($thisvar . " => " . $this -> $thisvar . "\n");
- }
- $this -> dEcho ("\n");
- }
- public function readString ($strIn)
- {
- $finalString = null;
- $readingString = false;
- // This will do more to the string, like actually parse its contents.
- $del = substr ($strIn, 0, 1);
- for ($i = 0; $i < strlen ($strIn); $i++)
- {
- if ($strIn[$i] == $del)
- {
- $readingString = !$readingString;
- }
- else
- {
- if ($strIn[$i] == "\\")
- {
- switch ($strIn[$i + 1])
- {
- case "r":
- $finalString .= "\r";
- break;
- case "n":
- $finalString .= "\n";
- break;
- case "\\":
- $finalString .= "\\";
- break;
- case "'":
- $finalString .= "'";
- break;
- case "\"":
- $finalString .= "\"";
- break;
- default:
- $finalString .= $strIn[$i + 1];
- break;
- }
- $i++;
- }
- else if ($strIn[$i] == "$")
- {
- // The string is terminated.
- // Read additional characters.
- // Last terminator...
- $i++;
- // Remaining
- $remaining = substr ($strIn, $i);
- $remainingValues = explode (",", $remaining);
- // Start at 1 to ignore initial string
- for ($vx = 1; $vx < count ($remainingValues); $vx++)
- {
- $finalString .= chr (hexdec ($remainingValues[$vx]));
- }
- // Terminate the job.
- $i = strlen ($strIn);
- }
- else
- {
- $finalString .= $strIn[$i];
- }
- }
- }
- return $finalString;
- }
- public function exec ($arguments)
- {
- if ($arguments != null)
- {
- // print_r ($arguments);
- if (($this -> mode == ".DATA") && ($arguments[1] == "db"))
- {
- $this -> data[$arguments[0]] = $this -> readString ($arguments[2]);
- $this -> dataAddressesByObject[$arguments[0]] = $this -> dataAddressesOffset;
- $this -> dataAddressesByAddress[$this -> dataAddressesOffset] = $arguments[0];
- $this -> dataAddressesOffset += strlen ($this -> data[$arguments[0]]);
- return null;
- }
- switch ($arguments[0])
- {
- case ".MODEL":
- case ".STACK":
- $this -> dEcho ("* Ignoring these calls for now.\n");
- return null;
- case ".CODE":
- case ".DATA":
- $this -> set_mode ($arguments[0]);
- return null;
- case "int":
- $this -> interrupt ($this -> parse_num ($arguments[1]));
- return null;
- case "mov":
- $reg = $this -> strip_comma ($arguments[1]);
- $this -> dEcho ("Have $reg \n");
- if (($reg == "ax") || ($reg == "bx") || ($reg == "cx") || ($reg == "dx"))
- {
- $this -> mov_xreg_val ($reg, $this -> parse_num ($arguments[2]));
- return null;
- }
- else if (($reg == "ah") || ($reg == "bh") || ($reg == "ch") || ($reg == "dh"))
- {
- $this -> mov_hreg_val ($reg, $this -> parse_num ($arguments[2]));
- return null;
- }
- else if (($reg == "al") || ($reg == "bl") || ($reg == "cl") || ($reg == "dl"))
- {
- $this -> dEcho ("Unhandled al/bl/cl/dl...\n");
- return null;
- }
- break;
- case "lea":
- $reg = $this -> strip_comma ($arguments[1]);
- $this -> $reg = $this -> dataAddressesByObject[$arguments[2]];
- $this -> dEcho ("* Loading " . $reg . " with " . $this -> $reg . "\n");
- return null;
- default:
- $this -> dEcho ("Failure -- Unhandled instruction:\n");
- exit ();
- }
- }
- }
- public function strip_comma ($reg)
- {
- return substr ($reg, 0, -1);
- }
- public function parse_num ($val2)
- {
- $val = trim ($val2);
- // check for h
- if (strtolower(substr($val, -1)) == "h")
- {
- // Convert it from hex to decimal.
- return hexdec (substr ($val, 0, -1));
- }
- else
- {
- return intval ($val);
- }
- }
- public function set_mode ($mode)
- {
- $this -> dEcho ("* Setting mode to: " . $mode . "\n");
- $this -> mode = $mode;
- }
- public function mov_xreg_val ($register, $value)
- {
- $this -> dEcho ("Setting $register to $value \n");
- $wi = $value;
- if ($wi > 65535) $wi = 65535;
- if ($wi < 0) $wi = 0;
- $this -> $register = $wi;
- $this -> refresh();
- return null;
- }
- public function mov_hreg_val ($register, $value)
- {
- $wi = $value;
- if ($wi > 255) $wi = 255;
- if ($wi < 0) $wi = 0;
- $low = substr($register, 0, -1) . "l";
- $all = substr($register, 0, -1) . "x";
- $v = ($value * 256) + $this -> $low;
- $this -> $all = $v;
- $this -> refresh();
- return null;
- }
- public function interrupt ($interrupt)
- {
- switch ($interrupt)
- {
- case 33:
- // Check what we have in AH as our primary interrupt checker.
- switch ($this -> ah)
- {
- case 0x09:
- // Print the contents of DX as a string.
- echo $this -> data[$this -> dataAddressesByAddress[$this -> dx]];
- break;
- case 0x4c:
- $this -> dEcho ("* Terminate with code " . $this -> al . "\n");
- exit ($this -> al);
- }
- break;
- default:
- echo "Failure -- Unhandled interrupt: " . $interrupt . "\n";
- exit ();
- break;
- }
- }
- }
- function read ($line)
- {
- $code = explode (";", $line); // Split by the comment.
- $thisCode = trim($code[0]);
- if (strlen($code[0]) == 0) return null;
- $args = explode (" ", $code[0], 3);
- // Clean the args up
- for ($i = 0; $i < count ($args); $i++)
- {
- $args[$i] = trim ($args[$i]);
- }
- if ($args[0] != NULL)
- {
- return $args;
- }
- return null;
- }
- $vm = new x86VM();
- $data = file_get_contents ($argv[1]);
- $lines = explode ("\n", $data);
- foreach ($lines as $aLine)
- {
- // echo ">> " . $aLine . "\n";
- $vm -> exec (read ($aLine));
- // echo "\n";
- }
- ?>
Add Comment
Please, Sign In to add comment