📄 func_command.c
字号:
/* File : func_command.c Author : Sergiy Uvarov - Copyright (C) 2001 Description : Description of commands. Copyright notice: avr_simulator - A GNU/Linux simulator for the Atmel AVR series of microcontrollers. Copyright (C) 2001 Sergey Uvarov 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. Sergiy Uvarov E-mail : colonel@ff.dsu.dp.ua*/#include <stdio.h>#include <inttypes.h>#include <string.h>#include <Xm/XmAll.h>#include "types.h"#include "global.h"#include "func_command.h"void check_Z_N_flags(uint8_t result){ /* check flag Z*/ if(result==0) set_sreg_flag(FLAG_Z); else clear_sreg_flag(FLAG_Z); /* check flag N */ if(result&0x80) set_sreg_flag(FLAG_N); else clear_sreg_flag(FLAG_N); }int get_io_index(int code){ int n; for(n=0;controllers[type_micro].io_registers[n].code!=-1;n++) if(code==controllers[type_micro].io_registers[n].code) return n; return -1;}void adc_command(void){ uint8_t arg1,arg2; arg1=gpr_pointer[list_commands[pc].arg1]; arg2=gpr_pointer[list_commands[pc].arg2]; gpr_pointer[list_commands[pc].arg1]+=arg2; if(get_sreg_flag(FLAG_C)) gpr_pointer[list_commands[pc].arg1]++; /* set bit, it means that field's value will be update */ mem_file_changed[list_commands[pc].arg1/8]|=1<<list_commands[pc].arg1%8; check_Z_N_flags(gpr_pointer[list_commands[pc].arg1]); /* check flag C */ if(((arg1&0x80)&(arg2&0x80))| ((arg1&0x80)&~(gpr_pointer[list_commands[pc].arg1]&0x80))| (~(gpr_pointer[list_commands[pc].arg1]&0x80)& (arg2&0x80))) set_sreg_flag(FLAG_C); else clear_sreg_flag(FLAG_C); /* check flag H */ if(((arg1&0x08)&(arg2&0x08))| ((arg1&0x08)&~(gpr_pointer[list_commands[pc].arg1]&0x8))| (~(gpr_pointer[list_commands[pc].arg1]&0x08)& (arg2&0x08))) set_sreg_flag(FLAG_H); else clear_sreg_flag(FLAG_H); /* check flag V */ if(((arg1&0x80)&(arg2&0x80)&(~(gpr_pointer[list_commands[pc].arg1]&0x80)))| ((~(arg1&0x80))&(~(arg2&0x80))&(gpr_pointer[list_commands[pc].arg1]&0x80))) set_sreg_flag(FLAG_V); else clear_sreg_flag(FLAG_V); /* check flag S */ if(get_sreg_flag(FLAG_N)^get_sreg_flag(FLAG_V)) set_sreg_flag(FLAG_S); else clear_sreg_flag(FLAG_S); pc++; clocks++;}void add_command(void){ unsigned char arg1,arg2; arg1=gpr_pointer[list_commands[pc].arg1]; arg2=gpr_pointer[list_commands[pc].arg2]; gpr_pointer[list_commands[pc].arg1]+=arg2; /* set bit, it means that field's value will be update */ mem_file_changed[list_commands[pc].arg1/8]|=1<<list_commands[pc].arg1%8; check_Z_N_flags(gpr_pointer[list_commands[pc].arg1]); /* check flag C */ if(((arg1&0x80)&(arg2&0x80))| ((arg1&0x80)&~(gpr_pointer[list_commands[pc].arg1]&0x80))| (~(gpr_pointer[list_commands[pc].arg1]&0x80)& (arg2&0x80))) set_sreg_flag(FLAG_C); else clear_sreg_flag(FLAG_C); /* check flag H */ if(((arg1&0x08)&(arg2&0x08))| ((arg1&0x08)&(gpr_pointer[list_commands[pc].arg1]&0x8))| ((gpr_pointer[list_commands[pc].arg1]&0x08)& (arg2&0x08))) set_sreg_flag(FLAG_H); else clear_sreg_flag(FLAG_H); /* check flag V */ if(((arg1&0x80)&(arg2&0x80)&(~(gpr_pointer[list_commands[pc].arg1]&0x80)))| ((~(arg1&0x80))&(~(arg2&0x80))&(gpr_pointer[list_commands[pc].arg1]&0x80))) set_sreg_flag(FLAG_V); else clear_sreg_flag(FLAG_V); /* check flag S */ if(get_sreg_flag(FLAG_N)^get_sreg_flag(FLAG_V)) set_sreg_flag(FLAG_S); else clear_sreg_flag(FLAG_S); pc++; clocks++;}void adiw_command(void){ uint16_t reg,old; reg=gpr_pointer[list_commands[pc].arg1]; reg+=gpr_pointer[list_commands[pc].arg1+1]<<8; old=reg; reg+=list_commands[pc].arg2; gpr_pointer[list_commands[pc].arg1]=(uint8_t)reg; gpr_pointer[list_commands[pc].arg1+1]=(uint8_t)(reg>>8); /* set bit, it means that field's value will be update */ mem_file_changed[list_commands[pc].arg1/8]|=1<<list_commands[pc].arg1%8; mem_file_changed[(list_commands[pc].arg1+1)/8]= 1<<(list_commands[pc].arg1+1)%8; /* check Flag Z */ if(!reg) set_sreg_flag(FLAG_Z); else clear_sreg_flag(FLAG_Z); /* check Flag N */ if(reg&0x8000) set_sreg_flag(FLAG_N); else clear_sreg_flag(FLAG_N); /* check Flag C */ if((~(reg&0x8000))&&(old&0x8000)) set_sreg_flag(FLAG_C); else clear_sreg_flag(FLAG_C); /* check flag V */ if((reg&0x8000)&&(~(old&0x8000))) set_sreg_flag(FLAG_V); else clear_sreg_flag(FLAG_V); /* check flag S */ if(get_sreg_flag(FLAG_N)^get_sreg_flag(FLAG_V)) set_sreg_flag(FLAG_S); else clear_sreg_flag(FLAG_S); pc++; clocks+=2;}void and_command(void){ gpr_pointer[list_commands[pc].arg1]&=gpr_pointer[list_commands[pc].arg2]; /* set bit, it means that field's value will be update */ mem_file_changed[list_commands[pc].arg1/8]|=1<<list_commands[pc].arg1%8; check_Z_N_flags(gpr_pointer[list_commands[pc].arg1]); /* check flag V */ clear_sreg_flag(FLAG_V); /* check flag S */ if(get_sreg_flag(FLAG_N)^get_sreg_flag(FLAG_V)) set_sreg_flag(FLAG_S); else clear_sreg_flag(FLAG_S); pc++; clocks++;}void andi_command(void){ gpr_pointer[list_commands[pc].arg1]= list_commands[pc].arg2&gpr_pointer[list_commands[pc].arg1]; /* set bit, it means that field's value will be update */ mem_file_changed[list_commands[pc].arg1/8]|=1<<list_commands[pc].arg1%8; check_Z_N_flags(gpr_pointer[list_commands[pc].arg1]); /* check flag V */ clear_sreg_flag(FLAG_V); /* check flag S */ if(get_sreg_flag(FLAG_N)^get_sreg_flag(FLAG_V)) set_sreg_flag(FLAG_S); else clear_sreg_flag(FLAG_S); pc++; clocks++;}void asr_command(void){ /* set flag C */ if(gpr_pointer[list_commands[pc].arg1]&0x01) set_sreg_flag(FLAG_C); else clear_sreg_flag(FLAG_C); gpr_pointer[list_commands[pc].arg1]=gpr_pointer[list_commands[pc].arg1]>>1; /* set bit, it means that field's value will be update */ mem_file_changed[list_commands[pc].arg1/8]|=1<<list_commands[pc].arg1%8; check_Z_N_flags(gpr_pointer[list_commands[pc].arg1]); /* check flag V */ if(get_sreg_flag(FLAG_N)^get_sreg_flag(FLAG_C)) set_sreg_flag(FLAG_V); else clear_sreg_flag(FLAG_V); /* check flag S */ if(get_sreg_flag(FLAG_N)^get_sreg_flag(FLAG_V)) set_sreg_flag(FLAG_S); else clear_sreg_flag(FLAG_S); pc++; clocks++;}void bclr_command(void){ switch(list_commands[pc].arg1) { case 7: clear_sreg_flag(FLAG_I); break; case 6: clear_sreg_flag(FLAG_T); break; case 5: clear_sreg_flag(FLAG_H); break; case 4: clear_sreg_flag(FLAG_S); break; case 3: clear_sreg_flag(FLAG_V); break; case 2: clear_sreg_flag(FLAG_N); break; case 1: clear_sreg_flag(FLAG_Z); break; case 0: clear_sreg_flag(FLAG_C); break; } pc++; clocks++;}void bld_command(void){ if(get_sreg_flag(FLAG_T)) gpr_pointer[list_commands[pc].arg1]|=1<<list_commands[pc].arg2; else gpr_pointer[list_commands[pc].arg1]&=~(1<<list_commands[pc].arg2); /* set bit, it means that field's value will be update */ mem_file_changed[list_commands[pc].arg1/8]|=1<<list_commands[pc].arg1%8; pc++; clocks++;}void brbc_command(void){ if(get_sreg_flag(1<<list_commands[pc].arg1)) {pc++;clocks++;} else { pc=list_commands[pc].arg2; clocks++; }}void brbs_command(void){ if(get_sreg_flag(1<<list_commands[pc].arg1)) { pc=list_commands[pc].arg2; clocks++; } else {pc++;clocks++;}}void bset_command(void){ set_sreg_flag(1<<list_commands[pc].arg1); pc++; clocks++;}void bst_command(void){ if(gpr_pointer[list_commands[pc].arg1]&(1<<list_commands[pc].arg2)) set_sreg_flag(FLAG_T); else clear_sreg_flag(FLAG_T); pc++; clocks++;}/* need to change for work on 22 bit PC */void call_command(void){ uint16_t sp; pc+=2; if(type_micro==0) { stack_90s1200[2]=stack_90s1200[1]; stack_90s1200[1]=stack_90s1200[0]; stack_90s1200[0]=pc; } else { if(ISPORT(SPH)) sp=get_port16(SPL,SPH); else sp=get_port(SPL); if(sp<2) {fprintf(stderr,"Error: Stack Pointer not set\n");} pc+=2; gpr_pointer[sp]=(uint8_t)(pc>>8); mem_file_changed[sp/8]|=1<<sp%8; sp--; gpr_pointer[sp]=(uint8_t)pc; mem_file_changed[sp/8]|=1<<sp%8; sp--; if(ISPORT(SPH)) set_port16(SPL,SPH,sp); else set_port(SPL,sp); } pc=list_commands[pc-2].arg1; clocks+=4;}void cbi_command(void){ int n,mask; for(mask=n=0;controllers[type_micro].io_registers[n].code!=-1;n++) if(controllers[type_micro].io_registers[n].address==list_commands[pc].arg1) mask=controllers[type_micro].io_registers[n].write_mask; if(mask&(1<<list_commands[pc].arg2)) io_pointer[list_commands[pc].arg1]&=~(1<<list_commands[pc].arg2); pc++; clocks+=2;}void com_command(void){ gpr_pointer[list_commands[pc].arg1]=0xFF-gpr_pointer[list_commands[pc].arg1]; /* set bit, it means that field's value will be update */ mem_file_changed[list_commands[pc].arg1/8]|=1<<list_commands[pc].arg1%8; check_Z_N_flags(gpr_pointer[list_commands[pc].arg1]); set_sreg_flag(FLAG_C); clear_sreg_flag(FLAG_V); /* check flag S */ if(get_sreg_flag(FLAG_N)^get_sreg_flag(FLAG_V)) set_sreg_flag(FLAG_S); else clear_sreg_flag(FLAG_S); pc++; clocks++;}void cp_command(void){ unsigned int result,arg1,arg2; arg1=gpr_pointer[list_commands[pc].arg1]; arg2=gpr_pointer[list_commands[pc].arg2]; result=arg1-arg2; /* check flag C */ if((~(arg1&0x80)&(arg2&0x80))|((arg2&0x80)&(result&0x80))| ((result&0x80)&~(arg2&0x80))) set_sreg_flag(FLAG_C); else clear_sreg_flag(FLAG_C); check_Z_N_flags(result); /* check flag V */ if(((arg1&0x80)&~(arg2&0x80)&~(result&0x80))| (~(arg1&0x80)&(arg2&0x80)&(result&0x80))) set_sreg_flag(FLAG_V); else clear_sreg_flag(FLAG_V); /* check flag S */ if(get_sreg_flag(FLAG_N)^get_sreg_flag(FLAG_V)) set_sreg_flag(FLAG_S); else clear_sreg_flag(FLAG_S); /* check flag H */ if(((arg1&0x08)&(arg2&0x08))|((arg2&0x08)&~(result&0x8))| (~(result&0x08)&(arg1&0x08))) set_sreg_flag(FLAG_H); else clear_sreg_flag(FLAG_H); pc++; clocks++;}void cpc_command(void){ unsigned int result,arg1,arg2; arg1=gpr_pointer[list_commands[pc].arg1]; arg2=gpr_pointer[list_commands[pc].arg2]; result=arg1-arg2; if(get_sreg_flag(FLAG_C)) result--; /* check flag C */ if((~(arg1&0x80)&(arg2&0x80))|((arg2&0x80)&(result&0x80))| ((result&0x80)&~(arg2&0x80))) set_sreg_flag(FLAG_C); else clear_sreg_flag(FLAG_C); check_Z_N_flags(result); /* check flag V */ if(((arg1&0x80)&~(arg2&0x80)&~(result&0x80))| (~(arg1&0x80)&(arg2&0x80)&(result&0x80))) set_sreg_flag(FLAG_V); else clear_sreg_flag(FLAG_V); /* check flag S */ if(get_sreg_flag(FLAG_N)^get_sreg_flag(FLAG_V)) set_sreg_flag(FLAG_S); else clear_sreg_flag(FLAG_S); /* check flag H */ if((~(arg1&0x08)&(arg2&0x08))|((arg2&0x08)&(result&0x8))| ((result&0x08)&~(arg1&0x08))) set_sreg_flag(FLAG_H); else clear_sreg_flag(FLAG_H); pc++; clocks++;}void cpi_command(void){ unsigned int result,arg1,arg2; arg1=gpr_pointer[list_commands[pc].arg1]; arg2=list_commands[pc].arg2; result=arg1-arg2; /* check flag C */ if((~(arg1&0x80)&(arg2&0x80))|((arg2&0x80)&(result&0x80))| ((result&0x80)&~(arg2&0x80))) set_sreg_flag(FLAG_C); else clear_sreg_flag(FLAG_C); check_Z_N_flags(result); /* check flag V */ if(((arg1&0x80)&~(arg2&0x80)&~(result&0x80))| (~(arg1&0x80)&(arg2&0x80)&(result&0x80))) set_sreg_flag(FLAG_V); else clear_sreg_flag(FLAG_V); /* check flag S */ if(get_sreg_flag(FLAG_N)^get_sreg_flag(FLAG_V)) set_sreg_flag(FLAG_S); else clear_sreg_flag(FLAG_S); /* check flag H */ if((~(arg1&0x08)&(arg2&0x08))|((arg2&0x08)&(result&0x8))| ((result&0x08)&~(arg1&0x08))) set_sreg_flag(FLAG_H); else clear_sreg_flag(FLAG_H); pc++; clocks++; }void cpse_command(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -