blob: f474dbb7dab8bd04402faa3034569ff81d3bbc42 (
plain)
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
package cpu
import cpu.opcodes.*
import ram.Ram
import kotlin.concurrent.thread
class Cpu {
val registers = Registers()
val ram = Ram()
var currentOp: Operation? = null
var nextOp: Operation? = null
var standardOpcodes: Map<Int, Operation>
var extendedOpcodes: Map<Int, Operation>
init {
val stdCommandGroup: MutableMap<Int, Operation> = mutableMapOf()
stdCommandGroup.putAll(loads8Bit)
stdCommandGroup.putAll(loads16Bit)
stdCommandGroup.putAll(arithmetic8Bit)
stdCommandGroup.putAll(arithmetic16Bit)
stdCommandGroup.putAll(misc)
stdCommandGroup.putAll(rotates)
stdCommandGroup.putAll(jumps)
stdCommandGroup.putAll(calls)
stdCommandGroup.putAll(restarts)
stdCommandGroup.putAll(returns)
standardOpcodes = stdCommandGroup.toMap()
val extCommandGroup: MutableMap<Int, Operation> = mutableMapOf()
extCommandGroup.putAll(miscExtended)
extCommandGroup.putAll(rotatesExtended)
extCommandGroup.putAll(shiftsExtended)
extCommandGroup.putAll(generateExtendedBitOps())
extendedOpcodes = extCommandGroup.toMap()
}
fun loadRom(rom: ByteArray) {
ram.load(rom)
}
fun executeNextInstruction() {
val (op, opArgs) = getNextOp()
op.command.invoke(registers, ram, opArgs)
currentOp = op
nextOp = peekNextOp()
}
fun run() {
thread {
while(true) {
executeNextInstruction()
}
}
}
private fun getNextOp(): Pair<Operation, IntArray> {
var addr = registers.PC
val startByte = ram.readByte(addr)
val op: Operation
op = if(startByte == 0xCB) {
extendedOpcodes[ram.readByte(++addr)]!!
} else {
standardOpcodes[startByte]!!
}
val opLength = op.length
val opArgs = IntArray(opLength)
IntRange(0, opLength -1).forEach {i ->
opArgs[i] = ram.readByte(++addr)
}
registers.PC = ++addr
return Pair(op, opArgs)
}
private fun peekNextOp(): Operation {
val startByte = ram.readByte(registers.PC)
return if(startByte == 0xCB) {
extendedOpcodes[ram.readByte(registers.PC + 1)]!!
} else {
standardOpcodes[startByte]!!
}
}
}
|