開発環境 Microsoft Visual Studio Community 2017
実行環境 Microsoft Windows 10 Home (64-bit)
プロジェクトの種類 Visual C# / コンソール アプリ (.NET Framework)
プロジェクト名 bin2t88



Program.cs
using System;
using System.IO;
 
namespace bin2t88
{
    class Program
    {
        private static BinaryWriter bw;
        private static int elapse;    // 経過時間
 
        static void Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("usage: bin2t88 ファイル名 開始アドレス バイナリファイル");
                Console.WriteLine("ex) bin2t88 SAMPLE b000 filename.bin");
                return;
            }
            string filename = args[0];
            int start = Convert.ToInt32(args[1], 16);   // HHHH or 0xHHHH
            string binfile = args[2];
            string t88file = binfile + ".t88";
            if (! File.Exists(binfile))
            {
                Console.WriteLine(binfile+": ファイルが存在しません。");
                return;
            }
 
            using (var fs = File.Create(t88file))
            {
                bw = new BinaryWriter(fs);
                elapse = 0;
 
                bw.Write("PC-8801 Tape Image(T88)\0".ToCharArray());    // ファイルヘッダ
                write_ver();
                write_space(7928);
                write_mark(1322);
                write_filename(filename);
                write_mark(330);
                write_data(start, binfile);
                write_mark(3966);
                write_space(9252);
                write_tag(0x0000, 0);   // 終了タグ
 
                bw.Close();
            }
        }
 
        private static void write_tag(int id, int len)
        {
            bw.Write((ushort)id);
            bw.Write((ushort)len);
        }
 
        private static void write_tick(int tick)
        {
            bw.Write(elapse);
            bw.Write(tick);
            elapse += tick;
        }
 
        // バージョン
        private static void write_ver()
        {
            write_tag(0x0001, 2);
            bw.Write((ushort)0x0100);
        }
 
        // データタグ
        private static void write_data_tag(int datlen)
        {
            write_tag(0x0101, 12 + datlen);
            write_tick(44 * datlen);
            bw.Write((ushort)datlen);
            bw.Write((ushort)0x01cc);
        }
 
        // スペース(0)
        private static void write_space(int tick)
        {
            write_tag(0x0102, 8);
            write_tick(tick);
        }
 
        // マーク(1)
        private static void write_mark(int tick)
        {
            write_tag(0x0103, 8);
            write_tick(tick);
        }
 
        private static void write_filename(string filename)
        {
            string str = "$$$" + (filename + "      ").Remove(6);
            write_data_tag(9);
            bw.Write(str.ToCharArray());
        }
 
        private static void write_data(int start, string binfile)
        {
            using (var fs = File.OpenRead(binfile))
            {
                var buf = new byte[256];
                var blk = (int)Math.Ceiling(fs.Length / 128.0);
                write_data_tag((int)fs.Length + 7 + 3 * blk);
 
                // 開始アドレス
                buf[0] = (byte)(start >> 8);
                buf[1] = (byte)(start & 0xff);
                write_data_check(buf, 2);
 
                // データ
                while (true)
                {
                    var read = fs.Read(buf, 1, 128);
                    if (read <= 0) break;
                    buf[0] = (byte)read;
                    write_data_check(buf, 1 + read);
                }
 
                // 終了
                buf[0] = 0;
                write_data_check(buf, 1);
            }
        }
 
        private static void write_data_check(byte[] buf, int len)
        {
            int sum = 0;
            for (var i = 0; i < len; i++)
            {
                sum += buf[i];
            }
            int check = 0x100 - (sum & 0xff);   // チェックバイト
            bw.Write((byte)0x3a);
            bw.Write(buf, 0, len);
            bw.Write((byte)check);
        }
    }
}
 
最終更新:2018年07月25日 07:39