/* unz80.c: turn a Z80 object file into asl source on stdout */
/* ats@offog.org */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "disz80.c"

int main(int argc, char **argv) {
  FILE *f;
  unsigned char mem[65536], *p, *oldp;
  char line[256];
  int l, d, labno[65536], x, labc, flag;

  for (x=0; x<65536; x++) labno[x] = mem[x] = 0;

  if ((f = fopen(argv[1],"r"))==NULL) {
    printf("Couldn't open \"%s\".\n", argv[1]);
    printf("Syntax: unz80 <object file> [<load addr in decimal>]\n");
    exit(20);
  }

  if (argc > 2) {
    d = atoi(argv[2]);
  } else {
    d = 0;
  }

  l = 0;
  while (!feof(f)) *(mem+d+(l++)) = fgetc(f);
  fclose(f);
  l--;
  printf("; unz80: loaded %d bytes from %s at %d\n", l, argv[1], d);
  printf("\n\tCPU Z80\n");
  printf("\tORG %05xh\n\n",d);

  /* first pass: find addresses that could, conceivably, be labels */
  p = mem + d;
  while ((p-(mem+d))<l) {
    labno[p-mem]=-1;
    p = (unsigned char *)disz80(p, line, p-mem);
  }

  /* give the interrupts labels */
  labno[0]=1;
  labno[0x08]=2;
  labno[0x10]=3;
  labno[0x18]=4;
  labno[0x20]=5;
  labno[0x28]=6;
  labno[0x30]=7;
  labno[0x38]=8;
  labno[0x66]=9;

  /* second pass: find addresses referred to by JR, JP, CALL */
  p = mem + d;
  labc = 10;
  while ((p-(mem+d))<l) {
    p = (unsigned char *)disz80(p, line, p-mem);
    if ( !(strncmp(line, "JR", 2)*strncmp(line, "JP", 2)
	 *strncmp(line, "CALL", 4)*strncmp(line, "DJNZ", 4))) {
      sscanf(line+strlen(line)-5, "%x", &x);
      if (labno[x]==-1) labno[x] = labc++;
    }
  }

  /* third pass: print */
  p = mem + d;
  while ((p-(mem+d))<l) {
    oldp = p;
    p = (unsigned char *)disz80(p, line, p-mem);
    flag = 0; /* flag=1 means this label needs redirecting */
    if ( !(strncmp(line, "JR", 2)*strncmp(line, "JP", 2)
	 *strncmp(line, "CALL", 4)*strncmp(line, "DJNZ", 4))) {
      sscanf(line+strlen(line)-5, "%x", &x);
      if (labno[x]&&(line[strlen(line)-1]!=')')) flag=1;
    }
    if (labno[oldp-mem]>0) {
      printf("Label%04d:",labno[oldp-mem]);
    } else {
      printf("\t");
    }
    if (flag) {
      line[strlen(line)-5] = '\0';
      printf("\t%sLabel%04d",line,labno[x]);
    } else {
      printf("\t%s",line);
    }

    if (labno[oldp-mem]>0) 
      printf("\t\t; %04x\n",oldp-mem);
    else
      printf("\n");
  }

  /* fourth pass: produce a dump file on stderr */
  p = mem+d;
  while(p<(mem+d+l)) {
    if (labno[p-mem]>0) 
      fprintf(stderr, "Label%04d:", labno[p-mem]);
    else 
      fprintf(stderr, "\t");
    fprintf(stderr, "\tDB %03xh\t\t; %04x\n", *p, p-mem);
    p++;
  }

  return 0;
}



