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

📄 fab_custom.c

📁 树大根深三棱尽所标杆ssfsfsa fdsafs
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * $Id: fab_custom.c,v 1.2 1998/07/28 23:08:48 mcculley Exp $ * * File:        fab.c * * Author:      Max Okumoto <okumoto@ucsd.edu> * * Abstract:    This program generates the code that simulates the dragonball's *              intelligent peripheral modules and system interface logic. * * Note:        All the registers have specified size and all simulated code *              should access the registers appropriately.  However we can't *              control what pilot programers do :-)  In these cases the *              *_get_xxx() and *_put_xxx() have to be written. * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  *****************************************************************************/#include <stdio.h>#include <stdarg.h>#include <stdlib.h>#include "../config.h"struct Fab;struct Reg;typedef void Reg_Op(struct Fab *, const struct Reg *);typedef struct Fab {	FILE	*f_c;	/* fp to generated custom.c file */	FILE	*f_h;	/* fp to generated custom.h file */	int	bo;	/* byte order */#define FAB_LITTLEENDIAN	0#define FAB_BIGENDIAN		1	int	lvl;	/* indent level */} Fab;typedef const struct Reg {	char	*name;			/* name of hardware register */	int	addr;			/* address of hardware register */	int	size;			/* size of hardware register */	int	init;			/* reset value of hardware register */	struct {		Reg_Op	*get;		Reg_Op	*put;	} b;				/* byte operations */	struct {		Reg_Op	*get;		Reg_Op	*put;	} w;				/* word operations */	struct {		Reg_Op	*get;		Reg_Op	*put;	} l;				/* word operations */	char	*fields;} Reg;/*---------------------------------------------------------------------------* * Helper functions *---------------------------------------------------------------------------*//*===========================================================================* * Function:	putln * * Abstract:	This function adds indention to each line. * * Note:	No state is kept between calls, so each fmt must contain *		complete lines. *===========================================================================*/static voidputln(Fab *f, const char fmt[], ...){	const char	*p;	int		count;	char		*new_fmt;	char		*s;	va_list		ap;	va_start(ap, fmt);	/*	 * Calc the size of new_fmt string.  (fmt.len + #newlines * #lvl)	 */	count = 0;	for (p = fmt; *p != '\0'; p++) {		count += (*p == '\n') ? (1 + f->lvl) : 1;	}	new_fmt = malloc(count + 1 + f->lvl);	s = new_fmt;	/*	 * Add tab characters to the begining of each line.	 */	if (fmt[0] == '\n' && fmt[1] == '\0') {		/* do nothing */	} else {		int		i;		for (i = 0; i < f->lvl; i++) *s++ = '\t';	}	for (p = fmt; *p != '\0'; p++) {		*s++ = *p;		if (p[0] == '\n' && p[1] != '\0' && p[1] != '\n') {			int		i;			for (i = 0; i < f->lvl; i++) *s++ = '\t';		}	}	*s++ = '\0';	/*	 * Output line.	 */	vfprintf(f->f_c, new_fmt, ap);	free(new_fmt);	va_end(ap);}/*---------------------------------------------------------------------------* * Operation generators *---------------------------------------------------------------------------*//* * Generic */static voidreg_get(Fab *f, Reg *r){	putln(f,"return db_%s.x;\n", r->name);}static voidreg_put(Fab *f, Reg *r){	putln(f,"db_%s.x = value;\n", r->name);}/* * System Control */static voidscr_put(Fab *f, Reg *r){	putln(f,"db_%s.x = value & ~(value & 0xe0);\n", r->name);}/* * Chip Select */static voidcsa1_put(Fab *f, Reg *r){	reg_put(f, r);	putln(f,"sram_protect = (value & 0x0008) != 0;\n", r->name);}/* * Phase Locked Loop */static voidpllfsr_get(Fab *f, Reg *r){	putln(f,"db_%s.anon.CLK32 ^= 1;\n", r->name);	reg_get(f, r);}/* * Interrupt controller */static voidimr_get_xxx(Fab *f, Reg *r){	putln(f,"return db_%s.x >> 16;\n", r->name);	f->lvl -= 2;	putln(f,"	case %s + 2:\n", r->name);	f->lvl += 2;	putln(f,"return db_%s.x;\n", r->name);}static voidimr_put(Fab *f, Reg *r){	reg_put(f, r);	putln(f,"updateisr();\n", r->name);}static voidimr_put_xxx(Fab *f, Reg *r){	putln(f,"db_%s.x &= 0x0000ffff;\n", r->name);	putln(f,"db_%s.x |= value << 16;\n", r->name);	putln(f,"updateisr();\n", r->name);	putln(f,"break;\n");	f->lvl -= 2;	putln(f,"	case %s + 2:\n", r->name);	f->lvl += 2;	putln(f,"db_%s.x &= 0xffff0000;\n", r->name);	putln(f,"db_%s.x |= value;\n", r->name);	putln(f,"updateisr();\n", r->name);}static voidiwr_get_xxx(Fab *f, Reg *r){	putln(f,"return db_%s.x >> 16;\n", r->name);	f->lvl -= 2;	putln(f,"	case %s + 2:\n", r->name);	f->lvl += 2;	putln(f,"return db_%s.x;\n", r->name);}static voidiwr_put_xxx(Fab *f, Reg *r){	putln(f,"db_%s.x &= 0x0000ffff;\n", r->name);	putln(f,"db_%s.x |= value << 16;\n", r->name);	putln(f,"break;\n");	f->lvl -= 2;	putln(f,"	case %s + 2:\n", r->name);	f->lvl += 2;	putln(f,"db_%s.x &= 0xffff0000;\n", r->name);	putln(f,"db_%s.x |= value;\n", r->name);}static voidisr_get_xxx(Fab *f, Reg *r){	putln(f,"return db_%s.x >> 16;\n", r->name);	f->lvl -= 2;	putln(f,"	case %s + 2:\n", r->name);	f->lvl += 2;	putln(f,"return db_%s.x;\n", r->name);}static voidisr_put(Fab *f, Reg *r){	putln(f,"if (db_ICR.anon.ET1 && (value & 0x00010000)) {\n"		"	db_IPR.anon.IRQ1 = 0;\n"		"	updateisr();\n"		"}\n"		"if (db_ICR.anon.ET2 && (value & 0x00020000)) {\n"		"	db_IPR.anon.IRQ2 = 0;\n"		"	updateisr();\n"		"}\n"		"if (db_ICR.anon.ET3 && (value & 0x00040000)) {\n"		"	db_IPR.anon.IRQ3 = 0;\n"		"	updateisr();\n"		"}\n"		"if (db_ICR.anon.ET6 && (value & 0x00080000)) {\n"		"	db_IPR.anon.IRQ6 = 0;\n"		"	updateisr();\n"		"}\n"		"if (value & 0x00800000) {\n"		"	db_IPR.anon.IRQ7 = 0;\n"		"	updateisr();\n"		"}\n");}static voidisr_put_xxx(Fab *f, Reg *r){	putln(f,"if (db_ICR.anon.ET1 && (value & 0x0001)) {\n"		"	db_IPR.anon.IRQ1 = 0;\n"		"	updateisr();\n"		"}\n"		"if (db_ICR.anon.ET2 && (value & 0x0002)) {\n"		"	db_IPR.anon.IRQ2 = 0;\n"		"	updateisr();\n"		"}\n"		"if (db_ICR.anon.ET3 && (value & 0x0004)) {\n"		"	db_IPR.anon.IRQ3 = 0;\n"		"	updateisr();\n"		"}\n"		"if (db_ICR.anon.ET6 && (value & 0x0008)) {\n"		"	db_IPR.anon.IRQ6 = 0;\n"		"	updateisr();\n"		"}\n"		"if (value & 0x0080) {\n"		"	db_IPR.anon.IRQ7 = 0;\n"		"	updateisr();\n"		"}\n");	putln(f,"break;\n");	f->lvl -= 2;	putln(f,"	case %s + 2:\n", r->name);	f->lvl += 2;	putln(f,"/* updateisr(); */\n");}static voidipr_get(Fab *f, Reg *r){	putln(f,"db_%s.anon.PEN = CustShptr->pen;\n", r->name);	reg_get(f, r);}static voidipr_get_xxx(Fab *f, Reg *r){	putln(f,"db_%s.anon.PEN = CustShptr->pen;\n", r->name);	putln(f,"return db_%s.x >> 16;\n", r->name);#if CHECKME	f->lvl -= 2;	putln(f,"	case %s + 2:\n", r->name);	f->lvl += 2;	putln(f,"db_%s.anon.PEN = CustShptr->pen;\n", r->name);	putln(f,"return db_%s.x;\n", r->name);#endif}static voidipr_put(Fab *f, Reg *r){	putln(f,"/* do nothing */\n", r->name);}/* * Parallel IO */static voidpcdata_get(Fab *f, Reg *r){	putln(f,"db_%s.anon.NMI = 1;	/* who knows, this makes the power on key work */\n", r->name);	reg_get(f, r);}static voidpddata_put(Fab *f, Reg *r){	putln(f,"db_PDDATA_edge &= ~value;\n"		"db_IPR.anon.PEN = CustShptr->pen;\n"		"db_IPR.x = (db_IPR.x & 0xffff00ff) |\n"		"	((((db_PDDATA_edge & db_PDIRQEDGE.x) |\n"		"	(db_PDDATA.x & ~db_PDIRQEDGE.x)) & db_PDIRQEN.x) << 8);\n"		"updateisr();\n");}static voidpdirqen_put(Fab *f, Reg *r){	reg_put(f, r);	putln(f,"db_IPR.anon.PEN = CustShptr->pen;\n"		"db_IPR.x = (db_IPR.x & 0xffff00ff) |\n"		"	((((db_PDDATA_edge & db_PDIRQEDGE.x) |\n"		"	(db_PDDATA.x & ~db_PDIRQEDGE.x)) & db_PDIRQEN.x) << 8);\n"		"updateisr();\n");}static voidpgdata_put(Fab *f, Reg *r){	reg_put(f, r);	putln(f,"CustShptr->Backlight = (value & 0x80);\n");}/* * Pulse Width Modulator */static voidpwmc_get_xxx(Fab *f, Reg *r){	putln(f,"return db_%s.x >> 8;\n", r->name);	f->lvl -= 2;	putln(f,"	case %s + 1:\n", r->name);	f->lvl += 2;	putln(f,"return db_%s.x;\n", r->name);}static voidpwmc_put_xxx(Fab *f, Reg *r){	putln(f,"db_%s.x &= 0x00ff;\n", r->name);	putln(f,"db_%s.x |= value << 8;\n", r->name);	putln(f,"break;\n");	f->lvl -= 2;	putln(f,"	case %s + 1:\n", r->name);	f->lvl += 2;	putln(f,"db_%s.x &= 0xff00;\n", r->name);	putln(f,"db_%s.x |= value;\n", r->name);}/* * Timer */static voidtstat1_get(Fab *f, Reg *r){	putln(f,"db_TCN1.anon.COUNT += 16;\n"		"if (db_TCN1.anon.COUNT - db_TCMP1.anon.COMPARE < 16) {\n"		"	db_TSTAT1.anon.COMP = 1;\n"		"	if (db_TCTL1.anon.FRR == 0) {\n"		"		db_TCN1.anon.COUNT = 0;\n"		"	}\n"		"}\n"		"db_TSTAT1_lastseen |= db_TSTAT1.x;\n");	reg_get(f, r);}static voidtstat1_put(Fab *f, Reg *r){	putln(f,"db_TSTAT1.x = db_TSTAT1.x & (value | ~db_TSTAT1_lastseen);\n"		"db_TSTAT1_lastseen = 0;\n"		"if (db_TSTAT1.anon.COMP == 0) {\n"		"	db_IPR.anon.TMR1 = 0;\n"		"	updateisr();\n"		"}\n");}static voidtstat2_get(Fab *f, Reg *r){	putln(f,"db_TSTAT2_lastseen |= db_TSTAT2.x;\n");	reg_get(f, r);}static voidtstat2_put(Fab *f, Reg *r){	putln(f,"db_TSTAT2.x = db_TSTAT2.x & (value | ~db_TSTAT2_lastseen);\n"		"db_TSTAT2_lastseen = 0;\n"		"if (db_TSTAT2.anon.COMP == 0) {\n"		"	db_IPR.anon.TMR2 = 0;\n"		"	updateisr();\n"		"}\n");}/* * Watchdog */static voidwcn_put(Fab *f, Reg *r){	putln(f,"db_WCN.x = 0;\n");}/* * Serial Peripheral Interface Slave *//*

⌨️ 快捷键说明

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