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>
|
()
|