dcpu16

Virtual Machine and Assembler for Notch's DCPU-16 Architecture
git clone http://frotz.net/git/dcpu16.git
Log | Files | Refs | README

disassemble.c (3070B)


      1 /*
      2  * Copyright (c) 2012, Brian Swetland
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without 
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *   Redistributions of source code must retain the above copyright notice, 
      9  *   this list of conditions and the following disclaimer.
     10  *
     11  *   Redistributions in binary form must reproduce the above copyright 
     12  *   notice, this list of conditions and the following disclaimer in the 
     13  *   documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
     18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
     19  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
     21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
     25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  *
     27  */
     28 
     29 /* A DCPU-16 Disassembler */
     30 
     31 /* DCPU-16 Spec is Copyright 2012 Mojang */
     32 /* http://0x10c.com/doc/dcpu-16.txt */
     33 
     34 #include <stdio.h>
     35 #include <stdlib.h>
     36 #include <stdint.h>
     37 #include <string.h>
     38 
     39 typedef uint16_t u16;
     40 
     41 static const char *opcode[] = {
     42 	"XXX", "MOV", "ADD", "SUB", "MUL", "DIV", "MOD", "SHL",
     43 	"SHR", "AND", "BOR", "XOR", "IFE", "IFN", "IFG", "IFB",
     44 };
     45 static const char regs[8] = "ABCXYZIJ";
     46 
     47 static u16 *dis_operand(u16 *pc, u16 n, char *out) {
     48 	if (n < 0x08) {
     49 		sprintf(out,"%c",regs[n & 7]);
     50 	} else if (n < 0x10) {
     51 		sprintf(out,"[%c]",regs[n & 7]);
     52 	} else if (n < 0x18) {
     53 		sprintf(out,"[%c, 0x%04x]",regs[n & 7], *pc++);
     54 	} else if (n > 0x1f) {
     55 		sprintf(out,"%d", n - 0x20);
     56 	} else switch (n) {
     57 		case 0x18: strcpy(out,"POP"); break;
     58 		case 0x19: strcpy(out,"PEEK"); break;
     59 		case 0x1A: strcpy(out,"PUSH"); break;
     60 		case 0x1B: strcpy(out,"SP"); break;
     61 		case 0x1C: strcpy(out,"PC"); break;
     62 		case 0x1D: strcpy(out,"O"); break;
     63 		case 0x1e: sprintf(out,"[0x%04x]",*pc++); break;
     64 		case 0x1f: sprintf(out,"0x%04x",*pc++); break;
     65 	}
     66 	return pc;	
     67 }
     68 u16 *disassemble(u16 *pc, char *out) {
     69 	u16 n = *pc++;
     70 	u16 op = n & 0xF;
     71 	u16 a = (n >> 4) & 0x3F;
     72 	u16 b = (n >> 10);
     73 	if (op > 0) {
     74 		if ((n & 0x03FF) == 0x1C1) {
     75 			sprintf(out,"JMP ");
     76 			pc = dis_operand(pc, b, out+strlen(out));
     77 			return pc;
     78 		}
     79 		sprintf(out,"%s ",opcode[op]);
     80 		pc = dis_operand(pc, a, out+strlen(out));
     81 		sprintf(out+strlen(out),", ");
     82 		pc = dis_operand(pc, b, out+strlen(out)); 
     83 		return pc;
     84 	}
     85 	if (a == 1) {
     86 		sprintf(out,"JSR ");
     87 		pc = dis_operand(pc, b, out+strlen(out));
     88 		return pc;
     89 	}
     90 	sprintf(out,"UNK[%02x] ", a);
     91 	pc = dis_operand(pc, b, out+strlen(out));
     92 	return pc;
     93 }
     94