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

📄 avr.cc

📁 AVR 单片机程序设计用到的模拟器
💻 CC
字号:
/* $Id: AVR.cc,v 1.5 2000/09/24 12:57:54 pure Exp $ */#include <iostream.h>#include <stdlib.h>#include "AVR.h"#include "AVR_UART.h"AVR::AVR(unsigned ramsize, unsigned romsize, unsigned model,	 unsigned mhz) : Device(0),REG(0, 0x20, 0),RAM(0x60, ramsize - 0x60, 0),R(REG, 0, 32),W(REG, 0, 31),ROM(0, romsize, 0){	PC = SP = 0;	opcode = opcode2 = 0;	bus.attach(&REG);	bus.attach(&RAM);	bus.attach(new AVR_UART(mhz));	bus.attach(this);	this->model = model;}AVR::~AVR(){}Device* AVR::cs(unsigned addr){	if ((addr >= 0x5d) && (addr <= 0x5f)) // SP,flags	    return this;	if (addr == 0x55) // MCUCR	    return this;	return (Device*) 0;}byte AVR::readb(unsigned addr){	switch (addr) {	case 0x55: return 0; // MCUCR		case 0x5d: return SP;	case 0x5e: return SP >> 8;	case 0x5f: return alu.SREG;	}	cerr << __FILE__ << ": reading from illegal address " << hex << addr << endl;	return 0;}void AVR::writeb(unsigned addr, byte data){	switch (addr) {	case 0x55: return; // MCUCR		case 0x5d: SP = data | (SP&0xff00); return;	case 0x5e: SP = (SP&0x00ff) | (((word)data)<<8); return;	case 0x5f: alu.SREG = data; return;	}	cerr << __FILE__ << ": writing to illegal address " << hex << addr << endl;}byte AVR::in(unsigned port){	return bus.readb(port+0x20);}void AVR::out(unsigned port, byte data){	bus.writeb(port+0x20, data);}byte AVR::ld(unsigned addr){	return bus.readb(addr);	/* clk += device->waitstates(); */}void AVR::st(unsigned addr, byte data){	bus.writeb(addr, data);	/* clk += device->waitstates(); */}void AVR::push(byte data){	clk++;	st(SP, data);	SP = SP - 1;}byte AVR::pop(){	clk++;	SP = SP + 1;	return ld(SP);}void AVR::op_add(int d, int r){	R[d] = alu.add(R[d], R[r]);}void AVR::op_adc(int d, int r){	R[d] = alu.adc(R[d], R[r]);}void AVR::op_adiw(int d, int k){	W[d] = alu.addw(W[d], k);	clk++;}void AVR::op_sub(int d, int r){	R[d] = alu.sub(R[d], R[r]);}void AVR::op_subi(int d, int k){	R[d] = alu.sub(R[d], k);}void AVR::op_sbc(int d, int r){	R[d] = alu.sbc(R[d], R[r]);}void AVR::op_sbci(int d, int k){	R[d] = alu.sbc(R[d], k);}void AVR::op_sbiw(int d, int k){	W[d] = alu.subw(W[d], k);	clk++;}void AVR::op_and(int d, int r){	R[d] = alu.and(R[d], R[r]);}void AVR::op_andi(int d, int k){	R[d] = alu.and(R[d], k);}void AVR::op_or(int d, int r){	R[d] = alu.ora(R[d], R[r]);}void AVR::op_ori(int d, int k){	R[d] = alu.ora(R[d], k);}void AVR::op_eor(int d, int r){	R[d] = alu.eor(R[d], R[r]);}void AVR::op_com(int d){	R[d] = alu.com(R[d]);}void AVR::op_neg(int d){	R[d] = alu.neg(R[d]);}void AVR::op_inc(int d){	R[d] = alu.inc(R[d]);}void AVR::op_dec(int d){	R[d] = alu.dec(R[d]);}void AVR::op_rjmp(int k){	PC += k;	clk++;}void AVR::op_ijmp(){	PC = W[30];	clk++;}void AVR::op_jmp(int k){	PC = k;	clk++;}void AVR::op_rcall(int k){	push(PC);	push(PC >> 8);	PC += k;}void AVR::op_icall(){	push(PC);	push(PC >> 8);	PC = W[30];}void AVR::op_call(int k){	push(PC);	push(PC >> 8);	PC = k;	clk++;}void AVR::op_ret(){	PC = ((unsigned)pop()) << 8;	PC |= pop();	clk++;}void AVR::op_reti(){	alu.set(alu.I);	op_ret();}void AVR::op_cpse(int d, int r){	if (R[d] == R[r]) 	    fetch();}void AVR::op_cp(int d, int r){	alu.sub(R[d], R[r]);}void AVR::op_cpc(int d, int r){	alu.sbc(R[d], R[r]);}void AVR::op_cpi(int d, int k){	alu.sub(R[d], k);}void AVR::op_sbrs(int r, int b){	if ((R[r] & (1 << b)))	    fetch();}void AVR::op_sbrc(int r, int b){	if (!(R[r] & (1 << b)))	    fetch();}void AVR::op_sbis(int a, int b){	if ((in(a) & (1 << b)))	    fetch();}void AVR::op_sbic(int a, int b){	if (!(in(a) & (1 << b)))	    fetch();}void AVR::op_brbs(int b, int k){	if (alu.isset(1<<b))	    op_rjmp(k);}void AVR::op_brbc(int b, int k){		if (!alu.isset(1<<b))	    op_rjmp(k);}void AVR::op_mov(int d, int r){	R[d] = (byte)R[r];}void AVR::op_ldi(int d, int k){	R[d] = k;}void AVR::op_lds(int d, int k){	R[d] = ld(k);	clk++;}void AVR::op_ld(int d, int r){	R[d] = ld(W[r]);	clk++;}void AVR::op_ldd(int d, int q, int r){	R[d] = ld(W[r] + q);	clk++;}void AVR::op_ld_inc(int d, int r){	R[d] = ld(W[r]);		W[r] = W[r] + 1;	clk++;}void AVR::op_ld_dec(int d, int r){	W[r] = W[r] - 1;	R[d] = ld(W[r]);	clk++;}void AVR::op_sts(int k, int d){	st(k, R[d]);	clk++;}void AVR::op_st(int d, int r){	st(W[d], R[r]);	clk++;}void AVR::op_std(int d, int q, int r){        st(W[d] + q, R[r]);	clk++;}void AVR::op_st_inc(int d, int r){	st(W[d], R[r]);	W[d] = W[d] + 1;	clk++;}void AVR::op_st_dec(int d, int r){	W[d] = W[d] - 1;	st(W[d], R[r]);	clk++;}void AVR::op_lpm(int r){	R[r] = ROM.readb(W[30]);	clk += 2;	}void AVR::op_in(int r, int a){	R[r] = in(a);}void AVR::op_out(int a, int r){	out(a, R[r]);}void AVR::op_push(int r){	push(R[r]);}void AVR::op_pop(int r){	R[r] = pop();}void AVR::op_lsr(int r){	R[r] = alu.lsr(R[r]);}void AVR::op_ror(int r){	R[r] = alu.ror(R[r]);}void AVR::op_asr(int r){	R[r] = alu.asr(R[r]);}void AVR::op_swap(int r){	R[r] = alu.swap(R[r]);}void AVR::op_bset(int b){	alu.bset(b);}void AVR::op_bclr(int b){	alu.bclr(b);}void AVR::op_sbi(int a, int b){	out(a, in(a) | (1<<b));	clk++;}void AVR::op_cbi(int a, int b){	out(a, in(a) & ~(1<<b));	clk++;}void AVR::op_bst(int r, int b){	alu.bst(R[r], b);}void AVR::op_bld(int r, int b){	R[r] = alu.bld(R[r], b);}void AVR::op_nop(){}int AVR::dispLDD(){  	return (((opcode & 0x2000) >> 8) | ((opcode & 0x0c00) >> 7)        	| (opcode & 7));}int AVR::regPP(){  	return ((opcode & 0x0600) >> 5) | (opcode & 0xf);}int AVR::reg50(){  	return (opcode & 0x01f0) >> 4;}int AVR::reg104(){  	return (opcode & 0xf) | ((opcode & 0x0200) >> 5);}int AVR::reg40(){  	return ((opcode & 0xf0) >> 4) + 16;}int AVR::reg20w(){  	return ((opcode & 0x30) >> 4) * 2 + 24;}int AVR::lit404(){  	return ((opcode & 0xf00) >> 4) | (opcode & 0xf);}	int AVR::lit204(){  	return ((opcode & 0xc0) >> 2) | (opcode & 0xf);}int AVR::add0fff() {  	return ((int)((opcode & 0xfff) ^ 0x800) - 0x800);}int AVR::add03f8(){  	return ((int)(((opcode >> 3) & 0x7f) ^ 0x40) - 0x40);}void AVR::fetch(){	opcode = ROM.readw(PC*2);	opcode2 = 0;	PC++;        clk++;      	switch (opcode & 0xf000) {	case 0x9000:         	switch (opcode & 0x0e00) {                case 0x0000:                case 0x0200: 			switch (opcode & 0xf) {			case 0x0:                                opcode2 = ROM.readw(PC*2);				PC++;                                clk++;			}			break;	        case 0x0400:			if ((opcode & 0x020c) == 0x000c) {                                opcode2 = ROM.readw(PC*2);				PC++;                                clk++;			}		        break;		}		break;	}}void AVR::execute(){	unsigned irq_n = bus.irq();	if (irq_n != 0xffffffff) {		clk++;		if (model == ATMEGA103) 			op_jmp(irq_n * 2);		else			op_jmp(irq_n);	}	fetch();	switch (opcode & 0xf000) {	case 0x0000: {    		int d = reg50();    		int r = reg104();    		switch (opcode & 0x0c00) {      		case 0x0000:			op_nop();			return;		case 0x0400:			op_cpc(d, r);			return;		case 0x0800:			op_sbc(d, r);			return;		case 0x0c00:			op_add(d, r);			return;		}		break;	}	case 0x1000: {		int d = reg50();		int r = reg104();		switch (opcode & 0x0c00) {		case 0x0000:			op_cpse(d, r);			return;		case 0x0400:			op_cp(d, r);			return;		case 0x0800:			op_sub(d, r);			return;		case 0x0c00:			op_adc(d, r);			return;		}		break;	}	case 0x2000: {		int d = reg50();		int r = reg104();		switch (opcode & 0x0c00) {		case 0x0000:			op_and(d, r);			return;		case 0x0400:			op_eor(d, r);			return;		case 0x0800:			op_or(d, r);			return;		case 0x0c00:			op_mov(d, r);			return;		}		break;	}	case 0x3000: {		int d = reg40();		byte k = lit404();		op_cpi(d, k);		return;	}	case 0x4000: {		int d = reg40();		byte k = lit404();		op_sbci(d, k);		return;	}	case 0x5000: {		int d = reg40();		byte k = lit404();		op_subi(d, k);		return;	}	case 0x6000: {		int d = reg40();		byte k = lit404();		op_ori(d, k);		return;	}	case 0x7000: {		int d = reg40();		byte k = lit404();		op_andi(d, k);		return;	}	case 0x8000:	case 0xa000:	{		int d = reg50();		int r = (opcode & 8) ? 28 : 30;		byte q = dispLDD();		if (opcode & 0x0200)		    op_std(r, q, d);		else		    op_ldd(d, q, r);		return;	}	case 0x9000: {		switch (opcode & 0x0e00) {		case 0x0000: {			int d = reg50();			switch (opcode & 0xf) {			case 0x0:				op_lds(d, opcode2);				return;			case 0x1:				op_ld_inc(d, 30);				return;			case 0x2:				op_ld_dec(d, 30);				return;			case 0x9:				op_ld_inc(d, 28);				return;			case 0xa:				op_ld_dec(d, 28);				return;			case 0xc:				op_ld(d, 26);				return;			case 0xd:				op_ld_inc(d, 26);				return;			case 0xe:				op_ld_dec(d, 26);				return;			case 0xf:				op_pop(d);				return;			}			break;		}		case 0x0200: {			int d = reg50();			switch (opcode & 0xf) {			case 0x0:				op_sts(opcode2, d);				return;			case 0x1:				op_st_inc(30, d);				return;			case 0x2:				op_st_dec(30, d);				return;			case 0x9:				op_st_inc(28, d);				return;			case 0xa:				op_st_dec(28, d);				return;			case 0xc:				op_st(26, d);				return;			case 0xd:				op_st_inc(26, d);				return;			case 0xe:				op_st_dec(26, d);				return;			case 0xf:				op_push(d);				return;			}			break;		}		case 0x0400:			if ((opcode & 0x020c) == 0x000c) {				/* u32 k = ((opcode & 0x01f0) >> 3) | (opcode & 1); */				if (opcode & 0x0002)				    op_call(opcode2);				else				    op_jmp(opcode2);				return;			}			if ((opcode & 0x010f) == 0x0008) {				byte b = (opcode & 0x70) >> 4;				if (opcode & 0x0080)				    op_bclr(b);				else				    op_bset(b);				return;			}			if ((opcode & 0x000f) == 0x0009) {				if (opcode & 0x0100)				    op_icall();				else				    op_ijmp();				return;			}			if ((opcode & 0x010f) == 0x0108) {				if ((opcode & 0x0090) == 0x0000) {					op_ret();					return;				} 				if ((opcode & 0x0090) == 0x0010) {					op_reti();					return;				}				if ((opcode & 0x00e0) == 0x0080) {					/* sleep() */				}				if ((opcode & 0x00e0) == 0x00a0) {					/* wdr() */				}				if ((opcode & 0x00f0) == 0x00c0) {					op_lpm(0);					return;				}				if ((opcode & 0x00f0) == 0x00d0) {					/* elpm() */				}			} else {				int d = reg50();				switch (opcode & 0xf) {				case 0x0:					op_com(d);					return;				case 0x1:					op_neg(d);					return;				case 0x2:					op_swap(d);					return;				case 0x3:					op_inc(d);					return;				/* case 0x4: NULL */				case 0x5:					op_asr(d);					return;				case 0x6:					op_lsr(d);					return;				case 0x7:					op_ror(d);					return;				case 0xa:					op_dec(d);					return;				}			}			break;		case 0x0600:			if (opcode & 0x0200) {				byte k = lit204();				int r = reg20w();				if (opcode & 0x0100)				    op_sbiw(r, k);				else				    op_adiw(r, k);				return;			}			break;		case 0x0800:		case 0x0a00: {			byte a = (opcode & 0xf8) >> 3;			byte b = (opcode & 7);			switch ((opcode & 0x0300) >> 8) {			case 0x0:				op_cbi(a, b);				return;			case 0x1:				op_sbic(a, b);				return;			case 0x2:				op_sbi(a, b);				return;			case 0x3:				op_sbis(a, b);				return;			}			break;		}		}		break;	}	case 0xb000: {		int d = reg50();		byte a = regPP();		if (opcode & 0x0800)	    	    op_out(a, d);		else	    	    op_in(d, a);		return;	}	case 0xc000: {		int k = add0fff();		op_rjmp(k);		return;	}	case 0xd000: {		int k = add0fff();		op_rcall(k);		return;	}	case 0xe000: {		int d = reg40();		byte k = lit404();		op_ldi(d, k);		return;	}	case 0xf000: 		if (opcode & 0x0800) {			int d = reg50();			byte b = opcode & 7;			switch ((opcode & 0x0600) >> 9) {			case 0x0:				op_bld(d, b);				return;			case 0x1:				op_bst(d, b);				return;			case 0x2:				op_sbrc(d, b);				return;			case 0x3:				op_sbrs(d, b);				return;			}		} else {			int k = add03f8();			byte b = opcode & 7;			if ((opcode & 0xc00) == 0x000) {			    op_brbs(b, k);			} else {		    	    op_brbc(b, k);			}			return;		}		break;		}   	cerr << "Unknown opcode: " << hex << opcode << endl;}unsigned AVR::reg(int n){	return R[n];}unsigned AVR::reg(const char* name){	int ch = name[0];	switch (ch) {	case 'W': return W[24];	case 'X': return W[26];	case 'Y': return W[28];	case 'Z': return W[30];	case 'S': 		switch (name[1]) {		case 'R': return alu.SREG;		case 'P': return SP;		}		return 0;	case 'P': return PC;	case 'r':		case 'R': 		ch = atoi(name+1);		if ((ch < 0) || (ch > 31)) return 0;		return reg(ch);	}	return 0;}void AVR::reg(const char* name, unsigned value){	int ch = name[0];	switch (ch) {	case 'W': W[24] = value; return;	case 'X': W[26] = value; return;	case 'Y': W[28] = value; return;	case 'Z': W[30] = value; return;	case 'S': 		switch (name[1]) {		case 'R': alu.SREG = value; return;		case 'P': SP = value; return;		}		return;	case 'P': PC = value; return;	case 'r':			case 'R': 		ch = atoi(name+1);		if ((ch < 0) || (ch > 31)) return;		R[ch] = value;	}}

⌨️ 快捷键说明

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