
/*
	GIER simulator - Dump drum

	(C) Copyright 2001-2016 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,c2;
static int track,track1,track2,cell,cell2;
static 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"};

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

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

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

  sprintf(result, "%s%s%s %s%s%s%s%d%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":"",
      ((w&ONE28_29)==0)?addr:(((addr<512)?addr:addr-1024)),
      (w&ONE27)?")":"");
  return result;
}

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


  if(f & ONE40)
  {
    fprintf(fd, "%s, ", dumphalfword(f, 0));
    fprintf(fd, "%s", dumphalfword(f, 1));
  }
  else
  {
    td = (f&ONE10_19)>>SHIFT19;
    fprintf(fd, "%s ", dumphalfword(f, 0));
    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 */
}

void main(int argc, char **argv)
{
  FILE *fp;
  char buf[1024];
  char ch1,ch2;
  char *bp,*cp;
  int i;
  int uppercase;

  if(argc<2)
  {
    fprintf(stderr, "Usage: drumdump 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);

  track1 = 0;
  track2 = 319;
  if(argc>2) track1=atoi(argv[2]);
  if(argc>3) track2=atoi(argv[3]);
  for(track=track1;track<=track2;track++)
  {
    printf("\n\nDrum track %d\n\n",track);
    for(cell=0;cell<40;cell++)
    {
      cell2 = track*40+cell;
      printf("%3d %6d ",cell,cell2);
      c=Tromle[cell2];
      printf("%14lld",(c&ONE0_39)>>SHIFT39);
      if(c&MARKa) printf("a");
      else if(c&MARKb) printf("b");
      else if(c&MARKc) printf("c");
      else printf(" ");
      printf("  %4d/%4d/%4d/%4d",
	  (c&ONE0_9)>>SHIFT9,
	  (c&ONE10_19)>>SHIFT19,
	  (c&ONE20_29)>>SHIFT29,
	  (c&ONE30_39)>>SHIFT39);
      if(c&MARKa) printf("a");
      else if(c&MARKb) printf("b");
      else if(c&MARKc) printf("c");
      else printf(" ");
      printf("    ");
      if(((c&ONE0_3)>>SHIFT3)==10 ||
	  ((c&ONE0_3)>>SHIFT3)==15)
      {
	printf("_t");
	uppercase=0;
	c2=c;
	for(i=0;i<6;i++)
	{
	  ch1 = (c2&ONE34_39)>>SHIFT39;
	  if(ch1==10) ch1=0;
	  ch2 = flx2a(ch1,&uppercase);
	  printf("%c", ch2);
	  c2 = c2>>6;
	}
	printf("  ");
      }
      else
	printf("          ");
      dumpword(stdout, c);
      printf("\n");
    }
  }
}
