📄 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(®); 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 + -