/* 
codmpasm.c (C) 09.2000 Wojciech M. Zabolotny (wzab@ise.pw.edu.pl)
The code below is licensed under GPL (GNU PUBLIC LICENSE) version 2.0
or higher
This code is based on the source of GPSIM simulator (written by James Bowman
and Scott Dattalo)
This file implements the program modifying the MPASM for DOS generated
COD file, so  that it can be used by GPSIM

The necessary changes include:
1) change of processor name to lower case
2) translation of source files (removal of DOS filepath and change to lower
   case)

The calling syntax:
codmpasm cod_filename
*/

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include "cod.h"
FILE * codefile = NULL;
char DirBlock[COD_BLOCK_SIZE];
char NameBlock[COD_BLOCK_SIZE];

void wexit(char * fmt, ...)
{
  va_list ap;
  int d;
  va_start(ap, fmt);
  vfprintf(stderr,fmt,ap);
  exit(1);
}

void ChangeProcessorName()
{
  int len; /* Length of the name */
  int i;
  char * p;
  len=DirBlock[COD_DIR_PROCESSOR-1];
  p=&DirBlock[COD_DIR_PROCESSOR];
  printf("NameLength=%d\n"
	 "ProcessorName=%*.*s\n",
	 len,len,len,p);
  for(i=0;i<len;i++)
    {
      *p = tolower(*p);
      p++;
    }
  printf("NewProcessorName=%*.*s\n",
	 len,len,&DirBlock[COD_DIR_PROCESSOR]);
}

void ChangeFileName(char * p)
{
  /*
    This function removes the DOS filepath from the filename
    and changes the file name to the lower case
  */
  int len, newlen, i, j;
  /* find the last occurence of the "\" character */
  len = *p; /* Get the length of the filename */
  printf("File name length = %d\n",len);
  printf("Old file name %*.*s\n",len,len,&p[1]);
  for (i=len;i>0;i--)
    if (p[i] == '\\') 
      break;
  /* Having the "\" position we can remove the path */
  newlen = len - i;
  i++;
  for (j=1; i<=len ;j++, i++ )
    p[j]=tolower(p[i]);
  /* Now let's padd the filename wih zeros */
  for (;j<=len; j++)
    p[j]=0;
  /* Let's set the new length */
  *p = newlen;
  printf("New file name length = %d\n",newlen);
  printf("New file name %*.*s\n",newlen,newlen,&p[1]);
}

void WriteBlock(int pos, char * block)
{
  if(fseek(codefile,pos*COD_BLOCK_SIZE,SEEK_SET))
    wexit("Can't set write position\n");
  if(fwrite(block,COD_BLOCK_SIZE,1,codefile) != 1)
    wexit("Can't write block\n");
}

void ReadBlock(int pos, char * block)
{
  if(fseek(codefile,pos*COD_BLOCK_SIZE,SEEK_SET))
    wexit("Can't set write position\n");
  if(fread(block,COD_BLOCK_SIZE,1,codefile) != 1)
    wexit("Can't write block\n");
}

void ProcessFNBlock(int pos)
{
  int i;
  ReadBlock(pos, NameBlock);
  for(i=0; i<COD_BLOCK_SIZE; i+= COD_FILE_SIZE)
    {
      printf("Checking the name\n");
      if(NameBlock[i]==0)
	break;
      ChangeFileName(&NameBlock[i]);
    }
  WriteBlock(pos, NameBlock);
}

int main(int argc, char * argv[])
{
  int FirstFNBlock, LastFNBlock, i;
  if (argc != 2)
    wexit("The correct calling syntax: codmpasm cod_filename\n");
  codefile = fopen(argv[1],"r+");
  if(!codefile) 
    wexit("Can't open codefile %s\n",argv[1]);
  /* Let's read the directory block */
  if(fread(DirBlock,COD_BLOCK_SIZE,1,codefile) != 1)
    wexit("Can't read the directory block\n");
  /* Let's read and change the processor name */
  ChangeProcessorName();
  /* Let's change the source file name in the directory block */
  ChangeFileName(&DirBlock[COD_DIR_SOURCE-1]);
  /* Write the changed Directory Block */
  WriteBlock(0,DirBlock);
  /* Let's find the first and the last block with source file */
  FirstFNBlock = * (short int *) &DirBlock[COD_DIR_NAMTAB];
  LastFNBlock = * (short int *) &DirBlock[COD_DIR_NAMTAB + 2];
  printf("First FN block = %d, last FN block = %d\n", 
	 FirstFNBlock, LastFNBlock);
  /* And finally we change all filenames in all blocks from file name table */
  for(i=FirstFNBlock; i <= LastFNBlock ; i++)
    {
      ProcessFNBlock(i);
    }
  fclose(codefile);
  return 0;
}

 
