misc/pattobytes.pl- Source code ソースコード - XEiJ - STUDIO KAMADA
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;
      }
    }

STUDIO KAMADA
Copyright © 1999-2026 Makoto Kamada