⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codeavr.c

📁 Outputs messages to a 2line LCD
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <stdio.h>
#include	<string.h>
#include <stdlib.h>
#include "defs.h"
#include "data.h"
#include "headers.h"


// Some predefinitions:
//
// INTSIZE is the size of an integer in the target machine
// BYTEOFF is the offset of an byte within an integer on the
//                                                                                                                                                                                                                                                                                       target machine. (ie: 8080,pdp11 = 0, 6809 = 1,
//                                                                                                                                                                                                                                                                                       360 = 3)
// This compiler assumes that an integer is the SAME length as
// a pointer - in fact, the compiler uses INTSIZE for both.

#define	INTSIZE			2			// can't really be changed for AVR
#define	BYTEOFF			1
#define	LABEL_PREFIX	"_"
#define	GLOBAL_PREFIX	"_"


#define	CHECKBYTE		0x55

static GetMemChar(int ptr, int offset);
static GetMemInt(int ptr, int offset);
static GetMemLong(int ptr, int offset);
static int CheckExtFun(char *p);

static struct t_fn 
{
	char name[20];
   int flag;
} extfunlist[] = {"structoffset",0,
   						"sextx",0,
							"sextz",0,
							"div",0,
                     "mul",0,
                     "neg",0,
                     "putstk_l",0,
                     "putstk_i_x", 0,
                     "putstk_i_z", 0,
                     "glpp",0,
                     "push_l",0,
                     "pop_l",0,
                     "sub_l",0,
                     "div_l",0,
                     "le",0,
                     "_case",0,
							"",0				};

static int CheckExtFun(char *p) {
	int i;

   i = 0;
   while (strlen(extfunlist[i].name) > 0) {
   	if (strcmp(extfunlist[i].name, p) == 0) {
      	if (extfunlist[i].flag == 0) {
      		extfunlist[i].flag = 1;
      		return FALSE;
         	}
         else
         	return TRUE;
         }
      else
      	i++;
      }
   return FALSE;
}


// print all assembler info before any code is generated

void header(void) {
	char ttt[100];

	outstr(";**********************************************************\n");
	outstr("; Small C for AVR\n;");
	FEvers();
   outstr("; Modifications and AVR code Copyright (C) by Ron Kreymborg\n");
	outstr(";**********************************************************\n");
	outstr("#include\t<avr.inc>\n");
   if (incname[0]) {
   	strcpy(ttt, "#include\t<");
      strcat(ttt, incname);
      strcat(ttt, ">\n");
   	outstr(ttt);
      }
   outstr("\tcol\t132\n");
   outstr("\tlstexp-\n");
   ot("module\t");
   outstr(module);
   nl();
   gtext();
}


void jmptable(void) {
}


void nl(void) {
	outbyte(EOL);
}


void initmac(void) {
	defmac("smallc\t1");
}


int galign(int t) {
	return(t);
}


// return size of an integer

int intsize(void) {
	return(INTSIZE);
}


// return offset of ls byte within word
// (ie: 8080 & pdp11 is 0, 6809 is 1, 360 is 3)

int byteoff(void) {
	return(BYTEOFF);
}


// Emit user label prefix

void LabPrefix(void) {
	outstr(LABEL_PREFIX);
}


void NamePrefix(void) {
	outstr(GLOBAL_PREFIX);
}


void InsertPrefix(char *t) {
	strcpy(t, GLOBAL_PREFIX);
}


// Emit internal label prefix

void internal_prefix(void) {
	outstr(GLOBAL_PREFIX);
}


// Save C machine state

void PushState(void) {
	ol("push\tr16");
   ol("in\tr16,0x3f");
   ol("push\tr16");
   ol("push\tr0");
   ol("push\tr1");
   ol("push\tr2");
   ol("push\tr3");
   ol("push\tr4");
   ol("push\tr5");
   ol("push\tr6");
   ol("push\tr7");
   ol("push\tr8");
   ol("push\tr9");
   ol("push\tr10");
   ol("push\tr11");
   ol("push\tr12");
   ol("push\tr13");
   ol("push\tr14");
   ol("push\tr15");
   ol("push\tr17");
   ol("push\tr18");
   ol("push\tr19");
   ol("push\tr20");
   ol("push\tr21");
   ol("push\tr22");
   ol("push\tr23");
   ol("push\tr24");
   ol("push\tr25");
   ol("push\tr26");
   ol("push\tr27");
   ol("push\tr28");
   ol("push\tr29");
   ol("push\tr30");
   ol("push\tr31");
}


// Restore C machine state

void PopState(void) {
	ol("pop\tr31");
	ol("pop\tr30");
	ol("pop\tr29");
	ol("pop\tr28");
	ol("pop\tr27");
	ol("pop\tr26");
	ol("pop\tr25");
	ol("pop\tr24");
	ol("pop\tr23");
	ol("pop\tr22");
	ol("pop\tr21");
	ol("pop\tr20");
	ol("pop\tr19");
	ol("pop\tr18");
	ol("pop\tr17");
	ol("pop\tr15");
	ol("pop\tr14");
	ol("pop\tr13");
	ol("pop\tr12");
	ol("pop\tr11");
	ol("pop\tr10");
	ol("pop\tr9");
	ol("pop\tr8");
	ol("pop\tr7");
	ol("pop\tr6");
	ol("pop\tr5");
	ol("pop\tr4");
	ol("pop\tr3");
	ol("pop\tr2");
   ol("pop\tr1");
   ol("pop\tr0");
	ol("pop\tr16");
   ol("out\t0x3f,r16");
   ol("pop\tr16");
   ol("reti");
}



// Output internal generated label prefix

void olprfix(void) {
	outbyte('L');
}


// Output a label definition terminator

void col(void) {
	outbyte(':');
}


// begin a comment line for the assembler

void comment(void) {
	outbyte(';');
}


// print any assembler stuff needed after all code

void trailer(void) {
	ol("end");
}


// function prologue

void prologue(void) {
	ot("ldiz\t");
   onum(softstklimit);
   outstr("\t\t; initialise for stack monitoring");
   nl();
   ot("ldi\tr20,");
   onum(CHECKBYTE);
   nl();
   ol("st\tz+,r20");
   ol("st\tz+,r20");
   if (hardstklimit != 0xffff) {
		ot("ldiz\t");
	   onum(hardstklimit);
	   nl();
	   ol("st\tz+,r20");
	   ol("st\tz+,r20");
      }
}


void CheckCode(void) {
   outstr("_ChkSoftStk");
   nl();
	ot("ldix\t");
	onum(softstklimit);
   outstr("\t\t; Stack monitoring code");
	nl();
   ol("ld\tr20,x+");
   ot("cpi\tr20,");
   onum(CHECKBYTE);
   nl();
   ol("brne\t_SoftErr");
   ol("ld\tr20,x+");
   ot("cpi\tr20,");
   onum(CHECKBYTE);
   nl();
   ol("brne\t_SoftErr");
   ol("ret");
   outstr("_SoftErr");
   nl();
   ot("in\tr20,");
   onum(StkErrPort);
   nl();
   ot("cbr\tr20,");
   onum(StkErrBit[1]);
   nl();
   ot("out\t");
   onum(StkErrPort);
   outstr(",r20\n");
   ol("rjmp\t$");
	if (hardstklimit != 0xffff) {
		outstr("_ChkHardStk");
	   nl();
		ot("ldix\t");
		onum(hardstklimit);
		nl();
	   ol("ld\tr20,x+");
	   ot("cpi\tr20,");
	   onum(CHECKBYTE);
	   nl();
	   ol("brne\t_HardErr");
	   ol("ld\tr20,x+");
	   ot("cpi\tr20,");
	   onum(CHECKBYTE);
	   nl();
	   ol("brne\t_HardErr");
	   ol("ret");
      outstr("_HardErr");
      nl();
      ot("in\tr20,");
      onum(StkErrPort);
      nl();
      ot("cbr\tr20,");
      onum(StkErrBit[0]);
      nl();
      ot("out\t");
	      onum(StkErrPort);
      outstr(",r20\n");
      ol("rjmp\t$");
      }
}

// text (code) segment

void gtext(void) {
	ol("rseg\tscode");
}


// data segment

void gdata(void) {
	ol("rseg\tsdata");
}


// provide the next available register(s)

int getregister(int type, int ident, int value) {
	int retval, bytes;

	bytes = 1;					// assume char
   if (type == CLONG)
     	bytes = 4;
   else
   if (type == CINT || type == UCINT || ident == POINTER)
		bytes = intsize();
   if (NextReg + bytes > REGS)
   	return -1;
	retval = REGBASE - NextReg;
	NextReg += bytes;
	return (retval);
}



// Restore the register boundary

void ResetRegBoundary(void) {
	NextReg = 0;
}


// Indicate register usage

void regsummary(void)
{
	outstr(";\tNext register free: r");
   onum(REGBASE-NextReg);
   nl();
}


// Output the variable symbol at scptr as an extern or a public

void ppubext(int scptr) {
	char text[50];

	if (symtab[scptr].storage == STATIC)
		return;
	ot(symtab[scptr].storage == EXTERN ? "extern\t" : "public\t");
	InsertPrefix(text);
   strcat(text, symtab[scptr].name);
	outstr(text);
	nl();
}


// Output the function symbol at scptr as an extern or a public

void fpubext(int scptr) {
	char text[50];

	if (symtab[scptr].storage == STATIC || symtab[scptr].type == STRUCTDEF)
		return;
	ot(symtab[scptr].offset == FUNCTION ? "public\t" : "extern\t");
	InsertPrefix(text);
   strcat(text, symtab[scptr].name);
	outstr(text);
	nl();
}


// Output a number

void onum(int num) {
	outdec(num);
}


// print partial instruction to get an immediate value into
// the primary register


void immed(STATE *stpt) {

   if (!(stpt->ident == FUNCTION || stpt->ident == FUNCDEF) && (stpt->storage == PUBLIC || stpt->storage == STATIC || stpt->storage == EXTERN)) {
		stkptr++;
      stack[stkptr].type = stpt->type;
      stack[stkptr].storage = stpt->storage;
      }
   else {
		ot("ldiz\t");
      InX = 0;
      }
}


void outname (char *p) {
	if (stkptr)
   	strcpy(stack[stkptr].name, p);
   else
   	outstr(p);
}


void doimmed(STATE *stpt, char *sname, int offset) {
	if (stpt->storage == AUTO) {
   	if (offset) {
		   if (InX)
	         ot("adiw\tr26,");
	      else
	      	ot("adiw\tr30,");
	      onum(offset);
	      nl();
         }
   	}
   else {
		if (InX) {
		   ot("ldi\tr31,high(");
		   outstr(stack[stkptr].name);
	      if (offset) {
	 			outstr("+");
	         onum(offset);
	         }
		   outstr(")\n");
			ot("ldi\tr30,low(");
		   outstr(stack[stkptr].name);
	      if (offset) {
	 			outstr("+");
	         onum(offset);
	         }
		   outstr(")\n");
		 	InX = 0;
	      }
	 	else {
		   ot("ldi\tr27,high(");
		   outstr(stack[stkptr].name);
	      if (offset) {
 				outstr("+");
	         onum(offset);
	         }
		   outstr(")\n");
			ot("ldi\tr26,low(");
		   outstr(stack[stkptr].name);
	      if (offset) {
	 			outstr("+");
	         onum(offset);
	         }
		   outstr(")\n");
		 	InX = 1;
   	   }
      }
}


void long_immed(void) {
   ot("ldil\t");
}


void doStructOff(int offset) {

   ot("ldi\tr25,");
   onum(offset>>8);
   ot("; ");
   onum(offset);
   nl();
   ot("ldi\tr24,");
   onum(offset & 0xff);
   nl();
   gcall("structoffset", CINT);
}


void gintoff(void) {
	ol("cli\t; interrupts off");
}


void ginton(void) {
	ol("sei\t; interrupts on");
}



// Fetch a static memory cell into the primary register.
// Do a cast if required.

void getmem(STATE *stpt) {
	int ptr;

	ptr = stpt->ptr;

	if (stkptr && (stpt->type == VOID || stpt->type == UCINT || stpt->type == CINT || (stpt->ident == POINTER && !stpt->pointing))) {
//		ol("ldd\tr0,z+1");
//     	ol("ld\tr31,z");
//		ol("mov\tr30,r0");
		if (stpt->ident == FUNCTION || stpt->ident == ARRAY) {
	      ot("ldi\tr31,high(");
	      outstr(stack[stkptr].name);
	      outstr(")\n");
	      ot("ldi\tr30,low(");
	      outstr(stack[stkptr].name);
	      outstr(")\n");
	      stkptr--;
         return;
	      }
		if (InX || (stpt->ident == FUNCPTR || (Indexing && stpt->ident != POINTER)))
			ot("lds\tr31,");
		else
			ot("lds\tr27,");
      outstr(stack[stkptr].name);
      nl();
		if (InX || stpt->ident == FUNCPTR || (Indexing && stpt->ident != POINTER)) {
  	   	ot("lds\tr30,");
     	   InX = 0;
         }
      else {
      	ot("lds\tr26,");
         InX = 1;
         }
  	   outstr(stack[stkptr].name);
      outstr("+1\n");
	   stkptr--;
		}
   else
	if (stkptr && (stpt->type == CCHAR || stpt->type == UCCHAR)) {
   	if ((CallFunction || stkptr) && stpt->ident == ARRAY) {
	      ot("ldi\tr31,high(");
	      outstr(stack[stkptr].name);
	      outstr(")\n");
	      ot("ldi\tr30,low(");
	      outstr(stack[stkptr].name);
	      outstr(")\n");
	      stkptr--;
         InX = 0;
         return;
	      }
		if (InX || stpt->ident == FUNCPTR || stpt->ident != POINTER) {
      	ot("lds\tr30,");
         InX = 0;
         }
      else {
			ot("lds\tr26,");
         InX = 1;
         }
      outstr(stack[stkptr].name);
      nl();
      if (IfFlag || Indexing)
      	sign_extend_int(stpt);
      stkptr--;
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -