URL
https://opencores.org/ocsvn/t48/t48/trunk
Subversion Repositories t48
[/] [t48/] [tags/] [rel_0_2_beta/] [sw/] [i8039emu/] [8039dasm.c] - Rev 338
Go to most recent revision | Compare with Previous | Blame | View Log
/**************************************************************************** * * mcs48 disassembler * * This file is Copyright 1996 Michael Cuddy, Fen's Ende Sofware. * Redistribution is allowed in source and binary form as long as both * forms are distributed together with the file 'README'. This copyright * notice must also accompany the files. * * This software should be considered a small token to all of the * emulator authors for thier dilligence in preserving our Arcade and * Computer history. * * Michael Cuddy, Fen's Ende Software. * 11/25/1996 * * Adapted by Andrea Mazzoleni for use with MAME * ***************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "memory.h" typedef unsigned char byte; #define FMT(a,b) a, b #define PTRS_PER_FORMAT 2 const char *Formats[] = { FMT("00000011dddddddd", "add a, #%X"), FMT("01101rrr", "add a, %R"), FMT("0110000r", "add a, @%R"), FMT("00010011dddddddd", "adc a, #%X"), FMT("01111rrr", "adc a, %R"), FMT("0111000r", "adc a, @%R"), FMT("01010011dddddddd", "anl a, #%X"), FMT("01011rrr", "anl a, %R"), FMT("0101000r", "anl a, @%R"), FMT("10011000dddddddd", "anl bus, #%X"), FMT("10011001dddddddd", "anl p1, #%X"), FMT("10011010dddddddd", "anl p2, #%X"), FMT("100111pp", "anld %P, a"), FMT("aaa10100aaaaaaaa", "call %A"), FMT("00100111", "clr a"), FMT("10010111", "clr c"), FMT("10100101", "clr f1"), FMT("10000101", "clr f0"), FMT("00110111", "cpl a"), FMT("10100111", "cpl c"), FMT("10010101", "cpl f0"), FMT("10110101", "cpl f1"), FMT("01010111", "da a"), FMT("00000111", "dec a"), FMT("11001rrr", "dec %R"), FMT("00010101", "dis i"), FMT("00110101", "dis tcnti"), FMT("11101rrraaaaaaaa", "djnz %R, %J"), FMT("00000101", "en i"), FMT("00100101", "en tcnti"), FMT("01110101", "ent0 clk"), FMT("00001001", "in a, p1"), FMT("00001010", "in a, p2"), FMT("00010111", "inc a"), FMT("00011rrr", "inc %R"), FMT("0001000r", "inc @%R"), FMT("00001000", "ins a,bus"), FMT("0001 0110aaaaaaaa", "jtf %J"), FMT("0010 0110aaaaaaaa", "jnt0 %J"), FMT("0011 0110aaaaaaaa", "jt0 %J"), FMT("0100 0110aaaaaaaa", "jnt1 %J"), FMT("0101 0110aaaaaaaa", "jt1 %J"), FMT("0111 0110aaaaaaaa", "jf1 %J"), FMT("1000 0110aaaaaaaa", "jni %J"), FMT("1001 0110aaaaaaaa", "jnz %J"), FMT("1011 0110aaaaaaaa", "jf0 %J"), FMT("1100 0110aaaaaaaa", "jz %J"), FMT("1110 0110aaaaaaaa", "jnc %J"), FMT("1111 0110aaaaaaaa", "jc %J"), FMT("bbb10010aaaaaaaa", "jb%B %J"), FMT("aaa00100aaaaaaaa", "jmp %A"), FMT("10110011", "jmpp @a"), FMT("00100011dddddddd", "mov a, #%X"), FMT("11111rrr", "mov a, %R"), FMT("1111000r", "mov a, @%R"), FMT("11000111", "mov a, psw"), FMT("10111rrrdddddddd", "mov %R, #%X"), FMT("10101rrr", "mov %R, a"), FMT("1010000r", "mov @%R, a"), FMT("1011000rdddddddd", "mov @%R, #%X"), FMT("11010111", "mov psw, a"), FMT("000011pp", "movd a, %P"), FMT("001111pp", "movd %P, a"), FMT("01000010", "mov a, t"), FMT("01100010", "mov t, a"), FMT("11100011", "movp3 a, @a"), FMT("10100011", "movp a, @a"), FMT("1000000r", "movx a, @%R"), FMT("1001000r", "movx @%R, a"), FMT("0100 1rrr", "orl a, %R"), FMT("0100 000r", "orl a, @%R"), FMT("0100 0011dddddddd", "orl a, #%X"), FMT("1000 1000dddddddd", "orl bus, #%X"), FMT("1000 1001dddddddd", "orl p1, #%X"), FMT("1000 1010dddddddd", "orl p2, #%X"), FMT("1000 11pp", "orld %P, a"), FMT("00000010", "outl bus, a"), FMT("001110pp", "outl %P, a"), FMT("10000011", "ret"), FMT("10010011", "retr"), FMT("11100111", "rl a"), FMT("11110111", "rlc a"), FMT("01110111", "rr a"), FMT("01100111", "rrc a"), FMT("11100101", "sel mb0"), FMT("11110101", "sel mb1"), FMT("11000101", "sel rb0"), FMT("11010101", "sel rb1"), FMT("01100101", "stop tcnt"), FMT("01000101", "strt cnt"), FMT("01010101", "strt t"), FMT("01000111", "swap a"), FMT("00101rrr", "xch a, %R"), FMT("0010000r", "xch a, @%R"), FMT("0011000r", "xchd a, @%R"), FMT("1101 0011dddddddd", "xrl a, #%X"), FMT("1101 1rrr", "xrl a, %R"), FMT("1101 000r", "xrl a, @%R"), FMT("00000000", "nop"), NULL }; #define MAX_OPS (((sizeof(Formats) / sizeof(Formats[0])) - 1) / PTRS_PER_FORMAT) typedef struct opcode { byte mask; /* instruction mask */ byte bits; /* constant bits */ char extcode; /* value that gets extension code */ const char *parse; /* how to parse bits */ const char *fmt; /* instruction format */ } M48Opcode; static M48Opcode Op[MAX_OPS+1]; static int OpInizialized = 0; static void InitDasm8039(void) { const char *p, **ops; byte mask, bits; int bit; int i; ops = Formats; i = 0; while (*ops) { p = *ops; mask = 0; bits = 0; bit = 7; while (*p && bit >= 0) { switch (*p++) { case '1': mask |= 1<<bit; bits |= 1<<bit; bit--; break; case '0': mask |= 1<<bit; bit--; break; case ' ': break; case 'b': case 'a': case 'r': case 'd': case 'p': bit --; break; default: printf("Invalid instruction encoding '%s %s'\n", ops[0],ops[1]); exit(1); } } if (bit != -1 ) { printf("not enough bits in encoding '%s %s' %d\n", ops[0],ops[1],bit); exit(1); } while (isspace(*p)) p++; if (*p) Op[i].extcode = *p; Op[i].bits = bits; Op[i].mask = mask; Op[i].fmt = ops[1]; Op[i].parse = ops[0]; ops += PTRS_PER_FORMAT; i++; } OpInizialized = 1; } int Dasm8039(char *buffer, unsigned pc) { int b, a, d, r, p; /* these can all be filled in by parsing an instruction */ int i; int op; int cnt = 1; int code, bit; const char *cp; if (!OpInizialized) InitDasm8039(); code = cpu_readop(pc); op = -1; /* no matching opcode */ for ( i = 0; i < MAX_OPS; i++) { if( (code & Op[i].mask) == Op[i].bits ) { if (op != -1) { fprintf(stderr, "Error: opcode %02X matches %d (%s) and %d (%s)\n", code,i,Op[i].fmt,op,Op[op].fmt); } op = i; } } if (op == -1) { sprintf(buffer,"db %2.2x",code); return cnt; } if (Op[op].extcode) { cnt++; code <<= 8; code |= cpu_readop_arg((pc+1)&0xffff); bit = 15; } else { bit = 7; } /* shift out operands */ cp = Op[op].parse; b = a = d = r = p = 0; while (bit >= 0) { /* printf("{%c/%d}",*cp,bit); */ switch(*cp) { case 'a': a <<=1; a |= ((code & (1<<bit)) ? 1 : 0); bit--; break; case 'b': b <<=1; b |= ((code & (1<<bit)) ? 1 : 0); bit--; break; case 'd': d <<=1; d |= ((code & (1<<bit)) ? 1 : 0); bit--; break; case 'r': r <<=1; r |= ((code & (1<<bit)) ? 1 : 0); bit--; break; case 'p': p <<=1; p |= ((code & (1<<bit)) ? 1 : 0); bit--; break; case ' ': break; case '1': case '0': bit--; break; case '\0': printf("premature end of parse string, opcode %x, bit = %d\n",code,bit); exit(1); } cp++; } /* now traverse format string */ cp = Op[op].fmt; while (*cp) { if (*cp == '%') { char num[10], *q; cp++; switch (*cp++) { case 'A': sprintf(num,"0%04XH",a); break; case 'J': sprintf(num,"0%04XH",((pc+1) & 0xf00) | a); break; case 'B': sprintf(num,"%d",b); break; case 'D': sprintf(num,"%d",d); break; case 'X': sprintf(num,"0%02XH",d); break; case 'R': sprintf(num,"r%d",r); break; case 'P': sprintf(num,"p%d",p); break; default: printf("illegal escape character in format '%s'\n",Op[op].fmt); exit(1); } q = num; while (*q) *buffer++ = *q++; *buffer = '\0'; } else { *buffer++ = *cp++; *buffer = '\0'; } } return cnt; }
Go to most recent revision | Compare with Previous | Blame | View Log