rees@apollo.UUCP (07/10/84)
# The rest of this file is a shell script which will extract: # Readme dis.c distab.c echo x - Readme cat >Readme <<'Godfather_Of_Soul' This is an el-cheapo Z-80 disassembler, written in C. I wrote it myself. No comments - tough. It expects to see an input file containing records of the form <start_adr> <count> <bytes> where <start_adr> and <count> are two byte integers, least significant first, and there are <count> bytes of data. There can be an arbitrary number of these records. There is some cruft in here for TRS-80 start addresses, in getbyte(). You can probably ignore it, but may want to take it out. If you give it a "-a" flag, it produces output suitable for input to a Z-80 assembler. Some of the Z-80 instructions are not supported. A special prize for anyone who adds these. Let me know if you find any use for this. Godfather_Of_Soul echo x - dis.c cat >dis.c <<'Godfather_Of_Soul' #include <stdio.h> extern struct optab { short op_mask, op_val; char *op_op; } optab[], toptab[], ddoptab[], edoptab[], fdoptab[]; struct optab *xopt[] = { toptab, ddoptab, edoptab, fdoptab, }; char *f1_op[] = { "add\ta,", "adc\ta,", "sub\t", "sbc\ta,", "and\t", "xor\t", "or\t", "cp\t" }; char *rnam[] = { "b", "c", "d", "e", "h", "l", "(hl)", "a" }; char *ssnam[] = { "bc", "de", "hl", "sp" }; char *qqnam[] = { "bc", "de", "hl", "af" }; char *cctab[] = { "nz", "z", "nc", "c", "po", "pe", "p", "m" }; int adr; char text[64]; int hexcol; int startadr= -1; int aflg; main(ac,av) int ac; char *av[]; { FILE *in; int c,i; int f0,f1,f2; struct optab *opp; char sbuf[32]; while (ac > 1 && av[1][0] == '-') { switch (av[1][1]) { case 'a': aflg = 1; break; } ac--; av++; } if (ac > 1) { if ((in = fopen(av[1], "r")) == NULL) { perror(av[1]); exit(1); } } else in = stdin; while ((c = getbyte(in)) != EOF) { if (aflg) strcpy(text, "\t"); else { sprintf(text, "%.4x \t", adr-1); hexcol = 5; addhex(c); } docode(c, optab, in, text); printf("%s\n", text); } if (!aflg) printf("%.4x ", adr); printf("\tend", adr); if (startadr != -1) { sphexno(sbuf, "\t%s", startadr); printf(sbuf); } printf("\n"); exit(0); } docode(c, opp, in, text) int c; struct optab *opp; FILE *in; char *text; { for (; opp->op_mask != 0; opp++) if ((c&opp->op_mask) == opp->op_val) break; expand(c, opp->op_op, in, text); } expand(c, op, in, text) int c; char *op, *text; FILE *in; { int i,j; char *s,sbuf[32]; for (s=op; *s; s++) { sbuf[0] = '\0'; switch (*s) { case 'B': i = getbyte(in); addhex(i); sphexno(sbuf, "%s", i); break; case '-': /* Relative jump */ i = getbyte(in); addhex(i); if (i > 127) i -= 256; i += adr; sphexno(sbuf, "%s", i); break; case 'W': addhex(i = getbyte(in)); addhex(j = getbyte(in)); i = i | (j << 8); sphexno(sbuf, "%s", i); break; case 'S': sprintf(sbuf, "%s", ssnam[(c>>4)&0x3]); break; case 'Q': sprintf(sbuf, "%s", qqnam[(c>>4)&0x3]); break; case 'P': sprintf(sbuf, "%s", rnam[(c>>3)&0x7]); break; case 'R': sprintf(sbuf, "%s", rnam[c&0x7]); break; case 'F': sprintf(sbuf, "%s", f1_op[(c>>3)&0x7]); break; case 'T': sprintf(sbuf, "%d", (c>>3)&0x7); break; case 'X': c = getbyte(in); addhex(c); docode(c, xopt[*(++s)-'0'], in, text); break; case 'K': strcpy(sbuf, (c&0x8) ? "d" : "i"); if (c & 0x10) strcat(sbuf, "r"); break; case 'C': sprintf(sbuf, "%s", cctab[(c>>3)&07]); break; default: sbuf[0] = *s; sbuf[1] = '\0'; break; } strcat(text, sbuf); } } addhex(x) int x; { if (aflg) return; addnib(x >> 4); addnib(x & 0xf); } addnib(x) int x; { x += '0'; if (x > '9') x += 'a' - '9' - 1; text[hexcol++] = x; } getbyte(f) FILE *f; { static int count; int i,oadr; char sbuf[32]; while (count == 0) { oadr = adr; if ((i = getint(f)) == EOF) return(EOF); adr = i; count = getint(f); if (adr == 0x40df && count == 2) { if ((startadr = getint(f)) == EOF) return(EOF); count = 0; adr = oadr; } else if (adr != oadr) { sphexno(sbuf, "%s", adr); if (!aflg) printf("%.4x ", oadr); printf("\torg\t%s\n", sbuf); } } adr++; count--; if ((i = getc(f)) == EOF) { printf("Premature EOF\n"); exit(1); } return(i); } getint(f) FILE *f; { int c,i; i = getc(f); if ((c = getc(f)) == EOF) return(EOF); else return(i | (c << 8)); } sphexno(s, sform, n) char *s, *sform; int n; { char sbuf[32], *xform; if (n < 0 || n > 0xffff) { fprintf(stderr, "sphexno(%d)\n", n); exit(1); } if (n <= 9) xform = "%d"; else if ((n > 0x10 && n <= 0x9f) || (n > 0x100 && n <= 0x9ff) || (n > 0x1000 && n <= 0x9fff)) xform = "%xh"; else xform = "0%xh"; sprintf(sbuf, xform, n); sprintf(s, sform, sbuf); } Godfather_Of_Soul echo x - distab.c cat >distab.c <<'Godfather_Of_Soul' struct optab { short op_mask, op_val; char *op_op; }; struct optab optab[] = { 0xff, 0, "nop", 0xc0, 0x40, "ld\tP,R", 0xc0, 0x80, "FR", 0xc7, 0x04, "inc\tP", 0xc7, 0x05, "dec\tP", 0xc7, 0x06, "ld\tP,B", 0xc7, 0xc0, "ret\tC", 0xc7, 0xc2, "jp\tC,W", 0xc7, 0xc4, "call\tC,W", 0xc7, 0xc6, "FB", 0xc7, 0xc7, "rst\tT", 0xcf, 0x01, "ld\tS,W", 0xef, 0x02, "ld\t(S),a", 0xef, 0x0a, "ld\ta,(S)", 0xcf, 0x03, "inc\tS", 0xcf, 0x09, "add\thl,S", 0xcf, 0x0b, "dec\tS", 0xff, 0x7, "rlca", 0xff, 0x8, "ex\taf,af'", 0xff, 0x0f, "rrca", 0xff, 0x10, "djnz\t-", 0xff, 0x17, "rla", 0xff, 0x18, "jr\t-", 0xff, 0x1f, "rra", 0xff, 0x20, "jr\tnz,-", 0xff, 0x27, "daa", 0xff, 0x28, "jr\tz,-", 0xff, 0x2f, "cpl", 0xff, 0x30, "jr\tnc,-", 0xff, 0x37, "scf", 0xff, 0x38, "jr\tc,-", 0xff, 0x22, "ld\t(W),hl", 0xff, 0x2a, "ld\thl,(W)", 0xff, 0x32, "ld\t(W),a", 0xff, 0x3a, "ld\ta,(W)", 0xff, 0x3f, "ccf", 0xcf, 0xc1, "pop\tQ", 0xff, 0xc3, "jp\tW", 0xcf, 0xc5, "push\tQ", 0xff, 0xc9, "ret", 0xff, 0xcb, "X0", 0xff, 0xcd, "call\tW", 0xff, 0xd3, "out\t(B),a", 0xff, 0xd9, "exx", 0xff, 0xdb, "in\ta,(B)", /* 0xff, 0xdd, "X1", */ 0xff, 0xe3, "ex\t(sp),hl", 0xff, 0xe9, "jp\t(hl)", 0xff, 0xeb, "ex\tde,hl", 0xff, 0xed, "X2", 0xff, 0xf3, "di", 0xff, 0xfb, "ei", /* 0xff, 0xfd, "X3", */ 0xff, 0xf9, "ld\tsp,hl", 0, 0, "???", }; struct optab toptab[] = { 0xf8, 0, "rlc\tR", 0xf8, 0x8, "rrc\tR", 0xf8, 0x10, "rl\tR", 0xf8, 0x18, "rr\tR", 0xf8, 0x20, "sla\tR", 0xf8, 0x28, "sra\tR", 0xf8, 0x38, "srl\tR", 0xc0, 0x40, "bit\tT,R", 0xc0, 0x80, "res\tT,R", 0xc0, 0xc0, "set\tT,R", 0, 0, "???", }; struct optab ddoptab[] = { 0, 0, "???", }; struct optab edoptab[] = { 0xcf, 0x42, "sbc\thl,S", 0xcf, 0x43, "ld\t(W),S", 0xcf, 0x4a, "adc\thl,S", 0xcf, 0x4b, "ld\tS,(W)", 0xe7, 0xa0, "ldK", 0xe7, 0xa1, "cpK", 0xe7, 0xa2, "inK", 0xff, 0x2b, "dec\tix", 0xff, 0x35, "dec\t(ix+B)", 0xff, 0x44, "neg", 0xff, 0x46, "im\t0", 0xff, 0x4b, "ld\tbc,(W)", 0xff, 0x4d, "reti", 0xff, 0x56, "im\t1", 0xff, 0x5b, "ld\tde,(W)", 0xff, 0x66, "im\t2", 0xff, 0x67, "rrd", 0xff, 0x6f, "rld", 0xff, 0x73, "ld\t(W),sp", 0xff, 0x7b, "ld\tsp,(W)", 0, 0, "???", }; struct optab fdoptab[] = { 0, 0, "???", }; Godfather_Of_Soul