summaryrefslogtreecommitdiff
path: root/nqdasm.c
blob: a2ff7323135953e54be988bf6b1082e8f30a7a70 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <string.h>

#include "mnemonics.h"

static const struct mnemonic *match_instruction(unsigned bits)
{
	for (int i = 0; i < MNEM_LAST; i++) {
		const struct mnemonic *m = mnemonics + i;
		if ((bits & m->mask) == m->bits) return m;
	}
	return NULL;
}

static void print_operand(unsigned bits, const struct operand *op)
{
	switch (op->type) {
	case REG:    printf( "r%d",      7 & (bits >> op->shift)); break;
	case REGPTR: printf("@r%d",      7 & (bits >> op->shift)); break;
	case IMM:    printf(  "%d", (uint8_t)(bits >> op->shift)); break;
	case PCOFF:  printf(  "%d",  (int8_t)(bits >> op->shift)); break;
	}
}

int main()
{
	unsigned bits;
	while (scanf(" %x\n", &bits) > 0) {
		const struct mnemonic *m = match_instruction(bits);
		if (!m) {
			fprintf(stderr, "could not decode instruction 0x%04x\n", bits);
			continue;
		}

		printf("\t%s", m->mnem);
		for (int i = 0; i < 3 && m->operands[i].type; i++) {
			if (i) printf(", ");
			else   printf("%*s", 8 - (int)strlen(m->mnem), "");
			print_operand(bits, m->operands + i);
		}
		printf("\n");
	}
	return 0;
}