<?php /*file.php*/
/*
'Keal's PHP File Routines 0x00
'Created August 20th-25th 2009 by Timothy Robert Keal alias jargon
'Released under the Gnu Public License 2.0
'
'http://puzzlum.retromachineshop.com/
'irc://chat.freenode.net/puzzlum
'
'Please review the Gnu Public License, Thank you.
'The GPL can be located online at http://www.gnu.org/copyleft/gpl.html
*/
function file_html($filename)
{
     return '<tt>'.str_replace("\t", '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',nl2br(htmlentities(file_get_contents('./'.$filename)))).'</tt><br>';
}
function file_save_var($filename,$data)
{
     file_put_contents($filename,serialize($data));
}
function file_load_var($filename)
{
     if(!is_file($filename))
     {
          return null;
     }
     else
     {
          return unserialize(file_get_contents($filename));
     }
}
function file_load_lines($filename)
{
     if(!is_file($filename))
     {
          return null;
     }
     return file_lines(file_get_contents($filename));
}
function file_lines($data)
{
     $variable=null;
     $variable['ct']=0;
     $data_last=strlen($data)+1;
     while(strlen($data)<$data_last)
     {
          $data_last=strlen($data);     
          $o_r=strpos($data,"\r");
          $o_n=strpos($data,"\n");
          if($o_n==$o_r+1)
          {
               $o_r=$o_r;
               $o_n=$o_n;
          }
          elseif(($o_r===FALSE)&&($o_n!==FALSE))
          {
               $o_r=$o_n;
               $o_n=$o_n;
          }
          elseif(($o_r!==FALSE)&&($o_n===FALSE))
          {
               $o_r=$o_r;
               $o_n=$o_r;
          }
          elseif(($o_r===FALSE)&&($o_n===FALSE))
          {
               $o_r=strlen($data);
               $o_n=strlen($data);
          }
          $ln=substr($data,0,$o_r);
          $data=substr($data,$o_n+1,strlen($data)-$o_n);
          $variable[$variable['ct']]=$ln;
          $variable['ct']=$variable['ct']+1;
     }
     return $variable;
}
?>

<?php /*list.php*/
/*
'Keal's PHP File Routines 0x00
'Created August 20th-25th 2009 by Timothy Robert Keal alias jargon
'Released under the Gnu Public License 2.0
'
'http://puzzlum.retromachineshop.com/
'irc://chat.freenode.net/puzzlum
'
'Please review the Gnu Public License, Thank you.
'The GPL can be located online at http://www.gnu.org/copyleft/gpl.html
*/
include_once('./file.php');
echo file_html('file.php');
echo file_html('list.php');
echo file_html('chasm.php');
echo file_html('index.php');
?>

<?php /*chasm.php*/
/*
'CHASM - Contextual Hybrid (Dis)Assembler 0x01
'Created August 20th-30th 2009 by Timothy Robert Keal alias jargon
'Released under the Gnu Public License 2.0
'
'http://puzzlum.retromachineshop.com/
'irc://chat.freenode.net/puzzlum
'
'Please review the Gnu Public License, Thank you.
'The GPL can be located online at http://www.gnu.org/copyleft/gpl.html
*/
include_once('./file.php');
function chasm_asm($processor,$data)
{
     $ln=file_lines($data);
     $instructionset=chasm_load($processor);
     if($instructionset===null)
     {
          return 'Unknown instruction set!';
     }
     $output='';
     $index=0;
     while($index<$ln['ct'])
     {
          if((strlen($ln[$index])>0)&&(substr($ln[$index],0,1)!==';')){
               /* echo '<i><tt>'.$ln[$index].'</tt></i><br>'."\r\n"; */
               $comment='';
               if(strpos($ln[$index],';')!==false)
               {
                    $comment=substr($ln[$index],strpos($ln[$index],';'));
                    $asm=chasm_spaces(substr($ln[$index],0,strlen($ln[$index])-strlen($comment)));
               }
               else
               {
                    $asm=chasm_spaces($ln[$index]);
               }
               /* echo '<b><tt>asm: '.$asm.'</tt></b><br>'."\r\n"; */
               if(strpos($asm,' ')!==false)
               {
                    $mnemonic=strtoupper(substr($asm,0,strpos($asm,' ')));
                    $asm=substr($asm,strpos($asm,' ')+1);
               }
               else
               {
                    $mnemonic=strtoupper($asm);
                    $asm='';
               }
               /* echo '<tt>mnemonic: '.$mnemonic.'</tt><br>'."\r\n"; */
               /* echo '<tt>arguments: '.$asm.'</tt><br>'."\r\n"; */
               /* echo '<tt>ct: '.$instructionset['mnemonic'][$mnemonic]['ct'].'</tt><br>'."\r\n"; */
               if($instructionset['mnemonic'][$mnemonic]['ct']!==null)
               {
                    $opcode='';
                    $index2=0;
                    while($index2<$instructionset['mnemonic'][$mnemonic]['ct'])
                    {
                         /* echo '<tt>syntax: '.$instructionset['mnemonic'][$mnemonic][$index2]['syntax'].'</tt><br>'."\r\n"; */
                         /* echo '<tt>regex: '.$instructionset['mnemonic'][$mnemonic][$index2]['regex'].'</tt><br>'."\r\n"; */
                         $chk=false;
                         if((strlen($instructionset['mnemonic'][$mnemonic][$index2]['syntax'])===0)&&(strlen($asm)===0))
                         {
                              $chk=true;
                         }
                         elseif(preg_match($instructionset['mnemonic'][$mnemonic][$index2]['regex'],$asm)===1)
                         {
                              $chk=true;
                         }
                         if($chk===true)
                         {
                              $opcode=$instructionset['mnemonic'][$mnemonic][$index2]['opcode'];
                              /* echo '<tt><b>output: '.$opcode; */
                              $output.=$opcode;
                              if(strpos($instructionset['mnemonic'][$mnemonic][$index2]['syntax'],'char')!==false)
                              {
                                   $o=strpos($instructionset['mnemonic'][$mnemonic][$index2]['syntax'],'char');
                                   $output.=substr($asm,$o+1,2);
                                   /* echo substr($asm,$o+1,2); */
                              }
                              elseif(strpos($instructionset['mnemonic'][$mnemonic][$index2]['syntax'],'addr')!==false)
                              {
                                   $o=strpos($instructionset['mnemonic'][$mnemonic][$index2]['syntax'],'addr');
                                   $output.=substr($asm,$o+1,2);
                                   /* echo substr($asm,$o+1,2); */
                              }
                              elseif(strpos($instructionset['mnemonic'][$mnemonic][$index2]['syntax'],'short')!==false)
                              {
                                   $o=strpos($instructionset['mnemonic'][$mnemonic][$index2]['syntax'],'short');
                                   $output.=substr($asm,$o+1,4);
                                   /* echo substr($asm,$o+1,4); */
                              }
                              /* echo '</b></tt><br>'."\r\n"; */
                              break;
                         }
                         $index2++;
                    }
               }
          }
          $index++;
     }
     if(strlen($output===0))
     {
          return ''; /* 'Nothing to assemble!'; */
     }
     return chasm_spaces_insert($output);
}
function chasm_disasm($processor,$data)
{
     $d=chasm_spaces_strip($data);
     if(preg_match('/^[0-9A-F]+$/',$d)===1)
     {
          $data=$d;
     }
     else
     {          
          $ln=file_lines('['.$data.']');
          if($ln===null)
          {
               $output='';
          }
          else
          {
               $output='';
               $index=0;
               while($index<$ln['ct'])
               {
                    if(strlen($output)>0)
                    {
                         $output.="\r\n";
                    }
                    $output.=';'.$ln[$index];
                    $index++;
               }
          }
          return $output;
     }
     $instructionset=chasm_load($processor);
     if($instructionset===null)
     {
          return 'Unknown instruction set!';
     }
     $output='';
     $data_last=strlen($data)+1;
     while($data_last>strlen($data))
     {
          /* echo '<tt>'.strlen($data).'</tt><br>'."\r\n"; */
          if(strlen($data)===0)
          {
               break;
          }
          $data_last=strlen($data);
          $opcode=strtoupper(substr($data,0,2));
          $comment='';
          while((strlen($opcode)<<1)<=16)
          {
               if($instructionset['opcode'][$opcode]['asm']!==null)
               {
                    break;
               }
               $opcode=strtoupper(substr($data,0,strlen($opcode)<<1));
               if(strlen($opcode)===strlen($data))
               {
                    break;
               }
          }
          if($instructionset['opcode'][$opcode]['asm']===null)
          {
               break;
          }
          else{
               $data=substr($data,strlen($opcode));
               $asm=$instructionset['opcode'][$opcode]['asm'];
               $comment=$instructionset['opcode'][$opcode]['comment'];
               if(strpos($asm,'char')!==false)
               {
                    if(strlen($data)>=2)
                    {
                         $asm=str_replace('char','$'.strtoupper(substr($data,0,2)),$asm);
                         $data=substr($data,2);
                    }
               }
               elseif(strpos($asm,'addr')!==false)
               {
                    if(strlen($data)>=2)
                    {
                         $asm=str_replace('addr','$'.strtoupper(substr($data,0,2)),$asm);
                         $data=substr($data,2);
                    }
               }
               elseif(strpos($asm,'short')!==false)
               {
                    if(strlen($data)>=4)
                    {
                         $asm=str_replace('short','$'.strtoupper(substr($data,0,4)),$asm);
                         $data=substr($data,4);
                    }
               }
               if((strlen($output)>0)&&(substr($output,strlen($output)-2,2)!=="\r\n"))
               {
                    $output.="\r\n";
               }               
               $output.=$asm.';'.$comment;
          }
     }
     if(strlen($data)!==0)
     {
          if(strlen($output)!==0)
          {
               if((strlen($output)>0)&&(substr($output,strlen($output)-2,2)!=="\r\n"))
               {
                    $output.="\r\n";
               }               
               $output.=chasm_spaces_insert($data);
          }
          else
          {
               if((strlen($output)>0)&&(substr($output,strlen($output)-2,2)!=="\r\n"))
               {
                    $output.="\r\n";
               }               
               $output.=chasm_spaces_insert($data);
          }
     }
     if(strlen($output)===0)
     {
          return ''; /* 'Nothing to disassemble!'; */
     }
     return $output;
}
function chasm_load($processor)
{
     $data=file_load_lines('./'.$processor.'.chasm');
     if($data['ct']===null)
     {
          return null;
     }
     $instructionset=null;
     $index=0;
     while($index<$data['ct'])
     {
          $ln=$data[$index];
          $opcode=strtoupper(substr($ln,0,strpos($ln,' ')));
          /* echo '<tt>ld opcode: '.$opcode.'</tt><br>'."\r\n"; */
          $sep=' ; ';
          $o1=strpos($ln,$sep);
          $o2=strrpos($ln,$sep);
          $len=strlen($sep);
          $instructionset['opcode'][$opcode]['asm']=substr($ln,$o1+$len,$o2-$o1-$len);
          /* echo '<tt>ld asm: '.$instructionset['opcode'][$opcode]['asm'].'</tt><br>'."\r\n"; */
          $instructionset['opcode'][$opcode]['comment']=substr($ln,$o2+$len);
          /* echo '<tt>ld comment: '.$instructionset['opcode'][$opcode]['comment'].'</tt><br>'."\r\n"; */
          if(strpos($instructionset['opcode'][$opcode]['asm'],' ')!==false)
          {
               $mnemonic=strtoupper(substr($instructionset['opcode'][$opcode]['asm'],0,strpos($instructionset['opcode'][$opcode]['asm'],' ')));
          }
          else
          {
               $mnemonic=$instructionset['opcode'][$opcode]['asm'];               
          }
          /* echo '<tt>ld mnemonic: '.$mnemonic.'</tt><br>'."\r\n"; */
          if($instructionset['mnemonic'][$mnemonic]['ct']===null)
          {
               $instructionset['mnemonic'][$mnemonic]['ct']=1;
          }
          else
          {
               $instructionset['mnemonic'][$mnemonic]['ct']++;
          }
          $index2=$instructionset['mnemonic'][$mnemonic]['ct']-1;          
          $instructionset['mnemonic'][$mnemonic][$index2]['opcode']=$opcode;
          if(strpos($instructionset['opcode'][$opcode]['asm'],' ')!==false)
          {
               $instructionset['mnemonic'][$mnemonic][$index2]['syntax']=chasm_spaces(substr($instructionset['opcode'][$opcode]['asm'],strpos($instructionset['opcode'][$opcode]['asm'],' ')+1));
          }
          else
          {
               $instructionset['mnemonic'][$mnemonic][$index2]['syntax']='';
          }
          /* echo '<tt>ld syntax: '.$instructionset['mnemonic'][$mnemonic][$index2]['syntax'].'</tt><br>'."\r\n"; */
          $instructionset['mnemonic'][$mnemonic][$index2]['regex']=preg_quote($instructionset['mnemonic'][$mnemonic][$index2]['syntax'],'/');
          $instructionset['mnemonic'][$mnemonic][$index2]['regex']=str_replace('char','(\\$[0-9A-F]{2})',$instructionset['mnemonic'][$mnemonic][$index2]['regex']);
          $instructionset['mnemonic'][$mnemonic][$index2]['regex']=str_replace('addr','(\\$[0-9A-F]{2})',$instructionset['mnemonic'][$mnemonic][$index2]['regex']);
          $instructionset['mnemonic'][$mnemonic][$index2]['regex']=str_replace('short','(\\$[0-9A-F]{4})',$instructionset['mnemonic'][$mnemonic][$index2]['regex']);
     $instructionset['mnemonic'][$mnemonic][$index2]['regex']='/^'.$instructionset['mnemonic'][$mnemonic][$index2]['regex'].'$/';
          /* echo '<tt>ld regex: '.$instructionset['mnemonic'][$mnemonic][$index2]['regex'].'</tt><br>'."\r\n"; */
          $index++;
     }
     return $instructionset;
}
function chasm_spaces($data)
{
     while(strpos($data,' ')>0)
     {
          $data=substr($data,0,strpos($data,' ')).substr($data,strpos($data,' ')+1);
     }
     while(substr($data,0,1)===' ')
     {
          $data=substr($data,1,strlen($data)-1);
     }
     while(substr($data,strlen($data)-1,1)===' ')
     {
          $data=substr($data,0,strlen($data)-1);
     }
     return $data;
}
function chasm_spaces_insert($data)
{
     $ct=0;
     $output='';
     while(strlen($data)>0)
     {
          if($ct>=16)
          {
               $ct=0;
          }
          if($ct===0)
          {
               if((strlen($output)>0)&&(substr($output,strlen($output)-2,2)!=="\r\n"))
               {
                    $output.="\r\n";
               }
               $output.='[';
          }
          if((strlen($output)>0)&&(substr($output,strlen($output)-2,2)!=="\r\n")&&(substr($output,strlen($output)-1,1)!=='['))
          {
               $output.=' ';
          }
          $output.=substr($data,0,2);
          $data=substr($data,2);
          if($ct===15)
          {
               $output.=']';
          }
          $ct++;
     }
     if((strlen($output)>0)&&(substr($output,strlen($output)-1,1)!==']'))
     {
          $output.=']';
     }
     return $output;
}
function chasm_spaces_strip($data)
{
     $data=str_replace("\r",'',$data);
     $data=str_replace("\n",'',$data);
     $data=str_replace(' ','',$data);
     $data=strtoupper($data);
     return $data;
}
?>

<!-- /* index.php
'CHASM - Contextual Hybrid (Dis)Assembler 0x01
'Created August 20th 2009 - March 14th 2010 by Timothy Robert Keal alias jargon
'Released under the Gnu Public License 2.0
'
'http://puzzlum.retromachineshop.com/
'irc://chat.freenode.net/puzzlum
'
'Please review the Gnu Public License, Thank you.
'The GPL can be located online at http://www.gnu.org/copyleft/gpl.html
*/ -->
<html><head><title>CHASM - Contextual Hybrid (Dis)Assembler</title></head><body>
<h1>CHASM - Contextual Hybrid (Dis)Assembler</h1>
<h3>Created August 20th 2009 - March 14th 2010 by Timothy Robert Keal alias jargon</h3>
<p>Created August 20th 2009 - March 14th 2010 by Timothy Robert Keal alias jargon<br>
Released under the Gnu Public License 2.0</p>
<p><a href="http://puzzlum.retromachineshop.com/">http://puzzlum.retromachineshop.com/</a><br>
<a href="irc://chat.freenode.net/puzzlum">irc://chat.freenode.net/puzzlum</a></p>
<p>Please review the Gnu Public License, Thank you.<br>
The GPL can be located online at <a href="http://www.gnu.org/copyleft/gpl.html">http://www.gnu.org/copyleft/gpl.html</a></p>
<form action="./" enctype="multipart/form-data" method="post">
<table cellspacing=8 cellpadding=0 border=0><tr><td align="left" valign="top">
<?php /*index.php*/
include_once('./chasm.php');
$processor=$_POST['processor'];
$data=$_POST['data'];
$action=$_POST['action'];
if(strlen($processor)!==0){
     if($action==='disasm')
     {
          $ln=null;
          $output='';
          $d=$data;
          if((strpos($d,'[')!==false)&&(strpos($d,']')!==false))
          {          
               while((strpos($d,'[')!==false)&&(strpos($d,']')!==false))
               {
                    if(strpos($d,']')>strpos($d,'['))
                    {
                         $ln=file_lines(substr($d,0,strpos($d,'[')));
                         $index=0;
                         while($index<$ln['ct'])
                         {
                              if((strlen($output)>0)&&(substr($output,strlen($output)-2,2)!=="\r\n"))
                              {
                                   $output.="\r\n";
                              }
                              $output.=';'.$ln[$index];
                              $index++;
                         }
                         $d=substr($d,strpos($d,'[')+1);
                         if((strlen($output)>0)&&(substr($output,strlen($output)-2,2)!=="\r\n"))
                         {
                              $output.="\r\n";
                         }
                         $output.=chasm_disasm($processor,substr($d,0,strpos($d,']')));
                         $d=substr($d,strpos($d,']')+1);                         
                    }
                    else
                    {
                         $ln=file_lines($d);
                         $index=0;
                         while($index<$ln['ct'])
                         {
                              if((strlen($output)>0)&&(substr($output,strlen($output)-2,2)!=="\r\n"))
                              {
                                   $output.="\r\n";
                              }
                              $output.=';'.$ln[$index];
                              $index++;
                         }
                         $d='';
                    }
                    $index++;
               }
               $ln=file_lines($d);
               $index=0;
               while($index<$ln['ct'])
               {
                    if((strlen($output)>0)&&(substr($output,strlen($output)-2,2)!=="\r\n"))
                    {
                         $output.="\r\n";
                    }
                    $output.=';'.$ln[$index];
                    $index++;
               }
               $d='';
          }
          else
          {
               $d=str_replace(' ','',$data);
               $output=chasm_disasm($processor,$d);
          }
          $output=';Disassembled using CHASM for the '.$processor.' processor!'."\r\n".$output;

     }
     if($action==='asm')
     {
          $output=chasm_asm($processor,$data);
     }
     $output=str_replace("\r\n","\n",$output);
     echo '<p><b>Data:</b><br><textarea name="data" size="40" rows="15" cols="60" style="width: 500px; height: 350px;">'.$output.'</textarea></p>';
}
else
{
     echo '<p><b>Data:</b><br><textarea name="data" size="40" rows="15" cols="60" style="width: 500px; height: 350px;">00 25 20 2C 53 D7 18 D9 00 F3 D8 F8 00</textarea></p>';
}
echo '</td><td align="center" valign="top">';
echo '<p><b>Processor:</b><br>';
echo '<select name="processor" size="5" style="width: 225px;">';
$proclist=glob('*.chasm');
sort($proclist);
foreach($proclist as $fn)
{
     $proctmp=substr($fn,0,strlen($fn)-strlen('.chasm'));
     echo '<option value="'.$proctmp.'"';
     if($processor===$proctmp)
     {
          echo ' selected';
     }
     echo '>'.$proctmp.'</option>';
}
echo '</select></p>';
echo '<p><b>Action:</b><br>';
echo '<select name="action" size="5" style="width: 225px;">';
echo '<option value="disasm"';
if($action!=='asm')
{
     echo ' selected';
}
echo '>Disassemble</option><option value="asm"';
if($action==='asm')
{
     echo ' selected';
}
echo '>Assemble</option>';
?>
</select></p>
<p><input type="submit" value="Submit"></p>
</td></tr></table>
</form>
<h1><a href="./list.php">Click to view source code.</a></h1>
<h1><a href="./6502.chasm">Click to view "6502.chasm"</a></h1>
<h1><a href="./arm.chasm">Click to sneak peak the work-in-progress "arm.chasm"</a></h1>
<h1><a href="./chasm01-1.zip">Click to download "CHASM 0x01-1" install archive.</a></h1>
</body></html>