/*********************************************************************
 *	compiler.c - functions for the various dsp registers. 
 *      Copyright (C) 2000 Rui Sousa 
 ********************************************************************* 
 *     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., 675 Mass Ave, Cambridge, MA 02139, 
 *     USA. 
 ********************************************************************* 
*/

#include<stdio.h>
#include "compiler.h"
extern int source_line_num;

int ip=0;

void illegal(const char *message)
{
	fprintf(stderr, "%s. line number:%d\n", message, source_line_num);
	exit(1);
}

void read_ok(int arg)
{

	if ((arg < 0x000) || (arg >= 0x400))
		illegal("adress out of range");

	if (arg > 0x021 && arg < 0x030)
	  {
	    fprintf(stderr,"0x%x  ",arg);
	  illegal("can't read from adress");
	  }
	return;
}

void write_ok(int arg)
{

	if ((arg < 0x000) || (arg >= 0x400))
		illegal("adress out of range");

	if (((arg > 0x040) && (arg < 0x050)) || (arg < 0x20))
	        illegal("can't write to adress");
	return;

}

//void OP(op, z, w, x, y)


//I had to reverse the arguments
void OP(int op, int y,int x,int w,int z)
{
	int  w0, w1;

	if (ip > 0x200)
		illegal("to many instructions");
	if (op >= 0x10 || op < 0x00)
		illegal("illegal op code");

	write_ok(z);
	read_ok(w);
	read_ok(x);
	read_ok(y);

	w0 = (x << 10) | y;
	w1 = (op << 20) | (z << 10) | w;
	dsp_code[ip * 2] = w0;
	dsp_code[ip * 2 + 1] = w1;
	ip++;

}



void RESET(void)
{
	int t = ip;

	ip = 0;
	while (ip < 0x200)
		OP(6, C_0, C_0, C_0, C_0);

	ip = t;
	return;
}


