mirror of
https://github.com/cshepherd/yagsdisasm.git
synced 2024-12-27 00:29:20 +00:00
182 lines
4.0 KiB
PHP
182 lines
4.0 KiB
PHP
<?php
|
|
/*
|
|
* YAGSDisasm - A 65C816 disassembler for Apple IIGS code and disk images
|
|
*
|
|
*/
|
|
require_once( 'Input/Input_2MG.php' );
|
|
require_once( 'Input/Input_PO.php' );
|
|
require_once( 'Input/Input_BIN.php' );
|
|
require_once( 'Disassembler/Disassembler_65816.php' );
|
|
require_once( 'Personality/Personality_AppleIIGS.php' );
|
|
|
|
// version string
|
|
$version_str = '1.0a';
|
|
|
|
/*
|
|
* begin options parsing here
|
|
*/
|
|
$options = getopt( 'p:e:x:m:f:s:n:o:Vvhk:' );
|
|
|
|
if( isset( $options['V'] ))
|
|
{
|
|
echo "Version: {$version_str}\n";
|
|
exit;
|
|
}
|
|
|
|
if( isset( $options['h'] ))
|
|
{
|
|
echo <<<EOF
|
|
YAGSDisasm - A 65C816 disassembler for Apple IIGS code and disk images
|
|
|
|
usage: php yagsdisasm.php [options]
|
|
-p specify machine personality (for auto commenting and formatting)
|
|
iigs - Apple IIGS (this is presently the only target)
|
|
-e value of E cpu flag (1 is emulation mode)
|
|
-x value of X cpu flag (1 is short X/Y register)
|
|
-m value of M cpu flag (1 is short accumulator)
|
|
-f specifies input file (required)
|
|
-i specifies format of input
|
|
2mg - .2mg disk (see -s, -n options)
|
|
po - .po disk image (see -s, -n options)
|
|
bin - binary blob (see -s, -n options which will refer to bytes instead of blocks, default is to disassemble the whole thing)
|
|
default behavior is to guess by file extension
|
|
-s starting disk block to disassemble (if input is binary blob, this is starting offset into file)
|
|
-n number of disk blocks to disassemble (if input is binary blob, this is length to disassemble from file)
|
|
-k skip this number of bytes from beginning when disassembling
|
|
-o 24-bit origin address, in hex (eg 002000)
|
|
addresses shorter than 24 bits will be zero-filled
|
|
addresses longer than 24 bits will be truncated
|
|
-v verbose/debugging info
|
|
-V print version information and exit
|
|
|
|
EOF;
|
|
exit;
|
|
}
|
|
|
|
// handle defaults and specification for filename and format
|
|
if( !isset( $options['f'] ))
|
|
{
|
|
echo "Filename must be specified with -f\n";
|
|
exit;
|
|
}
|
|
|
|
$filename = $options['f'];
|
|
$format = 'po';
|
|
$parts = explode( '.', $filename );
|
|
if( strtolower( $parts[count($parts)-1] ) == '2mg' )
|
|
{
|
|
$format = '2mg';
|
|
}
|
|
|
|
if( isset( $options['i'] ))
|
|
{
|
|
$known_type = false;
|
|
if( $options['i'] == '2mg' )
|
|
{
|
|
$format = '2mg';
|
|
$known_type = true;
|
|
}
|
|
if( $options['i'] == 'po' )
|
|
{
|
|
$format = 'po';
|
|
$known_type = true;
|
|
}
|
|
if( $options['bin'] == 'bin' )
|
|
{
|
|
$format = 'bin';
|
|
$known_type = true;
|
|
}
|
|
if( !$known_type )
|
|
{
|
|
echo "Unknown input image type: ".$options['i']."\n";
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// handle defaults and specification for starting block and ending block
|
|
if( $format == 'bin' )
|
|
{
|
|
$starting_block = 0;
|
|
$num_blocks = 'all';
|
|
} else {
|
|
$starting_block = 0;
|
|
$num_blocks = 1;
|
|
}
|
|
if( isset( $options['s'] ))
|
|
{
|
|
$starting_block = intval( $options['s'] );
|
|
}
|
|
if( isset( $options['n'] ))
|
|
{
|
|
$num_blocks = intval( $options['n'] );
|
|
}
|
|
|
|
// handle defaults and specifications for M, X, E cpu flags
|
|
$m_flag = 1;
|
|
$x_flag = 1;
|
|
$e_flag = 1;
|
|
if( isset( $options['m'] ))
|
|
{
|
|
$m_flag = intval( $options['m'] );
|
|
}
|
|
if( isset( $options['x'] ))
|
|
{
|
|
$x_flag = intval( $options['x'] );
|
|
}
|
|
if( isset( $options['e'] ))
|
|
{
|
|
$e_flag = intval( $options['e'] );
|
|
}
|
|
|
|
// handle verbosity
|
|
$verbose = false;
|
|
if( isset( $options['v'] ))
|
|
{
|
|
$verbose = true;
|
|
}
|
|
|
|
// handle origin address
|
|
$origin = 0x1000;
|
|
if( isset( $options['o'] ))
|
|
{
|
|
$origin = hexdec( $options['o'] );
|
|
}
|
|
|
|
// handle skip amount
|
|
$skip = 0;
|
|
if( isset( $options['k'] ))
|
|
{
|
|
$skip = $options['k'];
|
|
}
|
|
|
|
/*
|
|
* begin main operations here
|
|
*/
|
|
switch( $format )
|
|
{
|
|
case 'bin': $fh = new Input_BIN( $filename );
|
|
$data = $fh->getBlocks( $starting_block, $num_blocks );
|
|
break;
|
|
case '2mg': $fh = new Input_2MG( $filename );
|
|
$data = $fh->getBlocks( $starting_block, $num_blocks );
|
|
break;
|
|
case 'po': $fh = new Input_PO( $filename );
|
|
$data = $fh->getBytes( $starting_block, $num_blocks );
|
|
break;
|
|
}
|
|
if( $verbose )
|
|
{
|
|
echo "Processed {$format} file {$filename}\n";
|
|
$fh->printInfo();
|
|
}
|
|
|
|
if( $skip > 0 )
|
|
{
|
|
$data = substr( $data, $skip );
|
|
}
|
|
|
|
$pers = new Personality_AppleIIGS;
|
|
|
|
$dh = new Disassembler_65816;
|
|
$dh->disassemble( $m_flag, $x_flag, $e_flag, $origin, $data, $pers );
|