1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
module src/ram
import bytearray
interface Ram {
def getAddr(address: Int): Byte
def setAddr(address: Int, byte: Byte): Unit
def init(rom: ByteArray): Unit
}
def get(ram: ByteArray, address: Int): Byte = ram.unsafeGet(address)
def set(ram: ByteArray, address: Int, byte: Byte): Unit = ram.unsafeSet(address, byte)
def set(ram: ByteArray, address: Int, value: Int): Unit = ram.unsafeSet(address, value.toByte)
// Load the predefined fontset. There is no better way to do this, since they are hardcoded values.
def loadFont(ram: ByteArray): Unit = {
// Since there is no way to represent hex literals in Effekt, we have to use decimal literals and convert them to bytes.
val fontSet: List[Byte] = [
240.toByte, 144.toByte, 144.toByte, 144.toByte, 240.toByte, // 0
32.toByte, 96.toByte, 32.toByte, 32.toByte, 112.toByte, // 1
240.toByte, 16.toByte, 240.toByte, 128.toByte, 240.toByte, // 2
240.toByte, 16.toByte, 240.toByte, 16.toByte, 240.toByte, // 3
144.toByte, 144.toByte, 240.toByte, 16.toByte, 16.toByte, // 4
240.toByte, 128.toByte, 240.toByte, 16.toByte, 240.toByte, // 5
240.toByte, 128.toByte, 240.toByte, 144.toByte, 240.toByte, // 6
240.toByte, 16.toByte, 32.toByte, 64.toByte, 64.toByte, // 7
240.toByte, 144.toByte, 240.toByte, 144.toByte, 240.toByte, // 8
240.toByte, 144.toByte, 240.toByte, 16.toByte, 240.toByte, // 9
240.toByte, 144.toByte, 240.toByte, 144.toByte, 144.toByte, // A
224.toByte, 144.toByte, 224.toByte, 144.toByte, 224.toByte, // B
240.toByte, 128.toByte, 128.toByte, 128.toByte, 240.toByte, // C
224.toByte, 144.toByte, 144.toByte, 144.toByte, 224.toByte, // D
240.toByte, 128.toByte, 240.toByte, 128.toByte, 240.toByte, // E
240.toByte, 128.toByte, 240.toByte, 128.toByte, 128.toByte // F
]
fontSet.foreachIndex { (i, byte) =>
ram.set(i, byte)
}
}
// Load the ROM into memory starting at 0x200 (512)
def loadRom(ram: ByteArray, rom: ByteArray): Unit = rom.foreachIndex { (i, byte) =>
set(ram, 512 + i, byte)
}
def makeRam() = {
var ram: ByteArray in global = allocate(4096) // 4KB of memory
new Ram {
def getAddr(address: Int) = get(ram, address)
def setAddr(address: Int, byte: Byte) = set(ram, address, byte)
def init(rom: ByteArray) = {
loadFont(ram)
loadRom(ram, rom)
}
}
}
|