#!/usr/bin/perl

$sgmt = "segments";
%minsg = ();
%maxsg = ();
open( IFILE, "$sgmt" ) || die "open $sgmt - $!\n";
open my $fh, '+<expanded.bin' or die "can't update expanded.bin: $!";
while( $ln = <IFILE> )
{
  if( $ln =~ /^(\w+):\s.a\s(\w\w)\s(\w\w)\s(\w\w)\s(\w\w)\s*$/ )
  {
    $patchad = eval( "0x$1" );
    $sg      = eval( "0x$5$4" ) << 8 ;
    $ad      = eval( "0x$3$2" );
    $fullad  = $sg + $ad;
		if( defined $minsg{$sg} )
		{
			$minsg{$sg} = $fullad if( $fullad < $minsg{$sg} );
			$maxsg{$sg} = $fullad if( $fullad > $maxsg{$sg} );
		}
		else
		{
			$minsg{$sg} = $fullad;
			$maxsg{$sg} = $fullad;
		}
    printf( "P 0x%05x 0x%05x\n", $patchad, $fullad );
    seek $fh, $patchad + 1, 0;
		$sgmad = ( $sg << 12) + $ad;
		print $fh pack( "L", $sgmad);
  }
}
close $fh;
close( IFILE );

print "\nSegments:\n\n";
open( OFILE, "> expanded.idc" ) || die "create expanded.idc - $!\n";
print( OFILE "#define UNLOADED_FILE   1\n#include <idc.idc>\n\n" .
       "static main(void)\n{\n" .
       "  // set 'loading idc file' mode\n" .
       "  SetCharPrm(INF_GENFLAGS, INFFL_LOADIDC|GetCharPrm(INF_GENFLAGS));\n" .
       "  Segments();           // segmentation\n" .
       "  SetCharPrm(INF_GENFLAGS, ~INFFL_LOADIDC&GetCharPrm(INF_GENFLAGS));\n" .
       "}\n\nstatic Segments(void) {\n  SetSelector(0X1,0);\n  ;\n" );

$base = 0;
foreach $sg ( sort { $minsg{$a} <=> $minsg{$b} } ( keys %minsg ) )
{
	printf( "0x%05x: 0x%05x-0x%05x\n", $sg, $minsg{$sg}, $maxsg{$sg} );
	if( $base != 0 )
	{
    printf( OFILE "  SegCreate(0x%05x,0x%05x,0x%x,0,1,2);\n", $prev, $minsg{$sg}, $base );
    printf( OFILE "  SegRename(0x%05x,\"seg_%03x\");\n", $prev, $prev >> 8);
    printf( OFILE "  SegClass (0x%05x,\"CODE\");\n", $prev );
  }
	$prev = $minsg{$sg};
	$prev = 0x500 if( $base == 0 );
	$base = $sg >> 4;
}
    printf( OFILE "  SegCreate(0x%05x,0xa4500,0x%x,0,1,2);\n", $prev, $base );
    printf( OFILE "  SegRename(0x%05x,\"seg_%03x\");\n", $prev, $prev >> 8);
    printf( OFILE "  SegClass (0x%05x,\"CODE\");\n", $prev );
print( OFILE "}\n" );
close( OFILE );
exit;
# end
