aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/cpu')
-rw-r--r--src/main/kotlin/cpu/Cpu.kt18
-rw-r--r--src/main/kotlin/cpu/Operation.kt5
-rw-r--r--src/main/kotlin/cpu/Registers.kt124
-rw-r--r--src/main/kotlin/cpu/opcodes/Loads8Bit.kt91
4 files changed, 238 insertions, 0 deletions
diff --git a/src/main/kotlin/cpu/Cpu.kt b/src/main/kotlin/cpu/Cpu.kt
new file mode 100644
index 0000000..7ea34a4
--- /dev/null
+++ b/src/main/kotlin/cpu/Cpu.kt
@@ -0,0 +1,18 @@
+package cpu
+
+import cpu.opcodes.loads8Bit
+import ram.Ram
+
+class Cpu {
+
+ val registers = Registers()
+ val ram = Ram()
+
+ var opcodes: Map<Int, Operation>
+ init {
+ val commandGroups: MutableMap<Int, Operation> = mutableMapOf()
+ commandGroups.putAll(loads8Bit)
+ opcodes = commandGroups.toMap()
+ }
+
+} \ No newline at end of file
diff --git a/src/main/kotlin/cpu/Operation.kt b/src/main/kotlin/cpu/Operation.kt
new file mode 100644
index 0000000..71c3076
--- /dev/null
+++ b/src/main/kotlin/cpu/Operation.kt
@@ -0,0 +1,5 @@
+package cpu
+
+import ram.Ram
+
+class Operation(val name: String, val length: Int, val cycles: Int, val command: (Registers, Ram, List<Int>) -> Unit) \ No newline at end of file
diff --git a/src/main/kotlin/cpu/Registers.kt b/src/main/kotlin/cpu/Registers.kt
new file mode 100644
index 0000000..6cf417e
--- /dev/null
+++ b/src/main/kotlin/cpu/Registers.kt
@@ -0,0 +1,124 @@
+package cpu
+
+class Registers {
+
+ // General purpose registers
+ var B: Int = 0
+ set(value) {
+ validateUnsigned8Bit(value)
+ field = value
+ }
+ var C: Int = 0
+ set(value) {
+ validateUnsigned8Bit(value)
+ field = value
+ }
+ var D: Int = 0
+ set(value) {
+ validateUnsigned8Bit(value)
+ field = value
+ }
+ var E: Int = 0
+ set(value) {
+ validateUnsigned8Bit(value)
+ field = value
+ }
+ var H: Int = 0
+ set(value) {
+ validateUnsigned8Bit(value)
+ field = value
+ }
+ var L: Int = 0
+ set(value) {
+ validateUnsigned8Bit(value)
+ field = value
+ }
+
+ // Special registers
+ var A: Int = 0
+ set(value) {
+ validateUnsigned8Bit(value)
+ field = value
+ }
+ var F: Int = 0
+ set(value) {
+ validateUnsigned8Bit(value)
+ field = value
+ }
+ var SP: Int = 0
+ set(value) {
+ validateUnsigned16Bit(value)
+ field = value
+ }
+ var PC: Int = 0
+ set(value) {
+ validateUnsigned16Bit(value)
+ field = value
+ }
+
+ // 16-Bit accessors
+ var AF: Int
+ get() {
+ return bytesToWord(A, F)
+ }
+ set(value) {
+ validateUnsigned16Bit(value)
+ A = getMsb(value)
+ F = getLsb(value)
+ }
+
+ var BC: Int
+ get() {
+ return bytesToWord(B, C)
+ }
+ set(value) {
+ validateUnsigned16Bit(value)
+ B = getMsb(value)
+ C = getLsb(value)
+ }
+
+ var DE: Int
+ get() {
+ return bytesToWord(D, E)
+ }
+ set(value) {
+ validateUnsigned16Bit(value)
+ D = getMsb(value)
+ E = getLsb(value)
+ }
+
+ var HL: Int
+ get() {
+ return bytesToWord(H, L)
+ }
+ set(value) {
+ validateUnsigned16Bit(value)
+ H = getMsb(value)
+ L = getLsb(value)
+ }
+
+ private fun bytesToWord(msb: Int, lsb: Int): Int {
+ return msb.shl(8) + lsb
+ }
+
+ private fun getMsb(value: Int): Int {
+ return value.shr(8)
+ }
+
+ private fun getLsb(value: Int): Int {
+ return value.and(0xFF)
+ }
+
+ private fun validateUnsigned8Bit(value: Int) {
+ if(value < 0 || value > 255) {
+ throw IllegalArgumentException("Value $value is not an unsigned 8-Bit value")
+ }
+ }
+
+ private fun validateUnsigned16Bit(value: Int) {
+ if(value < 0 || value > 65535) {
+ throw IllegalArgumentException("Value $value is not an unsigned 16-Bit value")
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/main/kotlin/cpu/opcodes/Loads8Bit.kt b/src/main/kotlin/cpu/opcodes/Loads8Bit.kt
new file mode 100644
index 0000000..091db7f
--- /dev/null
+++ b/src/main/kotlin/cpu/opcodes/Loads8Bit.kt
@@ -0,0 +1,91 @@
+package cpu.opcodes
+
+import cpu.Operation
+
+// 8-Bit Loads
+var loads8Bit = mapOf(
+
+ 0x06 to Operation("LD B,n", 1, 8, {r, _, a -> r.B = a[0]}),
+ 0x0E to Operation("LD C,n", 1, 8, {r, _, a -> r.C = a[0]}),
+ 0x16 to Operation("LD D,n", 1, 8, {r, _, a -> r.D = a[0]}),
+ 0x1E to Operation("LD E,n", 1, 8, {r, _, a -> r.E = a[0]}),
+ 0x26 to Operation("LD H,n", 1, 8, {r, _, a -> r.H = a[0]}),
+ 0x2E to Operation("LD L,n", 1, 8, {r, _, a -> r.L = a[0]}),
+
+ 0x78 to Operation("LD A,B", 0, 4, {r, _, _ -> r.A = r.B}),
+ 0x79 to Operation("LD A,C", 0, 4, {r, _, _ -> r.A = r.C}),
+ 0x7A to Operation("LD A,D", 0, 4, {r, _, _ -> r.A = r.D}),
+ 0x7B to Operation("LD A,E", 0, 4, {r, _, _ -> r.A = r.E}),
+ 0x7C to Operation("LD A,H", 0, 4, {r, _, _ -> r.A = r.H}),
+ 0x7D to Operation("LD A,L", 0, 4, {r, _, _ -> r.A = r.L}),
+ 0x0A to Operation("LD A,(BC)", 0, 8, {r, m, _ -> r.A = m.readByte(r.BC)}),
+ 0x1A to Operation("LD A,(DE)", 0, 8, {r, m, _ -> r.A = m.readByte(r.DE)}),
+ 0x7E to Operation("LD A,(HL)", 0, 8, {r, m, _ -> r.A = m.readByte(r.HL)}),
+ 0x3E to Operation("LD A, n", 0, 8, {r, _, a -> r.A = a[0]}),
+
+ 0x40 to Operation("LD B,B", 0, 4, {r, _, _ -> r.B = r.B}),
+ 0x41 to Operation("LD B,C", 0, 4, {r, _, _ -> r.B = r.C}),
+ 0x42 to Operation("LD B,D", 0, 4, {r, _, _ -> r.B = r.D}),
+ 0x43 to Operation("LD B,E", 0, 4, {r, _, _ -> r.B = r.E}),
+ 0x44 to Operation("LD B,H", 0, 4, {r, _, _ -> r.B = r.H}),
+ 0x45 to Operation("LD B,L", 0, 4, {r, _, _ -> r.B = r.L}),
+ 0x46 to Operation("LD B,(HL)", 0, 8, {r, m, _ -> r.B = m.readByte(r.HL)}),
+
+ 0x48 to Operation("LD C,B", 0, 4, {r, _, _ -> r.C = r.B}),
+ 0x49 to Operation("LD C,C", 0, 4, {r, _, _ -> r.C = r.C}),
+ 0x4A to Operation("LD C,D", 0, 4, {r, _, _ -> r.C = r.D}),
+ 0x4B to Operation("LD C,E", 0, 4, {r, _, _ -> r.C = r.E}),
+ 0x4C to Operation("LD C,H", 0, 4, {r, _, _ -> r.C = r.H}),
+ 0x4D to Operation("LD C,L", 0, 4, {r, _, _ -> r.C = r.L}),
+ 0x4E to Operation("LD C,(HL)", 0, 8, {r, m, _ -> r.C = m.readByte(r.HL)}),
+
+ 0x50 to Operation("LD D,B", 0, 4, {r, _, _ -> r.D = r.B}),
+ 0x51 to Operation("LD D,C", 0, 4, {r, _, _ -> r.D = r.C}),
+ 0x52 to Operation("LD D,D", 0, 4, {r, _, _ -> r.D = r.D}),
+ 0x53 to Operation("LD D,E", 0, 4, {r, _, _ -> r.D = r.E}),
+ 0x54 to Operation("LD D,H", 0, 4, {r, _, _ -> r.D = r.H}),
+ 0x55 to Operation("LD D,L", 0, 4, {r, _, _ -> r.D = r.L}),
+ 0x56 to Operation("LD D,(HL)", 0, 8, {r, m, _ -> r.D = m.readByte(r.HL)}),
+
+ 0x58 to Operation("LD E,B", 0, 4, {r, _, _ -> r.E = r.B}),
+ 0x59 to Operation("LD E,C", 0, 4, {r, _, _ -> r.E = r.C}),
+ 0x5A to Operation("LD E,D", 0, 4, {r, _, _ -> r.E = r.D}),
+ 0x5B to Operation("LD E,E", 0, 4, {r, _, _ -> r.E = r.E}),
+ 0x5C to Operation("LD E,H", 0, 4, {r, _, _ -> r.E = r.H}),
+ 0x5D to Operation("LD E,L", 0, 4, {r, _, _ -> r.E = r.L}),
+ 0x5E to Operation("LD E,(HL)", 0, 8, {r, m, _ -> r.E = m.readByte(r.HL)}),
+
+ 0x60 to Operation("LD H,B", 0, 4, {r, _, _ -> r.H = r.B}),
+ 0x61 to Operation("LD H,C", 0, 4, {r, _, _ -> r.H = r.C}),
+ 0x62 to Operation("LD H,D", 0, 4, {r, _, _ -> r.H = r.D}),
+ 0x63 to Operation("LD H,E", 0, 4, {r, _, _ -> r.H = r.E}),
+ 0x64 to Operation("LD H,H", 0, 4, {r, _, _ -> r.H = r.H}),
+ 0x65 to Operation("LD H,L", 0, 4, {r, _, _ -> r.H = r.L}),
+ 0x66 to Operation("LD H,(HL)", 0, 8, {r, m, _ -> r.H = m.readByte(r.HL)}),
+
+ 0x68 to Operation("LD L,B", 0, 4, {r, _, _ -> r.L = r.B}),
+ 0x69 to Operation("LD L,C", 0, 4, {r, _, _ -> r.L = r.C}),
+ 0x6A to Operation("LD L,D", 0, 4, {r, _, _ -> r.L = r.D}),
+ 0x6B to Operation("LD L,E", 0, 4, {r, _, _ -> r.L = r.E}),
+ 0x6C to Operation("LD L,H", 0, 4, {r, _, _ -> r.L = r.H}),
+ 0x6D to Operation("LD L,L", 0, 4, {r, _, _ -> r.L = r.L}),
+ 0x6E to Operation("LD L,(HL)", 0, 8, {r, m, _ -> r.L = m.readByte(r.HL)}),
+
+ 0x70 to Operation("LD (HL),B", 0, 8, {r, m, _ -> m.writeByte(r.HL, r.B)}),
+ 0x71 to Operation("LD (HL),C", 0, 8, {r, m, _ -> m.writeByte(r.HL, r.C)}),
+ 0x72 to Operation("LD (HL),D", 0, 8, {r, m, _ -> m.writeByte(r.HL, r.D)}),
+ 0x73 to Operation("LD (HL),E", 0, 8, {r, m, _ -> m.writeByte(r.HL, r.E)}),
+ 0x74 to Operation("LD (HL),H", 0, 8, {r, m, _ -> m.writeByte(r.HL, r.H)}),
+ 0x75 to Operation("LD (HL),L", 0, 8, {r, m, _ -> m.writeByte(r.HL, r.L)}),
+ // 36 is not a typo
+ 0x36 to Operation("LD (HL),n", 1, 12, {r, m, a -> m.writeByte(r.HL, a[0])}),
+
+ 0x7F to Operation("LD A,A", 0, 4, {r, _, _ -> r.A = r.A}),
+ 0x47 to Operation("LD B,A", 0, 4, {r, _, _ -> r.B = r.A}),
+ 0x4F to Operation("LD C,A", 0, 4, {r, _, _ -> r.C = r.A}),
+ 0x57 to Operation("LD D,A", 0, 4, {r, _, _ -> r.D = r.A}),
+ 0x5F to Operation("LD E,A", 0, 4, {r, _, _ -> r.E = r.A}),
+ 0x67 to Operation("LD H,A", 0, 4, {r, _, _ -> r.H = r.A}),
+ 0x6F to Operation("LD L,A", 0, 4, {r, _, _ -> r.L = r.A})
+
+) \ No newline at end of file