Ejemplo n.º 1
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    fileInterleave = 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 + fileInterleave) % 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);
        }
Ejemplo n.º 2
0
 public abstract bool WriteFile(GR.Memory.ByteBuffer Filename, GR.Memory.ByteBuffer Content, C64Studio.Types.FileType Type);
Ejemplo 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?
                sector = (sector + directoryInterleave) % dirTrack.Sectors.Count;
                if (sector == 1)
                {
                    // 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);
        }