📄 arith_inst.cc
字号:
t_addr r, d; t_mem R, D, result, res; d= (code&0x1f0)>>4; r= ((code&0x200)>>5)|(code&0xf); R= ram->read(r); D= ram->read(d); t_mem sreg= ram->get(SREG); result= D+R+((sreg&BIT_C)?1:0); res= result & 0xff; ram->write(d, res); if (!res) sreg|= BIT_Z; else sreg&= ~BIT_Z; if (((D&R&~res)&0x80) || ((~D&~R&res)&0x80)) sreg|= (BIT_V|BIT_S); else sreg&= ~(BIT_V|BIT_S); if (res & 0x80) { sreg|= BIT_N; sreg^= BIT_S; } else sreg&= ~BIT_N; if (result & ~0xff) sreg|= BIT_C; else sreg&= ~BIT_C; if ((R&0xf) + (D&0xf) > 15) sreg|= BIT_H; else sreg&= ~BIT_H; ram->set(SREG, sreg); return(resGO);}/* * One's Complement * COM Rd 0<=d<=31 * 1001 010d dddd 0000 *____________________________________________________________________________ */intcl_avr::com_Rd(t_mem code){ t_addr d; t_mem D, result, res; d= (code&0x1f0)>>4; D= ram->read(d); result= ~D; res= result & 0xff; ram->write(d, res); t_mem sreg= ram->get(SREG); if (!res) sreg|= BIT_Z; else sreg&= ~BIT_Z; sreg&= ~BIT_V; if (res & 0x80) sreg|= (BIT_N|BIT_S); else sreg&= ~(BIT_N|BIT_S); sreg|= BIT_C; ram->set(SREG, sreg); return(resGO);}/* * Two's Complement * NEG Rd 0<=d<=31 * 1001 010d dddd 0001 *____________________________________________________________________________ */intcl_avr::neg_Rd(t_mem code){ t_addr d; t_mem D, result, res; d= (code&0x1f0)>>4; D= ram->read(d); result= (~D)+1; res= result & 0xff; ram->write(d, res); t_mem sreg= ram->get(SREG); if (res & (~d) & 0x08) sreg|= BIT_H; else sreg&= ~BIT_H; if (res > 0x80) sreg|= BIT_S; else sreg&= ~BIT_S; if (!res) { sreg|= BIT_Z; sreg&= ~BIT_C; } else { sreg&= ~BIT_Z; sreg|= BIT_C; } if (res == 0x80) sreg|= BIT_V; else sreg&= ~BIT_V; if (res & 0x80) sreg|= (BIT_N); else sreg&= ~BIT_N; ram->set(SREG, sreg); return(resGO);}/* * Increment * INC Rd 0<=d<=31 * 1001 010d dddd 0011 *____________________________________________________________________________ */intcl_avr::inc_Rd(t_mem code){ t_addr d; d= (code&0x1f0)>>4; t_mem data= ram->read(d)+1; ram->write(d, data); t_mem sreg= ram->get(SREG); data= data&0xff; if (data & 0x80) { sreg|= (BIT_N); if (data == 0x80) { sreg|= BIT_V; sreg&= ~BIT_S; } else { sreg&= ~BIT_V; sreg|= BIT_S; } sreg&= ~BIT_Z; } else { sreg&= ~(BIT_N|BIT_V|BIT_S); if (!data) sreg|= BIT_Z; else sreg&= ~BIT_Z; } ram->set(SREG, sreg); return(resGO);}/* * Arithmetic Shift Right * ASR Rd 0<=d<=31 * 1001 010d dddd 0101 *____________________________________________________________________________ */intcl_avr::asr_Rd(t_mem code){ t_addr d; t_mem D, result, res; d= (code&0x1f0)>>4; D= ram->read(d); t_mem sreg= ram->read(SREG) & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C); int n=0, v= 0, c= 0; if (D & 1) { sreg|= BIT_C; c= 1; } result= D>>1; if (result & 0x40) result|= 0x80; res= result & 0xff; ram->write(d, res); if (res & 0x80) { sreg|= BIT_N; n= 1; } if ((n ^ c) & 1) { sreg|= BIT_V; v= 1; } if ((n ^ v) & 1) sreg|= BIT_S; if (!res) sreg|= BIT_Z; ram->write(SREG, sreg); return(resGO);}/* * Logical Shift Right * LSR Rd 0<=d<=31 * 1001 010d dddd 0110 *____________________________________________________________________________ */intcl_avr::lsr_Rd(t_mem code){ t_addr d; t_mem D, result, res; d= (code &0x1f0)>>4; D= ram->read(d); t_mem sreg= ram->read(SREG) & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C); if (D & 1) sreg|= (BIT_C|BIT_V|BIT_S); result= D >> 1; res= result & 0xff; ram->write(d, res); if (!res) sreg|= BIT_Z; ram->write(SREG, sreg); return(resGO);}/* * Rotate Right trough Carry * ROR Rd 0<=d<=31 * 1001 010d dddd 0111 *____________________________________________________________________________ */intcl_avr::ror_Rd(t_mem code){ t_addr d; t_mem D, result, res; d= (code&0x1f0)>>4; D= ram->read(d); t_mem sreg= ram->read(SREG); int oldc= sreg & BIT_C; sreg= sreg & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C); int n= 0, v= 0, c= 0; if (D & 1) { sreg|= BIT_C; c= 1; } result= (D >> 1) | oldc?0x80:0; res= result & 0xff; ram->write(d, res); if (res & 0x80) { sreg|= BIT_N; n= 1; } if ((n ^ c) & 1) { sreg|= BIT_V; v= 1; } if ((n ^ v) & 1) sreg|= BIT_S; if (!res) sreg|= BIT_Z; ram->write(SREG, sreg); return(resGO);}/* * Decrement * DEC Rd 0<=d<=31 * 1001 010d dddd 1010 *____________________________________________________________________________ */intcl_avr::dec_Rd(t_mem code){ t_addr d; t_mem D, result, res; d= (code&0x1f0)>>4; D= ram->read(d); result= D-1; res= result & 0xff; ram->write(d, res); t_mem sreg= ram->get(SREG); if (!res) sreg|= BIT_Z; else sreg&= ~BIT_Z; int n= 0, v= 0; if (res & 0x80) { sreg|= BIT_N; n= 1; } else sreg&= ~BIT_N; if (D == 0x80) { sreg|= BIT_V; v= 1; } else sreg&= ~BIT_V; if ((n ^ v) & 1) sreg|= BIT_S; else sreg&= ~BIT_S; ram->set(SREG, sreg); return(resGO);}/* * Multiply * MUL Rd,Rr 0<=d<=31, 0<=r<=31 * 1001 11rd dddd rrrr *____________________________________________________________________________ */intcl_avr::mul_Rd_Rr(t_mem code){ t_addr d, r; t_mem D, R, result, resl, resh; d= (code>>4) & 0x1f; r= ((code&0x200)>>5) | (code&0xf); D= ram->read(d); R= ram->read(r); result= R*D; resl= result & 0xff; resh= (result>>8) & 0xff; ram->write(0, resl); ram->write(1, resh); t_mem sreg= ram->read(SREG) & ~BIT_C; if (resh & 0x80) sreg|= BIT_C; ram->write(SREG, sreg); tick(1); return(resGO);}/* * Add Immediate to Word * ADIW Rdl,K dl={24,26,28,30}, 0<=K<=63 * 1001 0110 KK dd KKKK *____________________________________________________________________________ */intcl_avr::adiw_Rdl_K(t_mem code){ t_addr dl; t_mem D, K, result, res; dl= 24+(2*((code&0x30)>>4)); K= ((code&0xc0)>>2)|(code&0xf); D= ram->read(dl+1)*256 + ram->read(dl); result= D+K; res= result & 0xffff; t_mem resl= result&0xff, resh= (result>>8)&0xff; ram->write(dl+1, resh); ram->write(dl, resl); t_mem sreg= ram->get(SREG); if (!res) sreg|= BIT_Z; else sreg&= ~BIT_Z; if (D&res&0x8000) sreg|= (BIT_V|BIT_S); else sreg&= ~(BIT_V|BIT_S); if (res & 0x8000) { sreg|= BIT_N; sreg^= BIT_S; } else sreg&= ~BIT_N; if ((~res)&D&0x8000) sreg|= BIT_C; else sreg&= ~BIT_C; ram->set(SREG, sreg); tick(1); return(resGO);}/* * Substract Immediate from Word * SBIW Rdl,K dl={24,26,28,30}, 0<=K<=63 * 1001 0111 KK dd KKKK *____________________________________________________________________________ */intcl_avr::sbiw_Rdl_K(t_mem code){ t_addr dl; t_mem D, K, result, res; dl= 24+(2*((code&0x30)>>4)); K= ((code&0xc0)>>2)|(code&0xf); D= ram->read(dl+1)*256 + ram->read(dl); if (K & 0x20) K|= ~0x3f; if (D & 0x8000) D|= ~0xffff; (signed)result= (signed)D-(signed)K; res= result & 0xffff; t_mem resl= res&0xff, resh= (res>>8)&0xff; ram->write(dl+1, resh); ram->write(dl, resl); t_mem sreg= ram->get(SREG) & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C); int n= 0, v= 0; if (0x8000 & D & (~res)) { sreg|= BIT_V; v= 1; } if (res & 0x8000) { sreg|= BIT_N; n= 1; } if ((n ^ v) & 1) sreg|= BIT_S; if (!res) sreg|= BIT_Z; if (0x8000 & res & (~D)) sreg|= BIT_C; ram->set(SREG, sreg); tick(1); return(resGO);}/* End of avr.src/arith_inst.cc */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -