diff --git a/src/main/kotlin/com/thequux/mcpdp/core/CPU.kt b/src/main/kotlin/com/thequux/mcpdp/core/CPU.kt index 7c86fcb..7733791 100644 --- a/src/main/kotlin/com/thequux/mcpdp/core/CPU.kt +++ b/src/main/kotlin/com/thequux/mcpdp/core/CPU.kt @@ -125,11 +125,11 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { val dst = opc_dst(opcode) val v = op_loadw(dst) val res = (v shl 8) or (v shr 8) - op_storw(dst, res) V = false C = false N = res bit 7 Z = (res and 0xFFu) == 0.toUShort() + op_storw(dst, res) } // SWAB else -> throw InvalidOpcodeException() } } @@ -154,35 +154,37 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { insnTable[0x0A] = {opcode -> when (opcode shr 6 and 3) { 0 -> { // CLR - op_storw(opc_dst(opcode), 0U) N = false V = false C = false Z = true + op_storw(opc_dst(opcode), 0U) } // CLR 1 -> { // COM val dst = opc_dst(opcode) - val res = op_loadw(dst).inv().also { op_storw(dst, it) } + val res = op_loadw(dst).inv() N = res bit 15 Z = res == 0U.toUShort() C = true V = false + op_storw(dst, res) } // COM 2 -> { // INC val dst = opc_dst(opcode) val src = op_loadw(dst) val res = src.inc() - op_storw(dst, res) N = res bit 15 Z = res == 0.toUShort() V = res == 0x8000.toUShort() + op_storw(dst, res) } // INC 3 -> { // DEC val dst = opc_dst(opcode) - val res = op_loadw(dst).dec().also { op_storw(dst, it) } + val res = op_loadw(dst).dec() N = res bit 15 Z = res == 0.toUShort() V = res == 0x7FFF.toUShort() + op_storw(dst, res) } // DEC } } // CLR, COM, INC, DEC @@ -191,31 +193,31 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { 0 -> { // NEG val dst = opc_dst(opcode) val res = op_loadw(dst).inv().inc() - op_storw(dst, res) N = res bit 15 Z = res == 0.toUShort() V = res == 0x8000.toUShort() C = !Z + op_storw(dst, res) } // NEG 1 -> { // ADC val dst = opc_dst(opcode) val c: UShort = if (C) 1u else 0u val res = (op_loadw(dst) + c).toUShort() - op_storw(dst, res) N = res bit 15 Z = res == 0u.toUShort() V = (res == 0x8000u.toUShort()) and C C = Z and C + op_storw(dst, res) } // ADC 2 -> { val dst = opc_dst(opcode) val src = op_loadw(dst) val res = if (C) src.dec() else src - op_storw(dst, res) N = res bit 15 Z = res == 0.toUShort() V = res == 0x8000.toUShort() C = C and (src == 0.toUShort()) + op_storw(dst, res) } // SBC 3 -> { val dst = op_loadw(opc_dst(opcode)) @@ -232,41 +234,41 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { val dst = opc_dst(opcode) val src = op_loadw(dst) val res = (src shr 1).bit(15, C) - op_storw(dst, res) C = src bit 0 N = res bit 15 Z = res == 0.toUShort() V = N xor C + op_storw(dst, res) } // ROR 1 -> { val dst = opc_dst(opcode) val src = op_loadw(dst) val res = (src shl 1).bit(0, C) - op_storw(dst, res) C = src bit 15 N = res bit 15 Z = res == 0.toUShort() V = N xor C + op_storw(dst, res) } // ROL 2 -> { // ASR val dst = opc_dst(opcode) val src = op_loadw(dst).toShort() val res = (src shr 1).toUShort() - op_storw(dst, res) N = res bit 15 Z = res == 0.toUShort() C = src bit 0 V = N xor C + op_storw(dst, res) } // ASR 3 -> { // ASL val dst = opc_dst(opcode) val src = op_loadw(dst) val res = src shl 1 - op_storw(dst, res.toUShort()) N = res bit 15 Z = res == 0.toUShort() C = src and 0x8000u != 0u.toUShort() V = N xor C + op_storw(dst, res) } // ASL } } // ROR, ROL, ASR, ASL @@ -289,14 +291,17 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { // memory ref core.getSpace(prv_mode).getw(src.toUShort(), dspace = false) } - stack_push(v) N = v bit 15 Z = v == 0u.toUShort() V = false + stack_push(v) } // MFPI // TODO 2 -> { val v = stack_pop() val dest = opc_dst(opcode) + N = v bit 15 + Z = v == 0u.toUShort() + V = false if (is_paddr_reg(dest)) { if (dest and 7u == 6u && prv_mode != cur_mode) { shadow_r6[prv_mode] = v @@ -306,14 +311,11 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { // memory ref core.getSpace(prv_mode).setw(dest.toUShort(), v, dspace = false) } - N = v bit 15 - Z = v == 0u.toUShort() - V = false } // MTPI // TODO 3 -> { - op_storw(opc_dst(opcode), if (N) (-1).toUShort() else 0.toUShort()) Z = !N V = false + op_storw(opc_dst(opcode), if (N) (-1).toUShort() else 0.toUShort()) } // SXT } } // MARK, MFPI, MTPI, SXT @@ -352,19 +354,19 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { val src = opc_src(opcode) val dst = opc_dst(opcode) val res = op_loadw(dst) and op_loadw(src).inv() - op_storw(dst, res) N = res bit 15 Z = res == 0u.toUShort() V = false + op_storw(dst, res) } // BIC for (i in 0x50..0x5F) insnTable[i] = { opcode -> // BIS val src = opc_src(opcode) val dst = opc_dst(opcode) val res = op_loadw(dst) or op_loadw(src) - op_storw(dst, res) N = res and 0x8000u != 0u.toUShort() Z = res == 0u.toUShort() V = false + op_storw(dst, res) } // BIS for (i in 0x60..0x6F) insnTable[i] = { opcode -> // ADD val src = opc_src(opcode) @@ -373,12 +375,12 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { val dstv = op_loadw(dst) val res = (srcv + dstv) val resw = res.toUShort() - op_storw(dst, res.toUShort()) N = resw > 0x7FFFu Z = resw == 0.toUShort() val src_sign = srcv and 0x8000u V = (src_sign == dstv and 0x8000u) && (src_sign != resw and 0x8000u) C = (res >= 0x10000u) + op_storw(dst, res.toUShort()) } // ADD insnTable[0x70] = { opcode -> // MUL val r = opcode shr 6 and 0x7 @@ -493,10 +495,10 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { val r = opcode shr 6 and 7 val dst = opc_dst(opcode) val res = op_loadw(dst) xor registers[r] - op_storw(dst, res) N = res bit 15 Z = res == 0.toUShort() V = false + op_storw(dst, res) } // XOR // 0x7A and 0x7C are undefined insnTable[0x7E] = { opcode -> // SOB @@ -526,33 +528,36 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { insnTable[0x8A] = { opcode -> when (opcode shr 6 and 3) { 0 -> { // CLRB - op_storb(opc_dstb(opcode), 0U) N = false V = false C = false Z = true + op_storb(opc_dstb(opcode), 0U) } // CLRB 1 -> { // COMB val dst = opc_dstb(opcode) - val res = op_loadb(dst).inv().also { op_storb(dst, it) } + val res = op_loadb(dst).inv() N = res bit 7 Z = res == 0U.toUByte() C = true V = false + op_storb(dst, res) } // COMB - 2 -> { // INC + 2 -> { // INCB val dst = opc_dstb(opcode) - val res = op_loadb(dst).inc().also { op_storb(dst, it) } + val res = op_loadb(dst).inc() N = res bit 7 Z = res == 0.toUByte() V = res == 0x80.toUByte() + op_storb(dst, res) } // INCB 3 -> { // DEC val dst = opc_dstb(opcode) - val res = op_loadb(dst).dec().also { op_storb(dst, it) } + val res = op_loadb(dst).dec() N = res bit 7 Z = res == 0.toUByte() V = res == 0x7F.toUByte() + op_storb(dst, res) } // DECB } } // CLRB, COMB, INCB, DECB @@ -561,31 +566,31 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { 0 -> { // NEGB val dst = opc_dstb(opcode) val res = op_loadb(dst).inv().inc() - op_storb(dst, res) N = res bit 7 Z = res == 0.toUByte() V = res == 0x8000.toUByte() C = !Z + op_storb(dst, res) } // NEGB 1 -> { // ADCB val dst = opc_dstb(opcode) val c: UShort = if (C) 1u else 0u val res = (op_loadb(dst) + c).toUByte() - op_storb(dst, res) N = res bit 7 Z = res == 0u.toUByte() V = (res == 0x80u.toUByte()) and C C = Z and C + op_storb(dst, res) } // ADCB 2 -> { val dst = opc_dstb(opcode) val src = op_loadb(dst) val res = if (C) src.dec() else src - op_storb(dst, res) N = res bit 8 Z = res == 0.toUByte() V = res == 0x80.toUByte() C = C and (src == 0.toUByte()) + op_storb(dst, res) } // SBCB 3 -> { val dst = op_loadb(opc_dstb(opcode)) @@ -602,41 +607,41 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { val dst = opc_dstb(opcode) val src = op_loadb(dst) val res = (src shr 1).bit(7, C) - op_storb(dst, res) C = src bit 0 N = res bit 7 Z = res == 0.toUByte() V = N xor C + op_storb(dst, res) } // RORB 1 -> { val dst = opc_dstb(opcode) val src = op_loadb(dst) val res = (src shl 1).bit(0, C) - op_storb(dst, res) C = src bit 7 N = res bit 7 Z = res == 0.toUByte() V = N xor C + op_storb(dst, res) } // ROLB 2 -> { // ASRB val dst = opc_dstb(opcode) val src = op_loadb(dst).toByte() val res = (src shr 1).toUByte() - op_storb(dst, res) N = res bit 7 Z = res == 0.toUByte() C = src bit 0 V = N xor C + op_storb(dst, res) } // ASRB 3 -> { // ASLB val dst = opc_dstb(opcode) val src = op_loadb(dst) val res = (src shl 1).toUByte() - op_storw(dst, res.toUShort()) N = res bit 7 Z = res == 0.toUByte() C = src bit 7 V = N xor C + op_storw(dst, res.toUShort()) } // ASLB } } // RORB, ROLB, ASRB, ASLB @@ -653,14 +658,17 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { // memory ref core.getSpace(prv_mode).getw(src.toUShort(), dspace = true) } - stack_push(v) N = v bit 15 Z = v == 0u.toUShort() V = false + stack_push(v) } // MFPD // TODO 2 -> { val v = stack_pop() val dest = opc_dst(opcode) + N = v bit 15 + Z = v == 0u.toUShort() + V = false if (is_paddr_reg(dest)) { if (dest and 7u == 6u && prv_mode != cur_mode) { shadow_r6[prv_mode] = v @@ -670,9 +678,6 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { // memory ref core.getSpace(prv_mode).setw(dest.toUShort(), v, dspace = true) } - N = v bit 15 - Z = v == 0u.toUShort() - V = false } // MTPD // TODO else -> { throw InvalidOpcodeException() } // Reserved } @@ -683,6 +688,9 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { val dst = opc_dstb(opcode) val dstv = op_loadb(src) + N = dstv bit 7 + Z = dstv == 0.toUByte() + V = false if (is_paddr_reg(dst)) { op_storw(dst, dstv.toUShort() sex 8) dstv.toUShort() sex 8 @@ -690,9 +698,6 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { op_storb(dst, dstv) dstv.toUShort() } - N = dstv bit 7 - Z = dstv == 0.toUByte() - V = false } // MOVB for (i in 0xA0..0xAF) insnTable[i] = { opcode -> // CMPB @@ -716,19 +721,19 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { val src = opc_srcb(opcode) val dst = opc_dstb(opcode) val res = op_loadb(dst) and op_loadb(src).inv() - op_storb(dst, res) N = res bit 7 Z = res == 0u.toUByte() V = false + op_storb(dst, res) } // BICB for (i in 0xD0..0xDF) insnTable[i] = { opcode -> // BISB val src = opc_srcb(opcode) val dst = opc_dstb(opcode) val res = op_loadb(dst) or op_loadb(src) - op_storb(dst, res) N = res bit 7 Z = res == 0u.toUByte() V = false + op_storb(dst, res) } // BISB for (i in 0xE0..0xEF) insnTable[i] = { opcode -> val src = opc_src(opcode) @@ -736,11 +741,11 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) { val srcv = op_loadw(src) val dstv = op_loadw(dst) val res = (dstv.toShort() - srcv.toShort()) - op_storw(dst, res.toUShort()) N = res < 0 Z = res == 0 V = ((srcv bit 31) xor (dstv bit 15)) and ((srcv bit 15) == (res bit 31)) C = (dst.toInt() + src.inv().inc().toInt()) < 0x1_0000 + op_storw(dst, res.toUShort()) } // SUB // insnTable[0x0E] = // TODO: check this // insnTable[0x0F] = // TODO: check this