コード例 #1
0
        private void handleSiInt(SiInt intNr)
        {
            Program program = process.virtualMachine.program;

            switch (intNr)
            {
            case SiInt.Halt:
            {
                process.changeIC(7);
                break;
            }

            case SiInt.OpenFileHandle:
            {
                byte[] memoryBytes = program.memAccesser.getAllBytes();
                string fileName    = Util.AsciiBytesToString(memoryBytes, checked ((int)(program.registers.B + program.registers.DS)));

                kernelStorage.resources.add(new CreateHandleRequest(process.id, fileName));
                break;
            }

            case SiInt.WriteToHandle:
            {
                uint bytesToWriteAmount = program.registers.CX;
                if (bytesToWriteAmount == 0xFFFFFFFF)
                {
                    bytesToWriteAmount = 4;
                }

                byte[] bytesToWrite = program.memAccesser.readFromAddr(program.registers.DS + program.registers.A, bytesToWriteAmount);

                this.kernelStorage.resources.add(new WriteHandleRequest(process.id, (int)program.registers.B, bytesToWrite));
                break;
            }

            case SiInt.CloseFileHandle:
            {
                kernelStorage.resources.add(new HandleOperationRequest(process.id, HandleOperationType.Close, (int)program.registers.B, process.programName));
                break;
            }

            case SiInt.ReadFromHandle:
            {
                this.kernelStorage.resources.add(new ReadHandleRequest(process.id, (int)program.registers.B, (int)program.registers.CX, process.programName));
                break;
            }

            case SiInt.DeleteFile:
            {
                this.kernelStorage.resources.add(new HandleOperationRequest(process.id, HandleOperationType.Delete, (int)program.registers.B, process.programName));
                break;
            }

            case SiInt.MountBattery:
            {
                this.kernelStorage.resources.add(
                    new BaseHandleResource(ResType.BaseHandleResource, HandleOperationType.CreateBatteryHandle, process.id, -1)
                    );
                break;
            }

            case SiInt.SeekHandle:
            {
                this.kernelStorage.resources.add(
                    new SetHandleSeekRequest(process.id, (int)program.registers.B, (int)program.registers.CX)
                    );
                break;
            }

            case SiInt.PrintConsoleRegA:
            {
                string numbers = program.registers.A.ToString() + "\n";
                this.kernelStorage.resources.add(new WriteHandleRequest(process.id, 0, Encoding.ASCII.GetBytes(numbers)));
                break;
            }

            default:
                throw new NotImplementedException();
            }

            return;
        }
コード例 #2
0
ファイル: RealMachine.cs プロジェクト: mantas7776/UniVM
        public void handleSiInt(Program program, SiInt siNr)
        {
            switch (siNr)
            {
            case SiInt.Halt:
                program.setDone();
                break;

            case SiInt.OpenFileHandle:
            {
                byte[] memoryBytes = program.memAccesser.getAllBytes();
                string fileName    = Util.AsciiBytesToString(memoryBytes, checked ((int)(program.registers.B + program.registers.DS)));
                channelDevice.storage = 1;
                StorageFile file = StorageFile.OpenOrCreate(storage, fileName);
                FileHandle  fh   = new FileHandle(file);

                int hndl = handles.add(fh);
                channelDevice.storage = 0;
                program.registers.B   = checked ((uint)hndl);
                program.registers.SI  = SiInt.None;
                break;
            }

            case SiInt.ReadFromHandle:
            {
                int    bytesToReadAmount = checked ((int)program.registers.CX);
                Handle handle            = handles[checked ((int)program.registers.B)];
                //handle battery, special case
                if (handle is Battery)
                {
                    byte[] batStatus = ((Battery)handle).getStatus();
                    program.memAccesser.writeFromAddr(program.registers.DS + program.registers.A, batStatus);
                }
                else
                {
                    //else handle other
                    FileHandle hndl = (FileHandle)handles[checked ((int)program.registers.B)];

                    channelDevice.storage = 1;
                    byte[] readBytes = new byte[program.registers.CX];

                    uint amountRead = 0;
                    try
                    {
                        for (uint i = 0; i < program.registers.CX; i++)
                        {
                            amountRead++;
                            readBytes[i] = hndl.read();
                        }
                        program.memAccesser.writeFromAddr(program.registers.DS + program.registers.A, readBytes);
                        program.registers.A = 0;
                    }
                    catch (Exception e)
                    {
                        if (!e.Message.Contains("Reading file out of bounds"))
                        {
                            throw e;
                        }
                        program.memAccesser.writeFromAddr(program.registers.DS + program.registers.A, readBytes);
                        program.registers.A = 1;
                        break;
                    }
                    program.registers.CX  = amountRead;
                    channelDevice.storage = 0;
                }


                program.registers.SI = SiInt.None;
                break;
            }

            case SiInt.ReadConsole:
            {
                this.channelDevice.console = 1;
                ConsoleDevice hndl      = (ConsoleDevice)handles[checked ((int)program.registers.B)];
                byte[]        readBytes = hndl.readLine();
                if (readBytes.Length > program.registers.CX)
                {
                    program.memAccesser.writeFromAddr(program.registers.DS + program.registers.A, readBytes, program.registers.CX);
                    program.registers.A = 1;
                }
                else
                {
                    uint len = checked ((uint)readBytes.Length);
                    program.memAccesser.writeFromAddr(program.registers.DS + program.registers.A, readBytes, len);
                    program.registers.CX = len;
                    program.registers.A  = 0;
                }

                this.channelDevice.console = 0;
                program.registers.A        = 0;
                program.registers.SI       = SiInt.None;
                break;
            }

            case SiInt.PrintConsole:
            case SiInt.WriteToHandle:
            {
                uint   bytesToWriteAmount = program.registers.CX;
                Handle hndl = handles[checked ((int)program.registers.B)];
                //handle battery, special case
                if (hndl is Battery)
                {
                    int status = BitConverter.ToInt32(
                        program.memAccesser.readFromAddr(
                            program.registers.DS + program.registers.A, 4)
                        , 0);
                    ((Battery)hndl).setStatus((byte)status);
                    program.registers.SI = SiInt.None;
                    return;
                }
                //handle others else

                channelDevice.storage = 1;
                byte[] bytesToWrite = program.memAccesser.readFromAddr(program.registers.DS + program.registers.A, bytesToWriteAmount);

                uint amountWritten = 0;
                try
                {
                    for (uint i = 0; i < bytesToWriteAmount; i++)
                    {
                        amountWritten++;
                        hndl.write(bytesToWrite[i]);
                    }

                    program.registers.A = 0;
                }
                catch (Exception e)
                {
                    if (!e.Message.Contains("Writing file out of bounds."))
                    {
                        throw e;
                    }
                    program.registers.A = 1;
                    break;
                }


                channelDevice.storage = 0;
                program.registers.CX  = amountWritten;
                program.registers.SI  = SiInt.None;
                break;
            }

            case SiInt.CloseFileHandle:
            {
                if (program.registers.B == 0)
                {
                    throw new Exception("Default handle closing is not allowed!");
                }
                Handle handle = handles[checked ((int)program.registers.B)];
                if (handle is Battery)
                {
                    this.channelDevice.battery = 0;
                }
                this.handles.remove(handle);
                program.registers.SI = SiInt.None;
                break;
            }

            case SiInt.DeleteFile:
            {
                channelDevice.storage = 1;
                Handle handle = handles[checked ((int)program.registers.B)];
                if (handle.GetType() != typeof(FileHandle))
                {
                    throw new Exception("Only file handles can be deleted");
                }
                FileHandle file     = (FileHandle)handle;
                string     fileName = file.fileName;
                this.handles.remove(handle);

                StorageFile.DeleteFile(storage, fileName);
                channelDevice.storage = 0;
                program.registers.SI  = SiInt.None;
                break;
            }

            case SiInt.MountBattery:
            {
                //wait till free
                if (channelDevice.battery == 1)
                {
                    break;
                }
                channelDevice.battery = 1;
                int hndl = handles.add(new Battery());
                program.registers.B  = checked ((uint)hndl);
                program.registers.SI = SiInt.None;
                break;
            }

            case SiInt.SeekHandle:
            {
                channelDevice.storage = 1;
                Handle handle = handles[checked ((int)program.registers.B)];
                if (handle.GetType() != typeof(FileHandle))
                {
                    throw new Exception("Only file handles can seek");
                }
                FileHandle file = (FileHandle)handle;
                file.Seek             = checked ((int)program.registers.CX);
                channelDevice.storage = 0;
                break;
            }

            case SiInt.PrintConsoleRegA:
                channelDevice.console = 1;
                Console.WriteLine(program.registers.A);
                channelDevice.console = 0;
                break;

            default:
                throw new NotImplementedException();
            }

            return;
        }