/* emit.c - emit an assembled address	*/
/* Copyright (c) 1994 Ian King		*/

#include <stdio.h>
#include "emit.h"

extern FILE *outputfile;
extern yyerror();

static int memory[MAX_PIC_SIZE];
static int maxaddr = -1;
static int minaddr = MAX_PIC_SIZE+1;
static unsigned char checksum;

void initemit()
{
	int i;

	for(i=0;i<MAX_PIC_SIZE;i++)
		memory[i] = DEFAULT_EMPTY_MEM;
}

void emit(int addr, int data)
{
	if (addr > MAX_PIC_SIZE)
	{
		yyerror("Illegal address (too big) used");
		exit(1);
	}

	if (addr < 0)
	{
		yyerror("Illegal address (too small) used");
		exit(1);
	}

	memory[addr] = data;

	if (addr > maxaddr)
		maxaddr = addr;

	if (addr < minaddr)
		minaddr = addr;
}

void ophex(int val, FILE *file)
{
	int chop;

	chop = val & 0xff;		/* make sure only byte output */
	fprintf(file,"%02X",chop);	/* output in uppercase hex    */
	checksum += chop;		/* update checksum            */
}

void writeihex16(int start, int end, FILE *file)
{
	int current;
	int numinthisline;
	int i;
	int addr;

	current = start;

	while(current < end)
	{
		checksum = 0;
		numinthisline = end - current;

		if (numinthisline > 8)
			numinthisline = 8;

		fputc(':',file);
		ophex(numinthisline*2, file);

		addr = current*2;	/* don't ya just lurve intel hex16 */
		ophex(addr>>8, file);	/* hi addr */
		ophex(addr, file);	/* lo addr */
		ophex(0, file);

		for(i=0;i<numinthisline;i++)
		{
			ophex(memory[current+i], file);		/* lo byte */
			ophex(memory[current+i]>>8, file);	/* hi byte */
		}

		ophex(0-checksum, file);
                fputc('\n', file);
		current += numinthisline;
	}

	fprintf(file,":00000001FF\n");
}

void outputmemory(int format, FILE *opfile)
{
	int i;

	switch(format)
	{
		case ASMRAW:	for(i=minaddr; i<maxaddr; i++)
					fprintf(opfile,"0x%04x = 0x%04x\n", i, memory[i]);
				break;

		case ASMIHX16:	writeihex16(minaddr, maxaddr+1, opfile);
				break;

		default:	yyerror("Illegal output format");
				break;
	}
}

/* ... The End ... */

