
/*
	GIER simulator - Print drum 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],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;
    if(addr2>=0 && addr2<40) 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,firsttrack,lasttrack,cell;
  GIERword c;

  if(argc<4)
  {
    fprintf(stderr, "Usage: catalogdump file.gier firsttrack lasttrack\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;

  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
      }
    }
  }
  fclose(fp);

  firsttrack=0;
  lasttrack=319;

  if(argc>2) firsttrack=atoi(argv[2]);
  if(argc>3) lasttrack=atoi(argv[3]);

  for(track=firsttrack;track<=lasttrack;track++)
  {
    printf("%sTrack: %d\n\n",(track>firsttrack?"#072":""),track);
    for(cell=0;cell<=39;cell++)
    {
      long long x;
      double f;
      int exponent;
      c=Tromle[track*40+cell];
      if( (c&ONE0) == 0)
      {
	x = (c&ONE0_39)>>SHIFT39;
      }
      else
      {
	x = ((c^ONE0_39)&ONE0_39)>>SHIFT39;
	x = -x-1;
      }
      printf("%2d ",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");
    }
  }

}
