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

#include <stdio.h>

extern char istr[40];

void paramlessop12(char *);
void byteop12(char *, unsigned char);
void bitop12(char *, unsigned char);
void literalop12(char *, unsigned char);
void gotoop12(char *, unsigned int);
void justregop12(char *, unsigned char);
void disasm12(unsigned int);

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

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

	f = bits0to7 & 0x1f;
	d = ((int)bits0to7 & 0x20) >> 5;
	sprintf(istr,"%s\t0x%02x , %d",opname, f, d);
}

void bitop12(char *opname, unsigned char bits0to7)
{
	int f;
	int b;

	f = bits0to7 & 0x1f;
	b = ((int)bits0to7 & 0xe0) >> 5;
	sprintf(istr,"%s\t0x%02x , 0x%x",opname, f, b);
}

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

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

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

void disasm12(unsigned int inst)
{
	unsigned char topnibble;
	unsigned char midnibble;
	unsigned char lownibble;
	unsigned char bbyte;
	unsigned char bits6and7;

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

	switch(topnibble)
	{
		case 0x00:	if (midnibble == 0)
					switch(lownibble)
					{
						case 0x00:	paramlessop12("nop");	break;
						case 0x02:	paramlessop12("option");	break;
						case 0x03:	paramlessop12("sleep");	break;
						case 0x04:	paramlessop12("clrwdt");	break;
						default:	justregop12("tris", bbyte);break;
					}
				else
					switch(bits6and7)
					{
						case 0x00:	justregop12("movwf", bbyte);break;
						case 0x01:	if(midnibble & 0x02)
									justregop12("clrf", bbyte);
								else
									paramlessop12("clrw");
								break;
						case 0x02:	byteop12("subwf",bbyte);	break;
						case 0x03:	byteop12("decf",bbyte);	break;
					}

				break;

		case 0x01:	switch(bits6and7)
				{
					case 0x00:	byteop12("iorf",bbyte);		break;
					case 0x01:	byteop12("andwf",bbyte);	break;
					case 0x02:	byteop12("xorwf",bbyte);	break;
					case 0x03:	byteop12("addwf",bbyte);	break;
				}
				break;

		case 0x02:	switch(bits6and7)
				{
					case 0x00:	byteop12("movf", bbyte);	break;
					case 0x01:	byteop12("comf", bbyte);	break;
					case 0x02:	byteop12("incf", bbyte);	break;
					case 0x03:	byteop12("decfsz", bbyte);	break;
				}
				break;

		case 0x03:	switch(bits6and7)
				{
					case 0x00:	byteop12("rrf", bbyte);		break;
					case 0x01:	byteop12("rlf", bbyte);		break;
					case 0x02:	byteop12("swapf", bbyte);	break;
					case 0x03:	byteop12("incfsz", bbyte);	break;
				}
				break;

		case 0x04:	bitop12("bcf", bbyte);		break;
		case 0x05:	bitop12("bsf", bbyte);		break;
		case 0x06:	bitop12("btfsc", bbyte);	break;
		case 0x07:	bitop12("btfss", bbyte);	break;
		case 0x08:	literalop12("retlw", bbyte);	break;
		case 0x09:	literalop12("call", bbyte);	break;
		case 0x0a:
		case 0x0b:	gotoop12("goto", inst);		break;
		case 0x0c:	literalop12("movlw", bbyte);	break;
		case 0x0d:	literalop12("iorlw", bbyte);	break;
		case 0x0e:	literalop12("andlw", bbyte);	break;
		case 0x0f:	literalop12("xorlw", bbyte);	break;
	}
}

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