/* pic14.c  - pic 14bit core routines	*/
/* version 0.1				*/
/* (c) I.King 1994			*/

#include <stdio.h>

extern char istr[40];

void paramlessop14(char *);
void byteop14(char *, unsigned char);
void bitop14(char *, unsigned int);
void literalop14(char *, unsigned char);
void gotoop14(char *, unsigned int);
void justregop14(char *, unsigned char);
void disasm14(unsigned int);

void paramlessop14(char *opname)
{
	sprintf(istr,"%s",opname);
}

void byteop14(char *opname, unsigned char bits0to7)
{
	int f;
	int d;

	f = bits0to7 & 0x7f;
	d = ((int)bits0to7 & 0x80) >> 7;
	sprintf(istr,"%s\t0x%02x , %d",opname, f, d);
}

void bitop14(char *opname, unsigned int bits0to9)
{
	int f;
	int b;

	f = bits0to9 & 0x007f;
	b = ((int)bits0to9 & 0x03ff) >> 7;
	sprintf(istr,"%s\t0x%02x , 0x%x",opname, f, b);
}

void literalop14(char *opname, unsigned char bits0to7)
{
	sprintf(istr,"%s\t0x%02x", opname, bits0to7);
}

void gotoop14(char *opname, unsigned int value)
{
	sprintf(istr,"%s\t0x%03x",opname, value & 0x07ff);
}

void justregop14(char *opname, unsigned char value)
{
	sprintf(istr,"%s\t0x%02x",opname, value & 0x7f);
}

void disasm14(unsigned int inst)
{
	unsigned char hinibble;
	unsigned char topnibble;
	unsigned char midnibble;
	unsigned char lownibble;
	unsigned char bbyte;
	unsigned char bits6and7;
	unsigned char bits10and11;

	hinibble  = (inst & 0x3000) >> 12;
	topnibble = (inst & 0x0f00) >> 8;
	midnibble = (inst & 0x00f0) >> 4;
	lownibble = (inst & 0x000f);
	bbyte	  = (inst & 0x00ff);
	bits6and7 = (unsigned char)((int) (bbyte & 0xc0) >> 6);
	bits10and11=(unsigned char)((int) (inst & 0x0c00) >> 10);

	switch(hinibble)
	{
		case 0x00:	switch(topnibble)
				{
					case 0x00:	if (bbyte & 0x80)
								justregop14("movwf", bbyte);
							else
								switch(bbyte)
								{
									case 0x00:
									case 0x20:
									case 0x40:
									case 0x60:	paramlessop14("nop");	break;
									case 0x64:	paramlessop14("clrwdt");break;
									case 0x09:	paramlessop14("retfie");break;
									case 0x08:	paramlessop14("return");break;
									case 0x63:	paramlessop14("sleep");	break;
									case 0x62:	paramlessop14("option");break;
									default:	if ((bbyte & 0xf8) == 0x60)
												justregop14("tris", bbyte & 0x07);
											else
												paramlessop14("Illegal Op");
											break;
								}
							break;

					case 0x01:	if (bbyte & 0x80)
								justregop14("clrf", bbyte);
							else
								paramlessop14("clrw");
							break;
					case 0x02:	byteop14("subwf", bbyte);	break;
					case 0x03:	byteop14("decf", bbyte);	break;
					case 0x04:	byteop14("iorwf", bbyte);	break;
					case 0x05:	byteop14("andwf", bbyte);	break;
					case 0x06:	byteop14("xorwf", bbyte);	break;
					case 0x07:	byteop14("addwf", bbyte);	break;
					case 0x08:	byteop14("movf", bbyte);	break;
					case 0x09:	byteop14("comf", bbyte);	break;
					case 0x0a:	byteop14("incf", bbyte);	break;
					case 0x0b:	byteop14("decfsz", bbyte);	break;
					case 0x0c:	byteop14("rrf", bbyte);		break;
					case 0x0d:	byteop14("rlf", bbyte);		break;
					case 0x0e:	byteop14("swapf", bbyte);	break;
					case 0x0f:	byteop14("incfsz", bbyte);	break;
				}
				break;

		case 0x01:	switch(bits10and11)
				{
					case 0x00:	bitop14("bcf", inst & 0x03ff);	break;
					case 0x01:	bitop14("bsf", inst & 0x03ff);	break;
					case 0x02:	bitop14("btfsc", inst & 0x03ff);break;
					case 0x03:	bitop14("btfss", inst & 0x03ff);break;
				}
				break;

		case 0x02:	if(inst & 0x0800)
					gotoop14("goto", inst);
				else
					gotoop14("call", inst);
				break;

		case 0x03:	switch(topnibble)
				{
					case 0x00:	
					case 0x01:	
					case 0x02:	
					case 0x03:	literalop14("movlw", bbyte);	break;
					case 0x04:	
					case 0x05:	
					case 0x06:	
					case 0x07:	literalop14("retlw", bbyte);	break;
					case 0x08:	literalop14("iorlw", bbyte);	break;
					case 0x09:	literalop14("andlw", bbyte);	break;
					case 0x0a:	literalop14("xorlw", bbyte);	break;
					case 0x0b:	paramlessop14("Illegal Op");	break;
					case 0x0c:	
					case 0x0d:	literalop14("sublw", bbyte);	break;
					case 0x0e:	
					case 0x0f:	literalop14("addlw", bbyte);	break;
				}
				break;
	
	}
}


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