diff --git a/dis.py b/dis.py index dc53d45..8236e67 100644 --- a/dis.py +++ b/dis.py @@ -50,93 +50,91 @@ def determine_instruction_type(opcode: int): else: return InstructionTypes.UNKNOWN -OP = [int(argv[1],16), 0] -if len(argv) >= 3: - OP[1] = int(argv[2],16) - -match determine_instruction_type(OP[0]): - case InstructionTypes.DATAPROCESSING_ALU6IMM: - alu_op_fmt = { - 0b0000: 'R{0} += {1};', - 0b0001: 'R{0} += {1}, Carry;', - 0b0010: 'R{0} -= {1};', - 0b0011: 'R{0} -= {1}, Carry;', - 0b0100: 'CMP R{0}, {1};', - 0b0110: 'R{0} =- {1};', - 0b1000: 'R{0} ^= {1};', - 0b1001: 'R{0} = {1};', - 0b1010: 'R{0} |= {1};', - 0b1011: 'R{0} &= {1};', - 0b1100: 'TEST R{0}, {1};', - } - alu_op = (OP[0] & 0b1111_000_000_000000) >> 12 - rd = (OP[0] & 0b0000_111_000_000000) >> 9 - im6 = OP[0] & 0b0000_000_000_111111 - - print(alu_op_fmt[alu_op].format(rd, im6)) - case InstructionTypes.DATAPROCESSING_ALU6DIR: - alu_op_fmt = { - 0b0000: 'R{0} += [{1}];', - 0b0001: 'R{0} += [{1}], Carry;', - 0b0010: 'R{0} -= [{1}];', - 0b0011: 'R{0} -= [{1}], Carry;', - 0b0100: 'CMP R{0}, [{1}];', - 0b0110: 'R{0} =- [{1}];', - 0b1000: 'R{0} ^= [{1}];', - 0b1001: 'R{0} = [{1}];', - 0b1010: 'R{0} |= [{1}];', - 0b1011: 'R{0} &= [{1}];', - 0b1100: 'TEST R{0}, [{1}];', - } - alu_op = (OP[0] & 0b1111_000_000_000000) >> 12 - rd = (OP[0] & 0b0000_111_000_000000) >> 9 - a6 = OP[0] & 0b0000_000_000_111111 - - print(alu_op_fmt[alu_op].format(rd, a6)) - case InstructionTypes.DATAPROCESSING_SHFT: - shift_op_fmt = { - 0b000: '', - 0b001: 'ASR', - 0b010: 'LSL', - 0b011: 'LSR', - 0b100: 'ROL', - 0b101: 'ROR', - } - alu_op_fmt = { - 0b0000: 'R{0} += R{1} {2} {3};', - 0b0001: 'R{0} += R{1} {2} {3}, Carry;', - 0b0010: 'R{0} -= R{1} {2} {3};', - 0b0011: 'R{0} -= R{1} {2} {3}, Carry;', - 0b0100: 'CMP R{0}, R{1} {2} {3};', - 0b0110: 'R{0} =- R{1} {2} {3};', - 0b1000: 'R{0} ^= R{1} {2} {3};', - 0b1001: 'R{0} = R{1} {2} {3};', - 0b1010: 'R{0} |= R{1} {2} {3};', - 0b1011: 'R{0} &= R{1} {2} {3};', - 0b1100: 'TEST R{0}, R{1} {2} {3};', - } - alu_op = (OP[0] & 0b1111_000_0_000_00_000) >> 12 - rd = (OP[0] & 0b0000_111_0_000_00_000) >> 9 - shift_op = (OP[0] & 0b0000_000_0_111_00_000) >> 5 - n = (OP[0] & 0b0000_000_0_000_11_000) >> 3 - rs = OP[0] & 0b0000_000_0_000_00_111 - - print(alu_op_fmt[alu_op].format(rd, rs, shift_op_fmt[shift_op], n+1)) - case InstructionTypes.INTERRUPT: - irq = (OP[0] & 0b01) != 0 - fiq = (OP[0] & 0b10) != 0 - - if irq and not fiq: - print('INT IRQ;') - elif not irq and fiq: - print('INT FIQ;') - elif irq and fiq: - print('INT FIQ,IRQ;') - else: - print('INT OFF;') - case InstructionTypes.FUNCTION_RETF: - print('RETF;') - case InstructionTypes.FUNCTION_RETI: - print('RETI;') - case _: - print('unknown instruction') +def disassemble(opcode: list): + match determine_instruction_type(opcode[0]): + case InstructionTypes.DATAPROCESSING_ALU6IMM: + + alu_op_fmt = { + 0b0000: 'R{0} += {1};', + 0b0001: 'R{0} += {1}, Carry;', + 0b0010: 'R{0} -= {1};', + 0b0011: 'R{0} -= {1}, Carry;', + 0b0100: 'CMP R{0}, {1};', + 0b0110: 'R{0} =- {1};', + 0b1000: 'R{0} ^= {1};', + 0b1001: 'R{0} = {1};', + 0b1010: 'R{0} |= {1};', + 0b1011: 'R{0} &= {1};', + 0b1100: 'TEST R{0}, {1};', + } + alu_op = (opcode[0] & 0b1111_000_000_000000) >> 12 + rd = (opcode[0] & 0b0000_111_000_000000) >> 9 + im6 = opcode[0] & 0b0000_000_000_111111 + return alu_op_fmt[alu_op].format(rd, im6) + case InstructionTypes.DATAPROCESSING_ALU6DIR: + + alu_op_fmt = { + 0b0000: 'R{0} += [{1}];', + 0b0001: 'R{0} += [{1}], Carry;', + 0b0010: 'R{0} -= [{1}];', + 0b0011: 'R{0} -= [{1}], Carry;', + 0b0100: 'CMP R{0}, [{1}];', + 0b0110: 'R{0} =- [{1}];', + 0b1000: 'R{0} ^= [{1}];', + 0b1001: 'R{0} = [{1}];', + 0b1010: 'R{0} |= [{1}];', + 0b1011: 'R{0} &= [{1}];', + 0b1100: 'TEST R{0}, [{1}];', + } + alu_op = (opcode[0] & 0b1111_000_000_000000) >> 12 + rd = (opcode[0] & 0b0000_111_000_000000) >> 9 + a6 = opcode[0] & 0b0000_000_000_111111 + return alu_op_fmt[alu_op].format(rd, a6) + case InstructionTypes.DATAPROCESSING_SHFT: + + shift_op_fmt = { + 0b000: '', + 0b001: 'ASR', + 0b010: 'LSL', + 0b011: 'LSR', + 0b100: 'ROL', + 0b101: 'ROR', + } + alu_op_fmt = { + 0b0000: 'R{0} += R{1} {2} {3};', + 0b0001: 'R{0} += R{1} {2} {3}, Carry;', + 0b0010: 'R{0} -= R{1} {2} {3};', + 0b0011: 'R{0} -= R{1} {2} {3}, Carry;', + 0b0100: 'CMP R{0}, R{1} {2} {3};', + 0b0110: 'R{0} =- R{1} {2} {3};', + 0b1000: 'R{0} ^= R{1} {2} {3};', + 0b1001: 'R{0} = R{1} {2} {3};', + 0b1010: 'R{0} |= R{1} {2} {3};', + 0b1011: 'R{0} &= R{1} {2} {3};', + 0b1100: 'TEST R{0}, R{1} {2} {3};', + } + alu_op = (opcode[0] & 0b1111_000_0_000_00_000) >> 12 + rd = (opcode[0] & 0b0000_111_0_000_00_000) >> 9 + shift_op = (opcode[0] & 0b0000_000_0_111_00_000) >> 5 + n = (opcode[0] & 0b0000_000_0_000_11_000) >> 3 + rs = opcode[0] & 0b0000_000_0_000_00_111 + return alu_op_fmt[alu_op].format(rd, rs, shift_op_fmt[shift_op], n+1) + case InstructionTypes.INTERRUPT: + + irq = (opcode[0] & 0b01) != 0 + fiq = (opcode[0] & 0b10) != 0 + if irq and not fiq: + return 'INT IRQ;' + + elif not irq and fiq: + return 'INT FIQ;' + elif irq and fiq: + return 'INT FIQ,IRQ;' + else: + return 'INT OFF;' + case InstructionTypes.FUNCTION_RETF: + return 'RETF;' + case InstructionTypes.FUNCTION_RETI: + return 'RETI;' + case _: + return 'unknown instruction' diff --git a/index.html b/index.html new file mode 100644 index 0000000..68f20fb --- /dev/null +++ b/index.html @@ -0,0 +1,48 @@ + + +
+ + + + + +This is an personal attempt at creating a disassembler for the µ'nSP ISA created by Sunplus Technology.
+The µ'nSP architecture is an 16-bit CPU architecture that was used on microcontrollers and some plug-and-play video game devices (Such as the various Jakks Pacific GameKey-board consoles and the VTech V.Smile).
+This disassembler was written in Python and runs on the web using Brython.
+Source is available at git.nadeko.net/Serg2/unsp-dasm and is licensed under the MIT No Attribution license.
+