/* bin2p - public domain by Russell Marks, 1996
 * convert Z80 M/C into a ZX81 program in .P format like this:
 * 10 REM <your code here>
 * 20 SAVE "Z"
 * 30 RAND USR 16514
 *
 * usage: bin2p input.bin output.p
 */

#include <stdio.h>


unsigned char binbuf[16384];

/* system vars from 16393 to 16508 inclusive.
 * These sample values were taken by saving a short program in the
 * format used, from xtender. Some of them are then modifed; see
 * fixsysvars() for details.
 */
unsigned char sysvars[116]={
  0x00,0x1E,0x00,0xA6,0x40,0xA7,0x40,0xBF,
  0x43,0x00,0x00,0xC0,0x43,0x93,0x40,0x00,
  0xC0,0xC0,0x43,0xC0,0x43,0x00,0x5D,0x40,
  0x00,0x02,0x00,0x00,0xFF,0xFF,0xFF,0x37,
  0x94,0x40,0x00,0x00,0x00,0x00,0x00,0x8D,
  0x0C,0x00,0x00,0x7D,0xF9,0x00,0x00,0xBC,
  0x21,0x18,0x40,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x76,0x00,0x00,0x00,0x00,
  0x00,0x00,0x85,0x00,0x00,0x00,0x84,0xA0,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00
  };

unsigned char lines20and30[]={
  0x00,0x14,0x05,0x00,0xF8,0x0B,0xBF,0x0B,
  0x76,0x00,0x1E,0x0E,0x00,0xF9,0xD4,0x1D,
  0x22,0x21,0x1D,0x20,0x7E,0x8F,0x01,0x04,
  0x00,0x00,0x76,0x76
  };



main(argc,argv)
int argc;
char **argv;
{
FILE *in,*out;
int x,y,siz;

if(argc!=3)
  {
  printf("usage: bin2p input.bin output.p\n");
  exit(1);
  }

if((in=fopen(argv[1],"rb"))==NULL)
  {
  printf("Couldn't open input file.\n");
  exit(1);
  }

if((out=fopen(argv[2],"wb"))==NULL)
  {
  printf("Couldn't open output file.\n");
  exit(1);
  }

/* read the binary */
siz=fread(binbuf,1,16384,in);

/* fix those system vars which need to be fixed */
fixsysvars(siz);

/* and write them */
fwrite(sysvars,1,116,out);

/* now we write the program */

/* first line 10 */
fprintf(out,"%c%c%c%c%c",0,10,(siz+2)%256,(siz+2)/256,0xEA); /* 0xEA = REM */

/* now the only important bit :-) */
fwrite(binbuf,siz,1,out);

/* the EOL... */
fputc(0x76,out);

/* now lines 20 and 30 */
fwrite(lines20and30,sizeof(lines20and30),1,out);

/* display file */
for(y=0;y<24;y++)
  {
  for(x=0;x<32;x++)
    fputc(0,out);
  fputc(0x76,out);
  }

/* vars and byte at E_LINE */
fputc(0x80,out); fputc(0x0B,out);

fclose(out);
fclose(in);

exit(0);
}


fixsysvars(binsiz)
int binsiz;
{
int tmp;

/* we need to do all this:
 *  D_FILE = 16514+binary_size+28
 *  DF_CC  = D_FILE+1
 *  VARS   = DF_CC+33*24
 *  E_LINE = VARS+1
 *  CH_ADD = 16514+binary_size+9
 *  STKBOT = E_LINE
 *  STKEND = E_LINE
 *  NXTLIN = CH_ADD+1
 */

#define POKE16(x,y)	*(sysvars+(x)-16393)=(y)%256,\
			*(sysvars+(x)-16392)=(y)/256
#define PEEK16(x)	((*(sysvars+(x)-16393))+\
			 256*(*(sysvars+(x)-16392)))

#define D_FILE	16396
#define DF_CC	16398
#define VARS	16400
#define E_LINE	16404
#define CH_ADD	16406
#define STKBOT	16410
#define STKEND	16412
#define NXTLIN	16425

POKE16(D_FILE,16514+binsiz+28);
POKE16(DF_CC, PEEK16(D_FILE)+1);
POKE16(VARS,  PEEK16(DF_CC)+33*24);
POKE16(E_LINE,PEEK16(VARS)+1);
POKE16(CH_ADD,16514+binsiz+9);
POKE16(STKBOT,PEEK16(E_LINE));
POKE16(STKEND,PEEK16(E_LINE));
POKE16(NXTLIN,PEEK16(CH_ADD)+1);
}
