
/*
	GIER simulator - Print core as  print .

	(C) Copyright 2001-2018 by Mogens Kjaer


   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "GIER.h"

#define MARKa ONE40
#define MARKb ONE41
#define MARKc ONE40_41
#define MARKS ONE40_41

static GIERword Tromle[960*40*10],Ferrit[1024],c;

char *opcodes[]=
  {"QQ", "ZQ", "AR", "SR", "AN", "SN", "AC", "SC",
   "MB", "AB", "MT", "MK", "ML", "DK", "DL", "NK",
   "NL", "HR", "TL", "CK", "CL", "GR", "GA", "GT",
   "TK", "CA", "GM", "PM", "XR", "GI", "PS", "PP",
   "PA", "PT", "HK", "PI", "IS", "IT", "CM", "BT",
   "NS", "NT", "GP", "NC", "IL", "US", "GG", "GC",
   "PC", "BS", "HS", "VY", "LK", "SK", "GK", "VK",
   "HV", "ZJ", "SY", "LY", "HH", "GS", "ZL", "UD"};

extern unsigned char flx2a(char, int *);

static char *dumphalfword(GIERword w, int right, int cell)
{
  int fmark;
  int op,addr,addr2;
  static char result[40];
  char relative[40];

  fmark = w&ONE41;
  if(right) w = w<<10;

  op=(w&ONE20_25)>>SHIFT25;
  addr=(w&ONE0_9)>>SHIFT9;

  if(((w&ONE28_29)!=0) && (addr>511)) addr=addr-1024;
  relative[0] = '\0';
  if((w&ONE28_29)==ONE28)
  {
    addr2 = (cell+addr)%1024;
    sprintf(relative," [%d] ",addr2);
  }
  sprintf(result, "%s%s%s %s%s%s%s%d%s%s",
      opcodes[op],
      (w&ONE26)?"S":"",
      fmark?"F":"",
      (w&ONE27)?"(":"",
      ((w&ONE28_29)==ONE28)?"r":"",
      ((w&ONE28_29)==ONE29)?"s":"",
      ((w&ONE28_29)==ONE28_29)?"p":"",
      addr,
      relative,
      (w&ONE27)?")":"");
  return result;
}

void dumpword(FILE *fd, GIERword f, int cell)
{
  int i;
  int td;

  if(f & ONE40)
  {
    fprintf(fd, "%s, ", dumphalfword(f, 0, cell));
    fprintf(fd, "%s", dumphalfword(f, 1, cell));
  }
  else
  {
    td = (f&ONE10_19)>>SHIFT19;
    fprintf(fd, "%s ", dumphalfword(f, 0, cell));
    if(td)
    {
      if(td>511)
	fprintf(fd, "t%d ", td-1024);
      else
	fprintf(fd, "t+%d ", td);
    }
    if(f&ONE30) fprintf(fd, "X");
    if(f&ONE31) fprintf(fd, "V");
    if(f&ONE32) fprintf(fd, "D");
    if(f&ONE33_39)
    {
      fprintf(fd, " ");
      switch((f&ONE33_34)>>SHIFT34)
      {
      case 0:
	fprintf(fd, "I");
	break;
      case 1:
	fprintf(fd, "M");
	break;
      case 2:
	fprintf(fd, "N");
	break;
      case 3:
	fprintf(fd, "L");
	break;
      }
      switch((f&ONE35_37)>>SHIFT37)
      {
      case 0:
	break;
      case 1:
	fprintf(fd, "K");
	break;
      case 2:
	fprintf(fd, "Z");
	break;
      case 3:
	fprintf(fd, "O");
	break;
      case 4:
	fprintf(fd, "T");
	break;
      case 5:
	fprintf(fd, "P");
	break;
      case 6:
	fprintf(fd, "Q");
	break;
      case 7:
	fprintf(fd, "R");
	break;
      }
      switch((f&ONE38_39)>>SHIFT39)
      {
      case 0:
	break;
      case 1:
	fprintf(fd, "B");
	break;
      case 2:
	fprintf(fd, "A");
	break;
      case 3:
	fprintf(fd, "C");
	break;
      }
    } /* Indicator */
  } /* Fullword */
}

int main(int argc, char **argv)
{
  FILE *fp;
  char buf[1024];
  char ch1,ch2;
  int uc,i,kind,s;
  char *bp,*cp;
  int track,firstcell,lastcell,firsttrack,lasttrack,cell,drummode;
  GIERword c;

  if(argc<4)
  {
    fprintf(stderr, "Usage: coreprint file.gier from to\n");
    exit(-1);
  }

  fp = fopen(argv[1], "r");

  if(fp == NULL)
  {
    fprintf(stderr, "Could not open %s for reading.\n", argv[1]);
    exit(-1);
  }

  for(i=0;i<40*960*10;i++) Tromle[i] = 0ULL;
  for(i=0;i<1024;i++) Ferrit[i] = 0ULL;

  while(1)
  {
    bp = fgets(buf, sizeof(buf), fp);
    if(bp == NULL) break;

    cp=strtok(bp, "\t\n");
    if(!cp) continue;

    if(!strncmp(cp, "Tromle[", 7))
    {
      sscanf(cp+7, "%d", &i);
      cp=strtok(0, "\t\n");
      if(i<960*40*10)
      {
#ifdef WINDOWS
	sscanf(cp, "%I64x", Tromle+i);
#else
	sscanf(cp, "%llx", Tromle+i);
#endif
      }
    }
    else if(!strncmp(cp, "Ferrit[", 7))
    {
      sscanf(cp+7, "%d", &i);
      cp=strtok(0, "\t\n");
#ifdef WINDOWS
      sscanf(cp, "%I64x", Ferrit+i);
#else
      sscanf(cp, "%llx", Ferrit+i);
#endif
    }

  }
  fclose(fp);

  firstcell=0;
  lastcell=1023;
  firsttrack=-1;
  lasttrack=-1;

  if(argc>2) firstcell=atoi(argv[2]);
  if(argc>3) lastcell=atoi(argv[3]);
  if(argc>4) firsttrack=atoi(argv[4]);
  if(argc>5) lasttrack=atoi(argv[5]);

  drummode=lasttrack!=-1;
  if(drummode)
  {
    firstcell+=firsttrack*40;
    lastcell+=lasttrack*40;
  }
  for(cell=firstcell;cell<=lastcell;cell++)
  {
    long long x;
    double f;
    int exponent;
    if(drummode)
    {
      c=Tromle[cell];
    }
    else
    {
      c=Ferrit[cell];
    }
    if( (c&ONE0) == 0)
    {
      x = (c&ONE0_39)>>SHIFT39;
    }
    else
    {
      x = ((c^ONE0_39)&ONE0_39)>>SHIFT39;
      x = -x-1;
    }
    if(drummode)
    {
      printf("%4d %4d ",cell/40,cell%40);
    }
    else
    {
      printf("%4d ",cell);
    }
    printf("%14lld ",x);
    if( (c&ONE10)==0 )
    {
      f=((double)(c&ONE10_39))/((double)ONE11);
    }
    else
    {
      f=-(((double)((-c)&ONE10_39))/((double)ONE11));
    }
    if( (c&ONE0)==0 )
    {
      exponent = (int) ((c&ONE0_9)>>SHIFT9);
    }
    else
    {
      exponent = ((int) ((c&ONE0_9)>>SHIFT9))-1024;
    }
    for(;exponent>0;exponent--) f = f*2.0;
    for(;exponent<0;exponent++) f = f*0.5;

    sprintf(buf,"%.10lg",f);
    /* printf(" %-18s ",buf); */
    sprintf(buf, "%d/%d/%d/%d",
	      (int) ((c&ONE0_9)>>SHIFT9),
	      (int) ((c&ONE10_19)>>SHIFT19),
	      (int) ((c&ONE20_29)>>SHIFT29),
	      (int) ((c&ONE30_39)>>SHIFT39));
    printf("%-19s ",buf);
    dumpword(stdout, c, cell);
    printf("\n");
  }

}
