misc/pattobytes.pl
#========================================================================================
# pattobytes.pl
# Copyright (C) 2003-2021 Makoto Kamada
#
# This file is part of the XEiJ (X68000 Emulator in Java).
# You can use, modify and redistribute the XEiJ if the conditions are met.
# Read the XEiJ License for more details.
# https://stdkmd.net/xeij/
#========================================================================================
use strict; #厳密な文法に従う
use warnings; #警告を表示する
use utf8; #UTF-8で記述する
{
my ($id, $fn) = @ARGV; #識別子とパッチファイル名
#パッチファイルを読み込む
open IN, '<', $fn or die "$fn not found";
binmode IN;
my $head_buffer; #X形式実行ファイルのヘッダ
read IN, $head_buffer, 64;
my $base_address = vec $head_buffer, 1, 32; #挿入コードのベースアドレス
my $text_size = vec $head_buffer, 3, 32; #textセクション(追加コード)の長さ
8 <= $text_size or die "text_size=$text_size";
my $data_size = vec $head_buffer, 4, 32; #dataセクション(挿入コード)の長さ
4 <= $data_size or die "data_size=$data_size";
my $text_buffer = ''; #textセクション(追加コード)
read IN, $text_buffer, $text_size;
my $data_buffer = ''; #dataセクション(挿入コード)
read IN, $data_buffer, $data_size;
close IN;
#(追加コードの長さ)<=(追加コードの末尾アドレス+1-追加コードの先頭アドレス)を確認する
my ($text_start, $text_end) = unpack 'N2', substr $data_buffer, 0, 8; #先頭アドレス,末尾アドレス
my $offset = $base_address - $text_start;
if ($offset == 0) {
printf " // text: \$%08X-\$%08X %d/%d %s\n",
$text_start, $text_end,
$text_size, $text_end + 1 - $text_start,
$text_size <= $text_end + 1 - $text_start ? 'OK' : 'ERROR';
} else {
printf " // text: \$%08X-\$%08X \$%08X-\$%08X %d/%d %s\n",
$text_start, $text_end,
$text_start + $offset, $text_end + $offset,
$text_size, $text_end + 1 - $text_start,
$text_size <= $text_end + 1 - $text_start ? 'OK' : 'ERROR';
}
#(挿入コードの長さ)<=(挿入コードの末尾アドレス+1-挿入コードの先頭アドレス)を確認する
my $pointer = 8;
while (1) {
my $start = unpack 'N', substr $data_buffer, $pointer, 4; #先頭アドレス
$start == 0 and last;
my ($end, $original, $size) = unpack 'N3', substr $data_buffer, $pointer + 4, 12; #末尾アドレス+1,元のデータ,長さ
if ($offset == 0) {
printf " // data: \$%08X-\$%08X %d/%d %s\n",
$start, $end,
$size, $end + 1 - $start,
$size <= $end + 1 - $start ? 'OK' : 'ERROR';
} else {
printf " // data: \$%08X-\$%08X \$%08X-\$%08X %d/%d %s\n",
$start, $end,
$start + $offset, $end + $offset,
$size, $end + 1 - $start,
$size <= $end + 1 - $start ? 'OK' : 'ERROR';
}
$pointer += 16 + $size;
}
#Javaのコードを出力する
foreach my $pair (['TEXT', $text_buffer], ['DATA', $data_buffer]) {
length $pair->[1] or next;
my $str = join '', map {
$_ == 8 ? '\\b' :
$_ == 9 ? '\\t' :
$_ == 10 ? '\\n' :
$_ == 12 ? '\\f' :
$_ == 13 ? '\\r' :
$_ == 34 || $_ == 39 || $_ == 92 ? sprintf '\\%c', $_ :
32 <= $_ && $_ <= 126 ? chr $_ :
sprintf '\\%03o', $_;
} unpack 'C*', $pair->[1];
$str =~ s/(?<!\\)((?:\\\\)*\\)00([0-7])(?![0-7])/$1$2/g;
$str =~ s/(?<!\\)((?:\\\\)*\\)0([0-7]{2})(?![0-7])/$1$2/g;
printf " public static final byte[] %s_%s = \"%s\".getBytes (XEiJ.ISO_8859_1);\n", $id, $pair->[0], $str;
}
}