package mtmc.asm.instructions import mtmc.asm.Assembler import mtmc.emulator.Register import mtmc.emulator.Register.Companion.fromInteger import mtmc.emulator.Register.Companion.toInteger import mtmc.tokenizer.MTMCToken import mtmc.util.BinaryUtils class LoadStoreRegisterInstruction( type: InstructionType, label: List, instructionToken: MTMCToken ) : Instruction(type, label, instructionToken) { private var targetToken: MTMCToken? = null private var pointerToken: MTMCToken? = null private var offsetToken: MTMCToken? = null fun setTargetToken(targetToken: MTMCToken) { this.targetToken = targetToken } fun setPointerToken(pointerToken: MTMCToken) { this.pointerToken = pointerToken } fun setOffsetToken(offsetToken: MTMCToken?) { this.offsetToken = offsetToken } override fun genCode(output: ByteArray, assembler: Assembler) { var opcode = 0 when (type) { InstructionType.LWR -> opcode = 4 InstructionType.LBR -> opcode = 5 InstructionType.SWR -> opcode = 6 InstructionType.SBR -> opcode = 7 else -> println("Invalid instruction type") } val target = toInteger(targetToken!!.stringValue) val pointer = toInteger(pointerToken!!.stringValue) var offset = Register.PC.ordinal if (offsetToken != null) { offset = toInteger(offsetToken!!.stringValue) } output[location] = (opcode shl 4 or target).toByte() output[location + 1] = (pointer shl 4 or offset).toByte() } companion object { fun disassemble(instruction: Short): String? { if (BinaryUtils.getBits(16, 2, instruction).toInt() == 1) { val builder = StringBuilder() val type = BinaryUtils.getBits(14, 2, instruction) if (type.toInt() == 0) { builder.append("lwr ") } else if (type.toInt() == 1) { builder.append("lbr ") } else if (type.toInt() == 2) { builder.append("swr ") } else if (type.toInt() == 3) { builder.append("sbr ") } val srcDestReg = BinaryUtils.getBits(12, 4, instruction) val addrReg = BinaryUtils.getBits(8, 4, instruction) val offsetReg = BinaryUtils.getBits(4, 4, instruction) builder.append(fromInteger(srcDestReg.toInt())).append(" ") builder.append(fromInteger(addrReg.toInt())).append(" ") builder.append(fromInteger(offsetReg.toInt())) return builder.toString() } return null } } }