private void readHandleFile(FileHandle hndl, ReadHandleRequest request) { this.kernelStorage.channelDevice.storage = 1; byte[] readBytes = new byte[request.amount]; Resource response; uint amountRead = 0; try { for (uint i = 0; i < request.amount; i++) { amountRead++; readBytes[i] = hndl.read(); } response = new ReadHandleResponse(this.id, readBytes, 0, checked ((uint)request.amount), request.createdByProcess); //program.memAccesser.writeFromAddr(program.registers.DS + program.registers.A, readBytes); } catch (Exception e) { if (!e.Message.Contains("Reading file out of bounds")) { throw e; } response = new ReadHandleResponse(this.id, readBytes, 1, checked ((uint)request.amount), request.createdByProcess); //program.memAccesser.writeFromAddr(program.registers.DS + program.registers.A, readBytes); } this.kernelStorage.channelDevice.storage = 0; kernelStorage.resources.add(response); request.release(); }
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; }