Exemplo n.º 1
0
        bool AddDirectoryEntry(GR.Memory.ByteBuffer Filename, int StartTrack, int StartSector, int SectorsWritten, C64Studio.Types.FileType Type)
        {
            _LastError = "";
            Track dirTrack      = Tracks[TRACK_DIRECTORY - 1];
            byte  dirTrackIndex = (byte)TRACK_DIRECTORY;

            for (int sector = SECTOR_DIRECTORY; sector < dirTrack.Sectors.Count; ++sector)
            {
                Sector sect = dirTrack.Sectors[sector];
                for (int i = 0; i < 8; ++i)
                {
                    if (sect.Data.ByteAt(BYTES_PER_DIR_ENTRY * i + 2) == 0)
                    {
                        // scratched (empty) entry

                        // default set PRG
                        if (i > 0)
                        {
                            // set track/sector of next dir sector
                            sect.Data.SetU8At(BYTES_PER_DIR_ENTRY * i + 0, 0);
                            sect.Data.SetU8At(BYTES_PER_DIR_ENTRY * i + 1, 0);
                        }
                        sect.Data.SetU8At(BYTES_PER_DIR_ENTRY * i + 2, (byte)Type);
                        sect.Data.SetU8At(BYTES_PER_DIR_ENTRY * i + 3, (byte)StartTrack);
                        sect.Data.SetU8At(BYTES_PER_DIR_ENTRY * i + 4, (byte)StartSector);

                        for (int j = 0; j < 16; ++j)
                        {
                            sect.Data.SetU8At(BYTES_PER_DIR_ENTRY * i + 5 + j, Filename.ByteAt(j));
                        }
                        sect.Data.SetU16At(BYTES_PER_DIR_ENTRY * i + 30, (UInt16)SectorsWritten);
                        return(true);
                    }
                }
                // do we need to alloc next dir sector?
                if (sector + 1 == dirTrack.Sectors.Count)
                {
                    // disk full!! (or continue on next track?)
                    _LastError = "disk is full";
                    return(false);
                }
                if (sect.Data.ByteAt(0) == 0)
                {
                    // current sector was last dir sector
                    sect.Data.SetU8At(0, dirTrackIndex);
                    sect.Data.SetU8At(1, (byte)(sector + 1));
                    AllocSector(dirTrackIndex, sector + 1);

                    dirTrack.Sectors[sector + 1].Data.SetU8At(0, 0);
                    dirTrack.Sectors[sector + 1].Data.SetU8At(1, 0xff);
                }
            }
            _LastError = "disk is full";
            return(false);
        }
Exemplo n.º 2
0
        public override bool WriteFile(GR.Memory.ByteBuffer Filename, GR.Memory.ByteBuffer Content, C64Studio.Types.FileType Type)
        {
            _LastError = "";
            GR.Memory.ByteBuffer dataToWrite = new GR.Memory.ByteBuffer(Content);
            if (dataToWrite.Length > FreeBytes())
            {
                _LastError = "file too large";
                return(false);
            }

            Sector bam = Tracks[TRACK_BAM - 1].Sectors[SECTOR_BAM];

            int    trackIndex     = 1;
            int    prevSector     = 0;
            int    interleave     = 10;
            int    bytesToWrite   = (int)dataToWrite.Length;
            int    writeOffset    = 0;
            Sector previousSector = null;
            int    searchSector   = -1;

            int startSector    = -1;
            int startTrack     = -1;
            int sectorsWritten = 0;

            write_next_sector :;
            trackIndex = 1;
            foreach (Track track in Tracks)
            {
                if (trackIndex == TRACK_DIRECTORY)
                {
                    // directory track
                    ++trackIndex;
                    continue;
                }
                if (track.FreeSectors == 0)
                {
                    ++trackIndex;
                    continue;
                }

                int sectorsPerTrack = track.Sectors.Count;
                searchSector = (prevSector + interleave) % sectorsPerTrack;

                while (true)
                {
                    if (track.Sectors[searchSector].Free)
                    {
                        AllocSector(trackIndex, searchSector);
                        if (previousSector != null)
                        {
                            previousSector.Data.SetU8At(0, (byte)trackIndex);
                            previousSector.Data.SetU8At(1, (byte)searchSector);
                        }
                        else
                        {
                            // first sector, add directory entry
                            startSector = searchSector;
                            startTrack  = trackIndex;
                        }
                        previousSector = track.Sectors[searchSector];
                        if (bytesToWrite > 254)
                        {
                            //Debug.Log( "Write to T/S " + trackIndex + "," + searchSector );
                            dataToWrite.CopyTo(previousSector.Data, writeOffset, 254, 2);
                            previousSector.Free = false;
                            writeOffset        += 254;
                            bytesToWrite       -= 254;
                            ++sectorsWritten;
                            prevSector = searchSector;
                            goto write_next_sector;
                        }
                        // last sector
                        //Debug.Log( "Write to T/S " + trackIndex + "," + searchSector );
                        previousSector.Free = false;
                        previousSector.Data.SetU8At(0, 0);
                        previousSector.Data.SetU8At(1, (byte)(1 + bytesToWrite));
                        dataToWrite.CopyTo(previousSector.Data, writeOffset, bytesToWrite, 2);
                        writeOffset += bytesToWrite;
                        bytesToWrite = 0;
                        ++sectorsWritten;

                        AddDirectoryEntry(Filename, startTrack, startSector, sectorsWritten, Type);
                        return(true);
                    }
                    else
                    {
                        ++searchSector;
                        if (searchSector >= sectorsPerTrack)
                        {
                            searchSector = 0;
                        }
                    }
                }
            }
            _LastError = "disk is full";
            return(false);
        }
Exemplo n.º 3
0
        bool AddDirectoryEntry(GR.Memory.ByteBuffer Filename, int StartTrack, int StartSector, int SectorsWritten, C64Studio.Types.FileType Type)
        {
            _LastError = "";
            Track dirTrack      = Tracks[TRACK_DIRECTORY - 1];
            byte  dirTrackIndex = (byte)TRACK_DIRECTORY;

            int directoryInterleave = 3;

            int sector = 1;

            do
            {
                Sector sect = dirTrack.Sectors[sector];
                for (int i = 0; i < 8; ++i)
                {
                    if (sect.Data.ByteAt(BYTES_PER_DIR_ENTRY * i + 2) == 0)
                    {
                        // scratched (empty) entry
                        // default set PRG
                        if (i > 0)
                        {
                            // set track/sector of next dir sector
                            sect.Data.SetU8At(0, 0);
                            sect.Data.SetU8At(1, 0);
                        }
                        sect.Data.SetU8At(BYTES_PER_DIR_ENTRY * i + 2, (byte)Type);
                        sect.Data.SetU8At(BYTES_PER_DIR_ENTRY * i + 3, (byte)StartTrack);
                        sect.Data.SetU8At(BYTES_PER_DIR_ENTRY * i + 4, (byte)StartSector);

                        for (int j = 0; j < 16; ++j)
                        {
                            sect.Data.SetU8At(BYTES_PER_DIR_ENTRY * i + 5 + j, Filename.ByteAt(j));
                        }
                        sect.Data.SetU16At(BYTES_PER_DIR_ENTRY * i + 30, (UInt16)SectorsWritten);
                        return(true);
                    }
                }
                // do we need to alloc next dir sector?
                do
                {
                    sector = (sector + directoryInterleave) % dirTrack.Sectors.Count;

                    // do NOT write into BAM
                }while (sector == SECTOR_BAM);

                if (sector == 1)
                {
                    // arrived at starting sector, disk full!
                    break;
                }
                if (sect.Data.ByteAt(0) == 0)
                {
                    // current sector was last dir sector
                    sect.Data.SetU8At(0, dirTrackIndex);
                    sect.Data.SetU8At(1, (byte)(sector));
                    AllocSector(dirTrackIndex, sector);

                    dirTrack.Sectors[sector].Data.SetU8At(0, 0);
                    dirTrack.Sectors[sector].Data.SetU8At(1, 0xff);
                }
            }while (true);
            _LastError = "disk is full";
            return(false);
        }
Exemplo n.º 4
0
 public abstract bool WriteFile(GR.Memory.ByteBuffer Filename, GR.Memory.ByteBuffer Content, C64Studio.Types.FileType Type);
Exemplo n.º 5
0
        public override bool WriteFile(GR.Memory.ByteBuffer Filename, GR.Memory.ByteBuffer Content, C64Studio.Types.FileType Type)
        {
            _LastError = "";

            int fileIndex = 0;

            foreach (FileRecord file in FileRecords)
            {
                if (file.EntryType == 0)
                {
                    // free slot found
                    file.EntryType   = 1;
                    file.C64FileType = Type;
                    if (Type == C64Studio.Types.FileType.PRG)
                    {
                        file.StartAddress = Content.UInt16At(0);
                        if (Content.Length < 2)
                        {
                            FileDatas[fileIndex] = new GR.Memory.ByteBuffer();
                        }
                        else
                        {
                            FileDatas[fileIndex] = Content.SubBuffer(2);
                        }
                    }
                    else
                    {
                        file.StartAddress    = 0x0801;
                        FileDatas[fileIndex] = new GR.Memory.ByteBuffer(Content);
                    }
                    file.EndAddress = (ushort)(file.StartAddress + Content.Length);
                    file.FileOffset = 0;
                    file.Filename   = Filename;
                    return(true);
                }
                ++fileIndex;
            }
            _LastError = "tape image is full";
            return(false);
        }
Exemplo n.º 6
0
        public override bool WriteFile(GR.Memory.ByteBuffer Filename, GR.Memory.ByteBuffer Content, C64Studio.Types.FileType Type)
        {
            _LastError = "";
            FileEntry file = new FileEntry();

            file.Filename = new GR.Memory.ByteBuffer(Filename);
            file.Data     = new GR.Memory.ByteBuffer(Content);
            if (Type == C64Studio.Types.FileType.PRG)
            {
                if (Content.Length >= 2)
                {
                    file.StartAddress = Content.UInt16At(0);
                    file.Data         = Content.SubBuffer(2);
                }
            }
            file.EndAddress = (ushort)(file.StartAddress + file.Data.Length - 1);
            if (file.StartAddress + file.Data.Length >= 65536)
            {
                _LastError = "file size too large";
                return(false);
            }
            TapFiles.Add(file);
            return(true);
        }
Exemplo n.º 7
0
 public override bool WriteFile(GR.Memory.ByteBuffer Filename, GR.Memory.ByteBuffer Content, C64Studio.Types.FileType Type)
 {
     _LastError = "";
     if ((Data.Length > 0) ||
         (Type != C64Studio.Types.FileType.PRG))
     {
         _LastError = "invalid file type";
         return(false);
     }
     Data          = new GR.Memory.ByteBuffer(Content);
     this.Filename = Filename;
     return(true);
 }