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 info.osdevelopment.sysemu.support.Utilities._
21 import scala.util.{Failure, Try}
22 
23 /**
24   * Companion object used to create a new read-write memory up to 2^60^ (1 EiB). Please note that the memory will be
25   * allocated immediately at creation on your host.
26   */
27 object ReadWriteMemory {
28 
29   /**
30     * Creates a default read-write memory with 1 GiB.
31     * @return a `Success` with a read-write memory with 1 GiB or a `Failure`
32     */
33   def apply(): Try[ReadWriteMemory] = {
34     apply(1.Gi)
35   }
36 
37   /**
38     * Creates a read-write memory with the given `size`.
39     * @param size the size of the memory
40     * @return a `Success` with the read-write memory with the given size or a `Failure`
41     */
42   def apply(size: Long): Try[ReadWriteMemory] = {
43     if (size <= 0 | size > 1.Ei) Failure(new IllegalArgumentException("Max size supported is 1 EiB"))
44     else {
45       if (size > 1.Gi) {
46         CombinedReadWriteMemory(size)
47       } else {
48         SimpleReadWriteMemory(size)
49       }
50     }
51   }
52 
53 }
54 
55 abstract class ReadWriteMemory protected() extends Memory {
56 
57   /**
58     * Read a single `Byte` from the memory at the given address.
59     * @param address the `address` to read from
60     * @return a `Success` with the byte read or a `Failure`
61     */
62   override final def readByte(address: Long): Try[Byte] = {
63     if (address < 0 | address >= size) Failure(new IllegalAddressException("Address outside memory"))
64     else doRead(address)
65   }
66 
67   /**
68     * The read method to be implemented by a subclass.
69     * @param address the address to read
70     * @return a `Success` with the byte read at the given address or a `Failure`
71     */
72   protected def doRead(address: Long): Try[Byte]
73 
74   /**
75     * Write a single `Byte` to the memory at the given address.
76     * @param address the `address` to write to
77     * @param value the `value` to write
78     * @return a `Success` when the byte is written or a `Failure`
79     */
80   override final def writeByte(address: Long, value: Byte): Try[Unit] = {
81     if (address < 0 | address >= size) Failure(new IllegalAddressException("Address outside memory"))
82     else doWrite(address, value)
83   }
84 
85   /**
86     * The write method to be implemented by a subclass.
87     * @param address the address to write
88     * @param value the `value` to write
89     * @return a `Success` when the byte is written or a `Failure`
90     */
91   protected def doWrite(address: Long, value: Byte): Try[Unit]
92 
93 }
Line Stmt Id Pos Tree Symbol Code
34 196 1298 - 1302 Select info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong.Gi info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi
34 195 1298 - 1299 Literal <nosymbol> 1L
34 197 1292 - 1303 Apply info.osdevelopment.sysemu.memory.ReadWriteMemory.apply ReadWriteMemory.this.apply(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi)
43 200 1585 - 1589 Select info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong.Ei info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Ei
43 202 1566 - 1589 Apply scala.Boolean.| size.<=(0).|(size.>(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Ei))
43 205 1591 - 1659 Block scala.util.Failure.apply scala.util.Failure.apply[Nothing](new scala.`package`.IllegalArgumentException("Max size supported is 1 EiB"))
43 199 1585 - 1586 Literal <nosymbol> 1L
43 198 1574 - 1575 Literal <nosymbol> 0
43 201 1578 - 1589 Apply scala.Long.> size.>(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Ei)
43 204 1591 - 1659 Apply scala.util.Failure.apply scala.util.Failure.apply[Nothing](new scala.`package`.IllegalArgumentException("Max size supported is 1 EiB"))
43 203 1599 - 1658 Apply java.lang.IllegalArgumentException.<init> new scala.`package`.IllegalArgumentException("Max size supported is 1 EiB")
45 208 1681 - 1692 Apply scala.Long.> size.>(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi)
45 207 1688 - 1692 Select info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong.Gi info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi
45 213 1677 - 1792 If <nosymbol> if (size.>(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi)) CombinedReadWriteMemory.apply(size) else SimpleReadWriteMemory.apply(size)
45 206 1688 - 1689 Literal <nosymbol> 1L
46 209 1704 - 1733 Apply info.osdevelopment.sysemu.memory.CombinedReadWriteMemory.apply CombinedReadWriteMemory.apply(size)
46 210 1704 - 1733 Block info.osdevelopment.sysemu.memory.CombinedReadWriteMemory.apply CombinedReadWriteMemory.apply(size)
48 211 1757 - 1784 Apply info.osdevelopment.sysemu.memory.SimpleReadWriteMemory.apply SimpleReadWriteMemory.apply(size)
48 212 1757 - 1784 Block info.osdevelopment.sysemu.memory.SimpleReadWriteMemory.apply SimpleReadWriteMemory.apply(size)
63 218 2161 - 2214 Apply info.osdevelopment.sysemu.memory.IllegalAddressException.<init> new IllegalAddressException("Address outside memory")
63 220 2153 - 2215 Block scala.util.Failure.apply scala.util.Failure.apply[Nothing](new IllegalAddressException("Address outside memory"))
63 214 2132 - 2133 Literal <nosymbol> 0
63 217 2122 - 2151 Apply scala.Boolean.| address.<(0).|(address.>=(ReadWriteMemory.this.size))
63 216 2136 - 2151 Apply scala.Long.>= address.>=(ReadWriteMemory.this.size)
63 219 2153 - 2215 Apply scala.util.Failure.apply scala.util.Failure.apply[Nothing](new IllegalAddressException("Address outside memory"))
63 215 2147 - 2151 Select info.osdevelopment.sysemu.memory.Memory.size ReadWriteMemory.this.size
64 222 2225 - 2240 Block info.osdevelopment.sysemu.memory.ReadWriteMemory.doRead ReadWriteMemory.this.doRead(address)
64 221 2225 - 2240 Apply info.osdevelopment.sysemu.memory.ReadWriteMemory.doRead ReadWriteMemory.this.doRead(address)
81 227 2837 - 2890 Apply info.osdevelopment.sysemu.memory.IllegalAddressException.<init> new IllegalAddressException("Address outside memory")
81 226 2798 - 2827 Apply scala.Boolean.| address.<(0).|(address.>=(ReadWriteMemory.this.size))
81 229 2829 - 2891 Block scala.util.Failure.apply scala.util.Failure.apply[Nothing](new IllegalAddressException("Address outside memory"))
81 223 2808 - 2809 Literal <nosymbol> 0
81 225 2812 - 2827 Apply scala.Long.>= address.>=(ReadWriteMemory.this.size)
81 228 2829 - 2891 Apply scala.util.Failure.apply scala.util.Failure.apply[Nothing](new IllegalAddressException("Address outside memory"))
81 224 2823 - 2827 Select info.osdevelopment.sysemu.memory.Memory.size ReadWriteMemory.this.size
82 231 2901 - 2924 Block info.osdevelopment.sysemu.memory.ReadWriteMemory.doWrite ReadWriteMemory.this.doWrite(address, value)
82 230 2901 - 2924 Apply info.osdevelopment.sysemu.memory.ReadWriteMemory.doWrite ReadWriteMemory.this.doWrite(address, value)