Exemple #1
0
        // ************** Extract File CP/M  *********************
        // inputs: path and filename, disk entry structure
        // output: requested file
        public int ExtractFileCPM(Form1.DiskFileEntry disk_file_entry)
        {
            var disk_image_file = disk_file_entry.DiskImageName;
            var result          = 1; // assume success
            int temp;
            var diskType    = 0;
            var ctr         = 0;     // for loop counter
            var maxBuffSize = 0x800; // largest allocation block size
            int allocBlock  = 0,
                dirStart    = 0,
                dirSize     = 0,
                interleave  = 0,
                spt         = 0,
                sectorSize  = 0;                     // disk parameter values
            var buff        = new byte[maxBuffSize]; // disk buffer equal to largest allocation block size
            var wBuff       = new byte[maxBuffSize]; //   write buffer
            //var directory = new List<FCBlist>();
            var skewMap =
                new int[16, 2];          // max number of sectors on a Heathkit floppy. Fill must be greater than buffer size

            for (var i = 0; i < 16; i++) // initialize skew table
            {
                skewMap[i, 0] = 32;
                skewMap[i, 1] = i;
            }

            // debug
            // var cpmFile = new CPMFile();
            //var temp1 = FCBfirst.Count;

            var encoding = new UTF8Encoding();
            var dir      = string.Format("{0}_Files",
                                         disk_image_file); // create directory name and check if directory exists

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            fnameb = encoding.GetBytes(disk_file_entry.FileName);

            // Create output File
            var name      = disk_file_entry.FileName.Substring(0, 8).Trim(' ');
            var ext       = disk_file_entry.FileName.Substring(8, 3).Trim(' ');
            var file_name = string.Format("{0}\\{1}.{2}", dir, name, ext);

            if (File.Exists(file_name))
            {
                if (MessageBox.Show("File exists, Overwrite it?", "File Exists", MessageBoxButtons.YesNo) ==
                    DialogResult.No)
                {
                    result = 0;
                    return(result);
                }
                else
                {
                    file_name = file_name + "1";
                }
            }

            var file_out = File.Create(file_name);
            var bin_out  = new BinaryWriter(file_out);


            // Open input file
            var file     = File.OpenRead(disk_image_file);
            var bin_file = new BinaryReader(file);

            temp = bin_file.Read(buff, 0, 256);
            var t = buff.Length;

            diskType = (int)buff[5];

            /* debug
             * ctr = DiskType.GetLength(0);
             * ctr = DiskType.GetLength(1);
             */
            for (ctr = 0; ctr < DiskType.GetLength(0); ctr++) // search DiskType array for values
            {
                if (diskType == DiskType[ctr, 0])
                {
                    break;
                }
            }

            // use default if no match found
            if (ctr == DiskType.GetLength(0))
            {
                ctr = DiskType.GetLength(0) - 1; // default H17 format
            }
            allocBlock = DiskType[ctr, 1];       // ALB Size
            dirStart   = DiskType[ctr, 2];       // physical start of directory
            dirSize    = DiskType[ctr, 4];       // size of the directory
            interleave = DiskType[ctr, 5];       // disk interleave
            spt        = DiskType[ctr, 6];       // sectors per track
            sectorSize = DiskType[ctr, 7];       // sector size           //else
                                                 // read the directory
            BuildSkew(ref skewMap, interleave, spt);
            // read directory sectors and place in sequential order in buff
            for (var i = 0; i < dirSize / allocBlock; i++)
            {
                GetALB(ref buff, allocBlock * i, bin_file, i, dirStart, allocBlock, sectorSize, spt, skewMap);
            }
            BuildDir(ref buff, dirSize, ref FCBfirst, fnameb);             // build FCB list for filename
            foreach (var f in FCBfirst)
            {
                var fcbNum = f.fcbnum;
                var cpmAlb = allocBlock / 128;              // number of 128 byte CP/M records in the allocation block
                var rBptr  = 0;
                var wBptr  = 0;
                for (var i = 0; i < 16; i++)
                {
                    if (f.fcb[i] > 0)
                    {
                        rBptr = wBptr = 0;
                        GetALB(ref buff, 0, bin_file, f.fcb[i], dirStart, allocBlock, sectorSize, spt, skewMap);
                        for (var j = 0; j < cpmAlb; j++)
                        {
                            if (fcbNum > 0)
                            {
                                for (var l = 0; l < 128; l++)
                                {
                                    wBuff[wBptr++] = buff[rBptr++];
                                }
                            }
                            fcbNum--;
                        }
                        bin_out.Write(wBuff, 0, wBptr);
                    }
                }
            }
            bin_out.Close();
            file_out.Close();

            bin_file.Close();
            file.Close();
            return(result);
        }
Exemple #2
0
        //***************** Extract File CP/M IMD
        // Call ReadImdDisk to make sure image is in memory
        // Check to make sure file is in DirList
        public int ExtractFileCPMImd(Form1.DiskFileEntry diskFileEntry)
        {
            var diskImage = diskFileEntry.DiskImageName;
            //var fileNameListtemp = new List<CPMFile.DirList>();
            long diskUsed = 0, diskTotal = 0;
            int  result = 0;



            var fileNameListTemp = ReadImdDir(diskImage, ref diskTotal);
            var obj = fileNameList.FirstOrDefault(x => x.fname == diskFileEntry.FileName);

            if (obj != null)
            {
                var encoding = new UTF8Encoding();
                var dir      = string.Format("{0}_Files", diskImage); // create directory name and check if directory exists
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
                fnameb = encoding.GetBytes(diskFileEntry.FileName);

                // Create output File
                var name      = diskFileEntry.FileName.Substring(0, 8).Trim(' ');
                var ext       = diskFileEntry.FileName.Substring(8, 3).Trim(' ');
                var file_name = string.Format("{0}\\{1}.{2}", dir, name, ext);

                if (File.Exists(file_name))
                {
                    if (MessageBox.Show("File exists, Overwrite it?", "File Exists", MessageBoxButtons.YesNo) ==
                        DialogResult.No)
                    {
                        result = 0;
                        return(result);
                    }
                    else
                    {
                        file_name = file_name + "1";
                    }
                }

                var file_out = File.Create(file_name);
                var bin_out  = new BinaryWriter(file_out);


                // Read file data from memory buffer
                byte[] wBuff = new byte[fileNameList[0].fsize * 1024 + 256];          // write buffer = file size plus a buffer
                int    wBPtr = 0;
                var    t0    = 0;
                foreach (var f in obj.fcbList)
                {
                    t0++;
                    var fcbNum = f.fcbnum;                                  // number of 128 byte CP/M records in the FCB
                    for (var i = 0; i < 16 / albNumSize && fcbNum > 0; i++) // read each fcb block in record. may be 8 or 16 values
                    {
                        if (f.fcb[i] > 0)                                   // only process valid allocation blocks
                        {
                            var sectPerAlb = albSize / sectorSize;
                            //var t2 = f.fcb[i] * sectPerAlb + dirSectStart; // debug
                            for (var albCnt = 0; albCnt < sectPerAlb; albCnt++) // number of sectors to read in this allocation block
                            {
                                //var t3 = f.fcb[i] * sectPerAlb + dirSectStart + albCnt;
                                var bufPtr  = diskMap[f.fcb[i] * sectPerAlb + dirSectStart + albCnt]; // location of sector in buf[]
                                var bufData = buf[bufPtr];                                            // get IMD sector marker. If odd, a sector worth of data follows

                                if (bufData % 2 > 0)                                                  // IMD sector marker. odd number equals sector worth of data
                                {
                                    bufPtr++;                                                         // point to first data byte
                                    int k = 0;                                                        // declared outside for loop to preserve value
                                    for (; k < sectorSize / 128 && k < fcbNum; k++)                   // read only one sector or the number of fcb records left
                                    {
                                        for (var j = 0; j < 128; j++)
                                        {
                                            wBuff[wBPtr++] = buf[bufPtr++];
                                        }
                                    }
                                    fcbNum -= k; // decrement fcbnum counter by number of records read
                                }
                                else
                                // IMD marker even, sector is compressed. next byte equals sector data
                                {
                                    bufPtr++;
                                    int k = 0;

                                    for (; k < sectorSize / 128 && k < fcbNum; k++)
                                    {
                                        for (var j = 0; j < 128; j++)
                                        {
                                            wBuff[wBPtr++] = buf[bufPtr];
                                        }
                                    }
                                    fcbNum -= k; // decrement fcbnum counter by number of records read
                                }
                            }
                        }
                    }
                }
                wBPtr--;
                bin_out.Write(wBuff, 0, wBPtr);
                bin_out.Close();
                file_out.Close();
                result = 1;
            }
            else
            {
                MessageBox.Show(diskFileEntry.FileName + " error. File not found in DirList", "Error", MessageBoxButtons.OK);
            }

            return(result);
        }