예제 #1
0
        public D64Drive(IEC iec, string filepath)
            : base(iec)
        {
            the_file = null;
            ram      = null;

            Ready         = false;
            orig_d64_name = filepath;

            for (int i = 0; i < chan_mode.Length - 1; i++)
            {
                chan_mode[i] = ChannelMode.CHMOD_FREE;
            }
            chan_mode[15] = ChannelMode.CHMOD_COMMAND;

            // Open .d64 file
            open_close_d64_file(filepath);
            if (the_file != null)
            {
                // Allocate 1541 RAM
                ram = new BytePtr(0x800);
                unsafe
                {
                    bam = (BAM *)(ram.Pointer + 0x700);
                }
                Reset();
                Ready = true;
            }
        }
예제 #2
0
        protected void set_error(ErrorCode1541 error)
        {
            if (error_ptr_buf != null)
            {
                error_ptr_buf.Dispose();
            }

            unsafe
            {
                error_ptr_buf = Errors_1541[(int)error];
                error_ptr = error_ptr_buf;
                error_len = Errors_1541[(int)error].Length;
            }

            // Set drive condition
            if (error != ErrorCode1541.ERR_OK)
                if (error == ErrorCode1541.ERR_STARTUP)
                    LED = DriveLEDState.DRVLED_OFF;
                else
                    LED = DriveLEDState.DRVLED_ERROR;
            else if (LED == DriveLEDState.DRVLED_ERROR)
                LED = DriveLEDState.DRVLED_OFF;

            the_iec.UpdateLEDs();
        }
예제 #3
0
        unsafe void chd64_cmd(byte *d64name)
        {
            using (BytePtr str = new BytePtr(IEC.NAMEBUF_LENGTH))
            {
                byte *p = str;

                // Convert .d64 file name
                for (int i = 0; i < IEC.NAMEBUF_LENGTH && (*p++ = conv_from_64(*d64name++, false)) != 0; i++)
                {
                    ;
                }

                close_all_channels();

                // G:. resets the .d64 file name to its original setting
                if (str[0] == '.' && str[1] == 0)
                {
                    open_close_d64_file(orig_d64_name);
                }
                else
                {
                    open_close_d64_file(str.ToString());
                }

                // Read BAM
                read_sector(18, 0, (byte *)bam);
            }
        }
예제 #4
0
파일: FSDrive.cs 프로젝트: rudzen/sharp-c64
        void find_first_file(BytePtr aName)
        {
            DirectoryInfo dir = new DirectoryInfo(dir_path);

            if (!dir.Exists)
            {
                return;
            }

            FileInfo[] files = dir.GetFiles();

            string name = aName.ToString();

            IEnumerator fenum = files.GetEnumerator();

            while (fenum.MoveNext() && (((FileInfo)fenum.Current).Name == "." || ((FileInfo)fenum.Current).Name == ".."))
            {
                ;
            }

            do
            {
                FileInfo fi = (FileInfo)fenum.Current;

                // Match found? Then copy real file name
                if (match(name, fi.Name))
                {
                    CharFunctions.strncpy(aName, fi.Name);
                    return;
                }
            } while (fenum.MoveNext());
        }
예제 #5
0
        byte open_direct(int channel, BytePtr filename)
        {
            int buf = -1;

            if (filename[1] == 0)
            {
                buf = alloc_buffer(-1);
            }
            else
            if ((filename[1] >= '0') && (filename[1] <= '3') && (filename[2] == 0))
            {
                buf = alloc_buffer(filename[1] - '0');
            }

            if (buf == -1)
            {
                set_error(ErrorCode1541.ERR_NOCHANNEL);
                return((byte)C64StatusCode.ST_OK);
            }

            unsafe
            {
                // The buffers are in the 1541 RAM at $300 and are 256 bytes each
                chan_buf[channel]     = buf_ptr[channel] = (byte *)ram + 0x300 + (buf << 8);
                chan_mode[channel]    = ChannelMode.CHMOD_DIRECT;
                chan_buf_num[channel] = buf;

                // Store actual buffer number in buffer
                *chan_buf[channel] = (byte)(buf + '0');
                buf_len[channel] = 1;
            }

            return((byte)C64StatusCode.ST_OK);
        }
예제 #6
0
        public override byte Open(int channel, byte[] aFilename)
        {
            using (BytePtr filename = new BytePtr(aFilename))
            {
                set_error(ErrorCode1541.ERR_OK);

                // Channel 15: Execute file name as command
                if (channel == 15)
                {
                    execute_command(filename);
                    return (byte)C64StatusCode.ST_OK;
                }

                // Close previous file if still open
                if (file[channel] != null)
                {
                    file[channel].Dispose();
                    file[channel] = null;
                }

                if (filename[0] == '$')
                    unsafe
                    {
                        return open_directory(channel, filename.Pointer + 1);
                    }

                if (filename[0] == '#')
                {
                    set_error(ErrorCode1541.ERR_NOCHANNEL);
                    return (byte)C64StatusCode.ST_OK;
                }

                return open_file(channel, filename);
            }
        }
예제 #7
0
        unsafe void convert_filename(BytePtr srcname, BytePtr destname, ref FileAccessMode filemode, ref FileType filetype)
        {
            byte *p;

            // Search for ':', p points to first character after ':'
            if ((p = CharFunctions.strchr(srcname, ':')) != null)
            {
                p++;
            }
            else
            {
                p = srcname;
            }

            // Remaining string -> destname
            CharFunctions.strncpy(destname, srcname, p);

            // Look for mode parameters seperated by ','
            p = destname;
            while ((p = CharFunctions.strchr(p, ',')) != null)
            {
                // Cut string after the first ','
                *p++ = 0;
                switch ((Char)(*p))
                {
                case 'P':
                    filetype = FileType.FTYPE_PRG;
                    break;

                case 'S':
                    filetype = FileType.FTYPE_SEQ;
                    break;

                case 'U':
                    filetype = FileType.FTYPE_USR;
                    break;

                case 'L':
                    filetype = FileType.FTYPE_REL;
                    break;

                case 'R':
                    filemode = FileAccessMode.FMODE_READ;
                    break;

                case 'W':
                    filemode = FileAccessMode.FMODE_WRITE;
                    break;

                case 'A':
                    filemode = FileAccessMode.FMODE_APPEND;
                    break;
                }
            }
        }
예제 #8
0
        public static void strncpy(BytePtr dest, string src)
        {
            int i = 0;

            for (; i < dest.Length && i < src.Length; i++)
            {
                dest[i] = (byte)src[i];
            }

            dest[i] = 0x00;
        }
예제 #9
0
        public static void strncpy(BytePtr dest, BytePtr src, long start)
        {
            long i = start, j = 0;

            for (; i < dest.Length && src[i] != 0x00; i++, j++)
            {
                dest[j] = src[i];
            }

            dest[j] = 0x00;
        }
예제 #10
0
        unsafe public static byte *strchr(BytePtr src, byte c)
        {
            for (int i = 0; i < src.Length; i++)
            {
                if (src[i] == c)
                {
                    return(src.Pointer + i);
                }
            }

            return(null);
        }
예제 #11
0
        unsafe byte open_file(int channel, BytePtr filename)
        {
            using (BytePtr plainname = new BytePtr(256))
            {
                FileAccessMode filemode = FileAccessMode.FMODE_READ;
                FileType       filetype = FileType.FTYPE_PRG;
                int            track = -1, sector = -1;

                convert_filename(filename, plainname, ref filemode, ref filetype);

                // Channel 0 is READ PRG, channel 1 is WRITE PRG
                if (channel == 0)
                {
                    filemode = FileAccessMode.FMODE_READ;
                    filetype = FileType.FTYPE_PRG;
                }
                if (channel == 1)
                {
                    filemode = FileAccessMode.FMODE_WRITE;
                    filetype = FileType.FTYPE_PRG;
                }

                // Allow only read accesses
                if (filemode != FileAccessMode.FMODE_READ)
                {
                    set_error(ErrorCode1541.ERR_WRITEPROTECT);
                    return((byte)C64StatusCode.ST_OK);
                }

                // Find file in directory and open it
                if (find_file(plainname, ref track, ref sector))
                {
                    return(open_file_ts(channel, track, sector));
                }
                else
                {
                    set_error(ErrorCode1541.ERR_FILENOTFOUND);
                }

                return((byte)C64StatusCode.ST_OK);
            }
        }
예제 #12
0
        public override byte Open(int channel, byte[] afilename)
        {
            using (BytePtr filename = new BytePtr(afilename))
            {
                set_error(ErrorCode1541.ERR_OK);

                // Channel 15: execute file name as command
                if (channel == 15)
                {
                    execute_command(filename);
                    return((byte)C64StatusCode.ST_OK);
                }

                if (chan_mode[channel] != ChannelMode.CHMOD_FREE)
                {
                    set_error(ErrorCode1541.ERR_NOCHANNEL);
                    return((byte)C64StatusCode.ST_OK);
                }

                if (filename[0] == '$')
                {
                    if (channel != 0)
                    {
                        return(open_file_ts(channel, 18, 0));
                    }
                    else
                    {
                        unsafe
                        {
                            return(open_directory(filename.Pointer + 1));
                        }
                    }
                }

                if (filename[0] == '#')
                {
                    return(open_direct(channel, filename));
                }

                return(open_file(channel, filename));
            }
        }
예제 #13
0
파일: FSDrive.cs 프로젝트: rudzen/sharp-c64
        void execute_command(BytePtr command)
        {
            switch ((char)command[0])
            {
            case 'I':
                close_all_channels();
                set_error(ErrorCode1541.ERR_OK);
                break;

            case 'U':
                if ((command[1] & 0x0f) == 0x0a)
                {
                    Reset();
                }
                else
                {
                    set_error(ErrorCode1541.ERR_SYNTAX30);
                }
                break;

            case 'G':
                if ((char)command[1] != ':')
                {
                    set_error(ErrorCode1541.ERR_SYNTAX30);
                }
                else
                {
                    unsafe
                    {
                        string dir = new string((sbyte *)(command.Pointer + 2));
                        chdir_cmd(dir);
                    }
                }
                break;

            default:
                set_error(ErrorCode1541.ERR_SYNTAX30);
                break;
            }
        }
예제 #14
0
파일: FSDrive.cs 프로젝트: rudzen/sharp-c64
        public override byte Open(int channel, byte[] aFilename)
        {
            using (BytePtr filename = new BytePtr(aFilename))
            {
                set_error(ErrorCode1541.ERR_OK);

                // Channel 15: Execute file name as command
                if (channel == 15)
                {
                    execute_command(filename);
                    return((byte)C64StatusCode.ST_OK);
                }

                // Close previous file if still open
                if (file[channel] != null)
                {
                    file[channel].Dispose();
                    file[channel] = null;
                }

                if (filename[0] == '$')
                {
                    unsafe
                    {
                        return(open_directory(channel, filename.Pointer + 1));
                    }
                }

                if (filename[0] == '#')
                {
                    set_error(ErrorCode1541.ERR_NOCHANNEL);
                    return((byte)C64StatusCode.ST_OK);
                }

                return(open_file(channel, filename));
            }
        }
예제 #15
0
        unsafe void chd64_cmd(byte* d64name)
        {
            using (BytePtr str = new BytePtr(IEC.NAMEBUF_LENGTH))
            {
                byte* p = str;

                // Convert .d64 file name
                for (int i = 0; i < IEC.NAMEBUF_LENGTH && (*p++ = conv_from_64(*d64name++, false)) != 0; i++) ;

                close_all_channels();

                // G:. resets the .d64 file name to its original setting
                if (str[0] == '.' && str[1] == 0)
                    open_close_d64_file(orig_d64_name);
                else
                    open_close_d64_file(str.ToString());

                // Read BAM
                read_sector(18, 0, (byte*)bam);
            }
        }
예제 #16
0
        unsafe void convert_filename(BytePtr srcname, BytePtr destname, ref FileAccessMode filemode, ref FileType filetype)
        {
            byte* p;

            // Search for ':', p points to first character after ':'
            if ((p = CharFunctions.strchr(srcname, ':')) != null)
                p++;
            else
                p = srcname;

            // Remaining string -> destname
            CharFunctions.strncpy(destname, srcname, p);

            // Look for mode parameters seperated by ','
            p = destname;
            while ((p = CharFunctions.strchr(p, ',')) != null)
            {

                // Cut string after the first ','
                *p++ = 0;
                switch ((Char)(*p))
                {
                    case 'P':
                        filetype = FileType.FTYPE_PRG;
                        break;
                    case 'S':
                        filetype = FileType.FTYPE_SEQ;
                        break;
                    case 'U':
                        filetype = FileType.FTYPE_USR;
                        break;
                    case 'L':
                        filetype = FileType.FTYPE_REL;
                        break;
                    case 'R':
                        filemode = FileAccessMode.FMODE_READ;
                        break;
                    case 'W':
                        filemode = FileAccessMode.FMODE_WRITE;
                        break;
                    case 'A':
                        filemode = FileAccessMode.FMODE_APPEND;
                        break;
                }
            }
        }
예제 #17
0
        public override byte Open(int channel, byte[] afilename)
        {
            using (BytePtr filename = new BytePtr(afilename))
            {
                set_error(ErrorCode1541.ERR_OK);

                // Channel 15: execute file name as command
                if (channel == 15)
                {
                    execute_command(filename);
                    return (byte)C64StatusCode.ST_OK;
                }

                if (chan_mode[channel] != ChannelMode.CHMOD_FREE)
                {
                    set_error(ErrorCode1541.ERR_NOCHANNEL);
                    return (byte)C64StatusCode.ST_OK;
                }

                if (filename[0] == '$')
                    if (channel != 0)
                        return open_file_ts(channel, 18, 0);
                    else
                    {
                        unsafe
                        {
                            return open_directory(filename.Pointer + 1);
                        }
                    }

                if (filename[0] == '#')
                    return open_direct(channel, filename);

                return open_file(channel, filename);
            }
        }
예제 #18
0
 private unsafe void AllocateChannelBuffer(int channel, int size)
 {
     chan_buf_alloc[channel] = new BytePtr(size);
     chan_buf[channel] = chan_buf_alloc[channel];
 }
예제 #19
0
파일: FSDrive.cs 프로젝트: rudzen/sharp-c64
        byte open_file(int channel, BytePtr filename)
        {
            using (BytePtr plainname = new BytePtr(256))
            {
                FileAccessMode filemode = FileAccessMode.FMODE_READ;
                FileType       filetype = FileType.FTYPE_PRG;
                bool           wildflag = false;
                FileMode       fmode    = FileMode.Open;
                FileAccess     faccess  = FileAccess.Read;

                unsafe
                {
                    convert_filename(filename, plainname, ref filemode, ref filetype, ref wildflag);
                }

                // Channel 0 is READ PRG, channel 1 is WRITE PRG
                if (channel == 0)
                {
                    filemode = FileAccessMode.FMODE_READ;
                    filetype = FileType.FTYPE_PRG;
                }
                else if (channel == 1)
                {
                    filemode = FileAccessMode.FMODE_WRITE;
                    filetype = FileType.FTYPE_PRG;
                }

                // Wildcards are only allowed on reading
                if (wildflag)
                {
                    if (filemode != FileAccessMode.FMODE_READ)
                    {
                        set_error(ErrorCode1541.ERR_SYNTAX33);
                        return((byte)C64StatusCode.ST_OK);
                    }

                    find_first_file(plainname);
                }

                // Select fopen() mode according to file mode
                switch (filemode)
                {
                case FileAccessMode.FMODE_READ:
                    fmode   = FileMode.Open;
                    faccess = FileAccess.Read;
                    break;

                case FileAccessMode.FMODE_WRITE:
                    fmode   = FileMode.OpenOrCreate;
                    faccess = FileAccess.ReadWrite;
                    break;

                case FileAccessMode.FMODE_APPEND:
                    fmode   = FileMode.Append;
                    faccess = FileAccess.ReadWrite;
                    break;
                }

                try
                {
                    string fullpath = Path.Combine(dir_path, plainname.ToString());

                    file[channel] = new FileStream(fullpath, fmode, faccess);

                    if (filemode == FileAccessMode.FMODE_READ)  // Read and buffer first byte
                    {
                        read_char[channel] = (byte)file[channel].ReadByte();
                    }
                    else
                    {
                        Environment.CurrentDirectory = Assembly.GetExecutingAssembly().Location;
                    }
                }
                catch (DirectoryNotFoundException)
                {
                    set_error(ErrorCode1541.ERR_NOTREADY);
                }
                catch (FileNotFoundException)
                {
                    set_error(ErrorCode1541.ERR_FILENOTFOUND);
                }
            }

            return((byte)C64StatusCode.ST_OK);
        }
예제 #20
0
        Stream the_file; // File pointer for .d64 file

        #endregion Fields

        #region Constructors

        public D64Drive(IEC iec, string filepath)
            : base(iec)
        {
            the_file = null;
            ram = null;

            Ready = false;
            orig_d64_name = filepath;

            for (int i = 0; i < chan_mode.Length - 1; i++)
            {
                chan_mode[i] = ChannelMode.CHMOD_FREE;
            }
            chan_mode[15] = ChannelMode.CHMOD_COMMAND;

            // Open .d64 file
            open_close_d64_file(filepath);
            if (the_file != null)
            {

                // Allocate 1541 RAM
                ram = new BytePtr(0x800);
                unsafe
                {
                    bam = (BAM*)(ram.Pointer + 0x700);
                }
                Reset();
                Ready = true;
            }
        }
예제 #21
0
 unsafe private void AllocateChannelBuffer(int channel, int size)
 {
     chan_buf_alloc[channel] = new BytePtr(size);
     chan_buf[channel]       = chan_buf_alloc[channel];
 }
예제 #22
0
        byte open_direct(int channel, BytePtr filename)
        {
            int buf = -1;

            if (filename[1] == 0)
                buf = alloc_buffer(-1);
            else
                if ((filename[1] >= '0') && (filename[1] <= '3') && (filename[2] == 0))
                    buf = alloc_buffer(filename[1] - '0');

            if (buf == -1)
            {
                set_error(ErrorCode1541.ERR_NOCHANNEL);
                return (byte)C64StatusCode.ST_OK;
            }

            unsafe
            {
                // The buffers are in the 1541 RAM at $300 and are 256 bytes each
                chan_buf[channel] = buf_ptr[channel] = (byte*)ram + 0x300 + (buf << 8);
                chan_mode[channel] = ChannelMode.CHMOD_DIRECT;
                chan_buf_num[channel] = buf;

                // Store actual buffer number in buffer
                *chan_buf[channel] = (byte)(buf + '0');
                buf_len[channel] = 1;
            }

            return (byte)C64StatusCode.ST_OK;
        }
예제 #23
0
        public static void strncpy(BytePtr dest, string src)
        {
            int i = 0;
            for (; i < dest.Length && i < src.Length; i++)
                dest[i] = (byte)src[i];

            dest[i] = 0x00;
        }
예제 #24
0
파일: FSDrive.cs 프로젝트: rudzen/sharp-c64
        unsafe byte open_directory(int channel, byte *filename)
        {
            using (BytePtr buf = new BytePtr(Encoding.ASCII.GetBytes("\u0001\u0004\u0001\u0001\u0000\u0000\u0012\u0022                \u0022 00 2A\0")),
                   pattern = new BytePtr(IEC.NAMEBUF_LENGTH))
            {
                //char str[NAMEBUF_LENGTH];
                byte *         p, q;
                int            i;
                FileAccessMode filemode = FileAccessMode.FMODE_READ;
                FileType       filetype = FileType.FTYPE_PRG;
                bool           wildflag = false;
                string         str;

                // Special treatment for "$0"
                if (filename[0] == '0' && filename[1] == 0)
                {
                    filename += 1;
                }

                // Convert filename ('$' already stripped), filemode/type are ignored
                convert_filename(filename, pattern, ref filemode, ref filetype, ref wildflag);

                DirectoryInfo dir = new DirectoryInfo(dir_path);
                if (!dir.Exists)
                {
                    set_error(ErrorCode1541.ERR_NOTREADY);
                    return((byte)C64StatusCode.ST_OK);
                }

                FileSystemInfo[] files = dir.GetFileSystemInfos();

                file[channel] = new FileStream(Path.GetTempFileName(), FileMode.OpenOrCreate, FileAccess.ReadWrite);

                p = (byte *)buf.Pointer + 8;

                for (i = 0; i < 16 & i < dir_title.Length; i++)
                {
                    *p++ = conv_to_64((byte)dir_title[i], false);
                }

                file[channel].Write(buf, 0, 32);

                IEnumerator fenum = files.GetEnumerator();
                while (fenum.MoveNext() && (((FileSystemInfo)fenum.Current).Name == "." || ((FileSystemInfo)fenum.Current).Name == ".."))
                {
                    ;
                }

                do
                {
                    FileSystemInfo fsi = (FileSystemInfo)fenum.Current;

                    if (match(pattern.ToString(), fsi.Name))
                    {
                        // Clear line with spaces and terminate with null byte
                        for (i = 0; i < buf.Length; i++)
                        {
                            buf[i] = (byte)' ';
                        }

                        buf[31] = 0;

                        p = buf;
                        *p++ = 0x01;    // Dummy line link
                        *p++ = 0x01;

                        if (fsi is FileInfo)
                        {
                            FileInfo fi = (FileInfo)fsi;

                            // Calculate size in blocks (254 bytes each)
                            i = (int)((fi.Length + 254) / 254);
                            *p++ = (byte)(i & 0xff);
                            *p++ = (byte)((i >> 8) & 0xff);

                            p++;
                            if (i < 10)
                            {
                                p++;            // Less than 10: add one space
                            }
                            if (i < 100)
                            {
                                p++;            // Less than 100: add another space
                            }
                            str = fi.Name;
                            // Convert and insert file name
                            *p++ = (byte)'\"';
                            q = p;
                            for (i = 0; i < 16 && i < str.Length; i++)
                            {
                                *q++ = conv_to_64((byte)str[i], true);
                            }
                            *q++ = (byte)'\"';
                            p   += 18;
                        }
                        // File type
                        if (fsi is DirectoryInfo)
                        {
                            *p++ = (byte)'D';
                            *p++ = (byte)'I';
                            *p++ = (byte)'R';
                        }
                        else
                        {
                            *p++ = (byte)'P';
                            *p++ = (byte)'R';
                            *p++ = (byte)'G';
                        }

                        // Write line
                        file[channel].Write(buf, 0, 32);
                    }
                } while (fenum.MoveNext());
            }

            // Final line

            file[channel].Write(Encoding.ASCII.GetBytes("\u0001\u0001\0\0BLOCKS FREE.             \0\0\0"), 0, 32);

            file[channel].Position = 0;
            read_char[channel]     = (byte)file[channel].ReadByte();

            return((byte)C64StatusCode.ST_OK);
        }
예제 #25
0
        unsafe byte open_directory(int channel, byte* filename)
        {
            using (BytePtr buf = new BytePtr(Encoding.ASCII.GetBytes("\u0001\u0004\u0001\u0001\u0000\u0000\u0012\u0022                \u0022 00 2A\0")),
                pattern = new BytePtr(IEC.NAMEBUF_LENGTH))
            {
                //char str[NAMEBUF_LENGTH];
                byte* p, q;
                int i;
                FileAccessMode filemode = FileAccessMode.FMODE_READ;
                FileType filetype = FileType.FTYPE_PRG;
                bool wildflag = false;
                string str;

                // Special treatment for "$0"
                if (filename[0] == '0' && filename[1] == 0)
                    filename += 1;

                // Convert filename ('$' already stripped), filemode/type are ignored
                convert_filename(filename, pattern, ref filemode, ref filetype, ref wildflag);

                DirectoryInfo dir = new DirectoryInfo(dir_path);
                if (!dir.Exists)
                {
                    set_error(ErrorCode1541.ERR_NOTREADY);
                    return (byte)C64StatusCode.ST_OK;
                }

                FileSystemInfo[] files = dir.GetFileSystemInfos();

                file[channel] = new FileStream(Path.GetTempFileName(), FileMode.OpenOrCreate, FileAccess.ReadWrite);

                p = (byte*)buf.Pointer + 8;

                for (i = 0; i < 16 & i < dir_title.Length; i++)
                {
                    *p++ = conv_to_64((byte)dir_title[i], false);
                }

                file[channel].Write(buf, 0, 32);

                IEnumerator fenum = files.GetEnumerator();
                while (fenum.MoveNext() && (((FileSystemInfo)fenum.Current).Name == "." || ((FileSystemInfo)fenum.Current).Name == "..")) ;

                do
                {
                    FileSystemInfo fsi = (FileSystemInfo)fenum.Current;

                    if (match(pattern.ToString(), fsi.Name))
                    {
                        // Clear line with spaces and terminate with null byte
                        for (i = 0; i < buf.Length; i++)
                            buf[i] = (byte)' ';

                        buf[31] = 0;

                        p = buf;
                        *p++ = 0x01;	// Dummy line link
                        *p++ = 0x01;

                        if (fsi is FileInfo)
                        {
                            FileInfo fi = (FileInfo)fsi;

                            // Calculate size in blocks (254 bytes each)
                            i = (int)((fi.Length + 254) / 254);
                            *p++ = (byte)(i & 0xff);
                            *p++ = (byte)((i >> 8) & 0xff);

                            p++;
                            if (i < 10) p++;	// Less than 10: add one space
                            if (i < 100) p++;	// Less than 100: add another space

                            str = fi.Name;
                            // Convert and insert file name
                            *p++ = (byte)'\"';
                            q = p;
                            for (i = 0; i < 16 && i < str.Length; i++)
                                *q++ = conv_to_64((byte)str[i], true);
                            *q++ = (byte)'\"';
                            p += 18;
                        }
                        // File type
                        if (fsi is DirectoryInfo)
                        {
                            *p++ = (byte)'D';
                            *p++ = (byte)'I';
                            *p++ = (byte)'R';
                        }
                        else
                        {
                            *p++ = (byte)'P';
                            *p++ = (byte)'R';
                            *p++ = (byte)'G';
                        }

                        // Write line
                        file[channel].Write(buf, 0, 32);
                    }

                } while (fenum.MoveNext());
            }

            // Final line

            file[channel].Write(Encoding.ASCII.GetBytes("\u0001\u0001\0\0BLOCKS FREE.             \0\0\0"), 0, 32);

            file[channel].Position = 0;
            read_char[channel] = (byte)file[channel].ReadByte();

            return (byte)C64StatusCode.ST_OK;
        }
예제 #26
0
        void execute_command(BytePtr command)
        {
            switch ((char)command[0])
            {
                case 'I':
                    close_all_channels();
                    set_error(ErrorCode1541.ERR_OK);
                    break;

                case 'U':
                    if ((command[1] & 0x0f) == 0x0a)
                    {
                        Reset();
                    }
                    else
                        set_error(ErrorCode1541.ERR_SYNTAX30);
                    break;

                case 'G':
                    if ((char)command[1] != ':')
                        set_error(ErrorCode1541.ERR_SYNTAX30);
                    else
                    {
                        unsafe
                        {
                            string dir = new string((sbyte*)(command.Pointer + 2));
                            chdir_cmd(dir);
                        }
                    }
                    break;

                default:
                    set_error(ErrorCode1541.ERR_SYNTAX30);
                    break;
            }
        }
예제 #27
0
 unsafe public static byte *strchr(BytePtr src, Char c)
 {
     return(strchr(src, (byte)c));
 }
예제 #28
0
        unsafe void execute_command(BytePtr command)
        {
            UInt16 adr;
            int len;

            switch ((char)command[0])
            {
                case 'B':
                    if (command[1] != '-')
                        set_error(ErrorCode1541.ERR_SYNTAX30);
                    else
                        switch ((char)command[2])
                        {
                            case 'R':
                                block_read_cmd(command.Pointer + 3);
                                break;

                            case 'P':
                                buffer_ptr_cmd(command.Pointer + 3);
                                break;

                            case 'A':
                            case 'F':
                            case 'W':
                                set_error(ErrorCode1541.ERR_WRITEPROTECT);
                                break;

                            default:
                                set_error(ErrorCode1541.ERR_SYNTAX30);
                                break;
                        }
                    break;

                case 'M':
                    if (command[1] != '-')
                        set_error(ErrorCode1541.ERR_SYNTAX30);
                    else
                        switch ((char)command[2])
                        {
                            case 'R':
                                adr = (UInt16)(((byte)command[4] << 8) | ((byte)command[3]));
                                error_ptr = (byte*)((byte*)ram + (adr & 0x07ff));
                                if ((error_len = (byte)command[5]) == 0)
                                    error_len = 1;
                                break;

                            case 'W':
                                adr = (UInt16)(((byte)command[4] << 8) | ((byte)command[3]));
                                len = (byte)command[5];
                                for (int i = 0; i < len; i++)
                                    ram[adr + i] = (byte)command[i + 6];
                                break;

                            default:
                                set_error(ErrorCode1541.ERR_SYNTAX30);
                                break;
                        }
                    break;

                case 'I':
                    close_all_channels();
                    read_sector(18, 0, (byte*)bam);
                    set_error(ErrorCode1541.ERR_OK);
                    break;

                case 'U':
                    switch (command[1] & 0x0f)
                    {
                        case 1:		// U1/UA: Block-Read
                            block_read_cmd(command.Pointer + 2);
                            break;

                        case 2:		// U2/UB: Block-Write
                            set_error(ErrorCode1541.ERR_WRITEPROTECT);
                            break;

                        case 10:	// U:/UJ: Reset
                            Reset();
                            break;

                        default:
                            set_error(ErrorCode1541.ERR_SYNTAX30);
                            break;
                    }
                    break;

                case 'G':
                    if (command[1] != ':')
                        set_error(ErrorCode1541.ERR_SYNTAX30);
                    else
                        chd64_cmd(command.Pointer + 2);
                    break;

                case 'C':
                case 'N':
                case 'R':
                case 'S':
                case 'V':
                    set_error(ErrorCode1541.ERR_WRITEPROTECT);
                    break;

                default:
                    set_error(ErrorCode1541.ERR_SYNTAX30);
                    break;
            }
        }
예제 #29
0
 public static unsafe void strncpy(BytePtr dest, BytePtr src, byte* start)
 {
     strncpy(dest, src, start - src.Pointer);
 }
예제 #30
0
        unsafe bool find_file(BytePtr filename, ref int track, ref int sector)
        {
            int i, j;
            byte* p, q;
            DirEntry* de;

            fixed (Directory* dd = &dir)
            {
                // Scan all directory blocks
                dir.next_track = bam->dir_track;
                dir.next_sector = bam->dir_sector;

                while (dir.next_track != 0)
                {
                    if (!read_sector(dir.next_track, dir.next_sector, &dd->next_track))
                        return false;

                    DirEntry* ade = (DirEntry*)dd->entry;
                    // Scan all 8 entries of a block
                    for (j = 0; j < 8; j++)
                    {
                        de = &ade[j];
                        track = de->track;
                        sector = de->sector;

                        if (de->type != 0)
                        {
                            p = (byte*)filename;
                            q = de->name;
                            for (i = 0; i < 16 && (*p != 0); i++, p++, q++)
                            {
                                if (*p == '*')	// Wildcard '*' matches all following characters
                                    return true;
                                if (*p != *q)
                                {
                                    if (*p != '?') goto next_entry;	// Wildcard '?' matches single character
                                    if (*q == 0xa0) goto next_entry;
                                }
                            }

                            if (i == 16 || *q == 0xa0)
                                return true;
                        }
                    next_entry: ;
                    }
                }
            }
            return false;
        }
예제 #31
0
        unsafe void execute_command(BytePtr command)
        {
            UInt16 adr;
            int    len;

            switch ((char)command[0])
            {
            case 'B':
                if (command[1] != '-')
                {
                    set_error(ErrorCode1541.ERR_SYNTAX30);
                }
                else
                {
                    switch ((char)command[2])
                    {
                    case 'R':
                        block_read_cmd(command.Pointer + 3);
                        break;

                    case 'P':
                        buffer_ptr_cmd(command.Pointer + 3);
                        break;

                    case 'A':
                    case 'F':
                    case 'W':
                        set_error(ErrorCode1541.ERR_WRITEPROTECT);
                        break;

                    default:
                        set_error(ErrorCode1541.ERR_SYNTAX30);
                        break;
                    }
                }
                break;

            case 'M':
                if (command[1] != '-')
                {
                    set_error(ErrorCode1541.ERR_SYNTAX30);
                }
                else
                {
                    switch ((char)command[2])
                    {
                    case 'R':
                        adr       = (UInt16)(((byte)command[4] << 8) | ((byte)command[3]));
                        error_ptr = (byte *)((byte *)ram + (adr & 0x07ff));
                        if ((error_len = (byte)command[5]) == 0)
                        {
                            error_len = 1;
                        }
                        break;

                    case 'W':
                        adr = (UInt16)(((byte)command[4] << 8) | ((byte)command[3]));
                        len = (byte)command[5];
                        for (int i = 0; i < len; i++)
                        {
                            ram[adr + i] = (byte)command[i + 6];
                        }
                        break;

                    default:
                        set_error(ErrorCode1541.ERR_SYNTAX30);
                        break;
                    }
                }
                break;

            case 'I':
                close_all_channels();
                read_sector(18, 0, (byte *)bam);
                set_error(ErrorCode1541.ERR_OK);
                break;

            case 'U':
                switch (command[1] & 0x0f)
                {
                case 1:                 // U1/UA: Block-Read
                    block_read_cmd(command.Pointer + 2);
                    break;

                case 2:                 // U2/UB: Block-Write
                    set_error(ErrorCode1541.ERR_WRITEPROTECT);
                    break;

                case 10:                // U:/UJ: Reset
                    Reset();
                    break;

                default:
                    set_error(ErrorCode1541.ERR_SYNTAX30);
                    break;
                }
                break;

            case 'G':
                if (command[1] != ':')
                {
                    set_error(ErrorCode1541.ERR_SYNTAX30);
                }
                else
                {
                    chd64_cmd(command.Pointer + 2);
                }
                break;

            case 'C':
            case 'N':
            case 'R':
            case 'S':
            case 'V':
                set_error(ErrorCode1541.ERR_WRITEPROTECT);
                break;

            default:
                set_error(ErrorCode1541.ERR_SYNTAX30);
                break;
            }
        }
예제 #32
0
        unsafe byte open_file(int channel, BytePtr filename)
        {
            using (BytePtr plainname = new BytePtr(256))
            {

                FileAccessMode filemode = FileAccessMode.FMODE_READ;
                FileType filetype = FileType.FTYPE_PRG;
                int track = -1, sector = -1;

                convert_filename(filename, plainname, ref filemode, ref filetype);

                // Channel 0 is READ PRG, channel 1 is WRITE PRG
                if (channel == 0)
                {
                    filemode = FileAccessMode.FMODE_READ;
                    filetype = FileType.FTYPE_PRG;
                }
                if (channel == 1)
                {
                    filemode = FileAccessMode.FMODE_WRITE;
                    filetype = FileType.FTYPE_PRG;
                }

                // Allow only read accesses
                if (filemode != FileAccessMode.FMODE_READ)
                {
                    set_error(ErrorCode1541.ERR_WRITEPROTECT);
                    return (byte)C64StatusCode.ST_OK;
                }

                // Find file in directory and open it
                if (find_file(plainname, ref track, ref sector))
                    return open_file_ts(channel, track, sector);
                else
                    set_error(ErrorCode1541.ERR_FILENOTFOUND);

                return (byte)C64StatusCode.ST_OK;
            }
        }
예제 #33
0
 unsafe public static void strncpy(BytePtr dest, BytePtr src, byte *start)
 {
     strncpy(dest, src, start - src.Pointer);
 }
예제 #34
0
        void find_first_file(BytePtr aName)
        {
            DirectoryInfo dir = new DirectoryInfo(dir_path);

            if (!dir.Exists)
                return;

            FileInfo[] files = dir.GetFiles();

            string name = aName.ToString();

            IEnumerator fenum = files.GetEnumerator();
            while (fenum.MoveNext() && (((FileInfo)fenum.Current).Name == "." || ((FileInfo)fenum.Current).Name == "..")) ;

            do
            {
                FileInfo fi = (FileInfo)fenum.Current;

                // Match found? Then copy real file name
                if (match(name, fi.Name))
                {
                    CharFunctions.strncpy(aName, fi.Name);
                    return;
                }

            } while (fenum.MoveNext());
        }
예제 #35
0
 public static unsafe byte* strchr(BytePtr src, Char c)
 {
     return strchr(src, (byte)c);
 }
예제 #36
0
        byte open_file(int channel, BytePtr filename)
        {
            using (BytePtr plainname = new BytePtr(256))
            {
                FileAccessMode filemode = FileAccessMode.FMODE_READ;
                FileType filetype = FileType.FTYPE_PRG;
                bool wildflag = false;
                FileMode fmode = FileMode.Open;
                FileAccess faccess = FileAccess.Read;

                unsafe
                {
                    convert_filename(filename, plainname, ref filemode, ref filetype, ref wildflag);
                }

                // Channel 0 is READ PRG, channel 1 is WRITE PRG
                if (channel == 0)
                {
                    filemode = FileAccessMode.FMODE_READ;
                    filetype = FileType.FTYPE_PRG;
                }
                else if (channel == 1)
                {
                    filemode = FileAccessMode.FMODE_WRITE;
                    filetype = FileType.FTYPE_PRG;
                }

                // Wildcards are only allowed on reading
                if (wildflag)
                {
                    if (filemode != FileAccessMode.FMODE_READ)
                    {
                        set_error(ErrorCode1541.ERR_SYNTAX33);
                        return (byte)C64StatusCode.ST_OK;
                    }

                    find_first_file(plainname);
                }

                // Select fopen() mode according to file mode
                switch (filemode)
                {
                    case FileAccessMode.FMODE_READ:
                        fmode = FileMode.Open;
                        faccess = FileAccess.Read;
                        break;
                    case FileAccessMode.FMODE_WRITE:
                        fmode = FileMode.OpenOrCreate;
                        faccess = FileAccess.ReadWrite;
                        break;
                    case FileAccessMode.FMODE_APPEND:
                        fmode = FileMode.Append;
                        faccess = FileAccess.ReadWrite;
                        break;
                }

                try
                {
                    string fullpath = Path.Combine(dir_path, plainname.ToString());

                    file[channel] = new FileStream(fullpath, fmode, faccess);

                    if (filemode == FileAccessMode.FMODE_READ)	// Read and buffer first byte
                        read_char[channel] = (byte)file[channel].ReadByte();
                    else
                        Environment.CurrentDirectory = Assembly.GetExecutingAssembly().Location;
                }
                catch (DirectoryNotFoundException)
                {
                    set_error(ErrorCode1541.ERR_NOTREADY);
                }
                catch (FileNotFoundException)
                {
                    set_error(ErrorCode1541.ERR_FILENOTFOUND);
                }
            }

            return (byte)C64StatusCode.ST_OK;
        }
예제 #37
0
        public static void strncpy(BytePtr dest, BytePtr src, long start)
        {
            long i = start, j = 0;
            for (; i < dest.Length && src[i] != 0x00; i++, j++)
                dest[j] = src[i];

            dest[j] = 0x00;
        }
예제 #38
0
        unsafe bool find_file(BytePtr filename, ref int track, ref int sector)
        {
            int       i, j;
            byte *    p, q;
            DirEntry *de;

            fixed(Directory *dd = &dir)
            {
                // Scan all directory blocks
                dir.next_track  = bam->dir_track;
                dir.next_sector = bam->dir_sector;

                while (dir.next_track != 0)
                {
                    if (!read_sector(dir.next_track, dir.next_sector, &dd->next_track))
                    {
                        return(false);
                    }

                    DirEntry *ade = (DirEntry *)dd->entry;
                    // Scan all 8 entries of a block
                    for (j = 0; j < 8; j++)
                    {
                        de     = &ade[j];
                        track  = de->track;
                        sector = de->sector;

                        if (de->type != 0)
                        {
                            p = (byte *)filename;
                            q = de->name;
                            for (i = 0; i < 16 && (*p != 0); i++, p++, q++)
                            {
                                if (*p == '*')  // Wildcard '*' matches all following characters
                                {
                                    return(true);
                                }
                                if (*p != *q)
                                {
                                    if (*p != '?')
                                    {
                                        goto next_entry;                // Wildcard '?' matches single character
                                    }
                                    if (*q == 0xa0)
                                    {
                                        goto next_entry;
                                    }
                                }
                            }

                            if (i == 16 || *q == 0xa0)
                            {
                                return(true);
                            }
                        }
                        next_entry :;
                    }
                }
            }

            return(false);
        }
예제 #39
0
        public static unsafe byte* strchr(BytePtr src, byte c)
        {
            for (int i = 0; i < src.Length; i++)
                if (src[i] == c)
                    return src.Pointer + i;

            return null;
        }