1 /*
2  * sys-emu - A system emulator for tutorials
3  * Copyright (C) 2018 - 2019 osdevelopment-info
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18 package info.osdevelopment.sysemu.memory
19 
20 import java.nio.channels.SeekableByteChannel
21 import scala.util.{Failure, Success, Try}
22 
23 /**
24   * Companion object used to create a new read-only memory.
25   */
26 object ReadOnlyMemory {
27 
28   /**
29     * Create a read-only memory that is backed by a [[scala.Byte Byte]] array.
30     * @param data the data of the read-only memory
31     * @return a [[Memory]]
32     */
33   def apply(data: Array[Byte]): Try[ReadOnlyMemory] = {
34     Try(new ArrayReadOnlyMemory(data))
35   }
36 
37   /**
38     * Create a read-only memory that is backed by a `SeekableByteChannel`.
39     * @param data the data of the read-only memory
40     * @return a [[Memory]]
41     */
42   def apply(data: SeekableByteChannel): Try[ReadOnlyMemory] = {
43     Try(new ChannelReadOnlyMemory(data))
44   }
45 
46 }
47 
48 /**
49   * An abstract class to emulate a read-only memory. Subclasses can implement different possibilities to read the
50   * content.
51   */
52 abstract class ReadOnlyMemory protected() extends Memory {
53 
54   /**
55     * Read a single byte from the memory at the given address.
56     * @return a `Success` with the byte read, `Failure` otherwise
57     */
58   override final def readByte(address: Long): Try[Byte] = {
59     if (address < 0 | address >= size) Failure(new IllegalAddressException("Address outside memory"))
60     else doRead(address)
61   }
62 
63   /**
64     * The read method to be implemented by a subclass.
65     * @param address the address to read
66     * @return a `Success` with the byte read at the given address, `Failure` otherwise
67     */
68   protected def doRead(address: Long): Try[Byte]
69 
70   /**
71     * Write a single byte to the memory at the given address.
72     * @param address the address to write
73     * @param value the value to write
74     * @return a `Failure` when the address is outside the area of the memory
75     */
76   override final def writeByte(address: Long, value: Byte): Try[Unit] = {
77     if (address < 0 | address >= size) Failure(new IllegalAddressException("Address outside memory"))
78     else Success((): Unit)
79   }
80 
81 }
Line Stmt Id Pos Tree Symbol Code
34 173 1225 - 1259 Apply scala.util.Try.apply scala.util.Try.apply[info.osdevelopment.sysemu.memory.ArrayReadOnlyMemory](new ArrayReadOnlyMemory(data))
34 172 1229 - 1258 Apply info.osdevelopment.sysemu.memory.ArrayReadOnlyMemory.<init> new ArrayReadOnlyMemory(data)
43 175 1499 - 1535 Apply scala.util.Try.apply scala.util.Try.apply[info.osdevelopment.sysemu.memory.ChannelReadOnlyMemory](new ChannelReadOnlyMemory(data))
43 174 1503 - 1534 Apply info.osdevelopment.sysemu.memory.ChannelReadOnlyMemory.<init> new ChannelReadOnlyMemory(data)
59 182 1981 - 2043 Block scala.util.Failure.apply scala.util.Failure.apply[Nothing](new IllegalAddressException("Address outside memory"))
59 176 1960 - 1961 Literal <nosymbol> 0
59 178 1964 - 1979 Apply scala.Long.>= address.>=(ReadOnlyMemory.this.size)
59 181 1981 - 2043 Apply scala.util.Failure.apply scala.util.Failure.apply[Nothing](new IllegalAddressException("Address outside memory"))
59 180 1989 - 2042 Apply info.osdevelopment.sysemu.memory.IllegalAddressException.<init> new IllegalAddressException("Address outside memory")
59 177 1975 - 1979 Select info.osdevelopment.sysemu.memory.Memory.size ReadOnlyMemory.this.size
59 179 1950 - 1979 Apply scala.Boolean.| address.<(0).|(address.>=(ReadOnlyMemory.this.size))
60 184 2053 - 2068 Block info.osdevelopment.sysemu.memory.ReadOnlyMemory.doRead ReadOnlyMemory.this.doRead(address)
60 183 2053 - 2068 Apply info.osdevelopment.sysemu.memory.ReadOnlyMemory.doRead ReadOnlyMemory.this.doRead(address)
77 191 2665 - 2727 Block scala.util.Failure.apply scala.util.Failure.apply[Nothing](new IllegalAddressException("Address outside memory"))
77 185 2644 - 2645 Literal <nosymbol> 0
77 187 2648 - 2663 Apply scala.Long.>= address.>=(ReadOnlyMemory.this.size)
77 190 2665 - 2727 Apply scala.util.Failure.apply scala.util.Failure.apply[Nothing](new IllegalAddressException("Address outside memory"))
77 189 2673 - 2726 Apply info.osdevelopment.sysemu.memory.IllegalAddressException.<init> new IllegalAddressException("Address outside memory")
77 186 2659 - 2663 Select info.osdevelopment.sysemu.memory.Memory.size ReadOnlyMemory.this.size
77 188 2634 - 2663 Apply scala.Boolean.| address.<(0).|(address.>=(ReadOnlyMemory.this.size))
78 194 2737 - 2754 Block scala.util.Success.apply scala.util.Success.apply[Unit](((): Unit))
78 193 2737 - 2754 Apply scala.util.Success.apply scala.util.Success.apply[Unit](((): Unit))
78 192 2745 - 2747 Literal <nosymbol> ()