t_addr z;
z= ram->get(ZH)*256 + ram->get(ZL);
- PC= ((PC & ~0xffff) | z) % rom->size;
+ PC= rom->validate_address((PC & ~0xffff) | z);
+ //FIXME: analyze
return(resGO);
}
}
+/*
+ * Indirect Call to Subroutine
+ * ICALL
+ * 1001 0101 XXXX 1001
+ *____________________________________________________________________________
+ */
+
int
cl_avr::icall(t_mem code)
{
+ t_mem zl, zh;
+ t_addr z;
+
+ push_addr(PC);
+ zl= ram->read(ZL);
+ zh= ram->read(ZH);
+ z= zh*256 + zl;
+ PC= (PC & ~0xffff) | (z & 0xffff);
+ //FIXME: analyze
+ tick(2);
return(resGO);
}
}
+/*
+ * Return from Subroutine
+ * RET
+ * 1001 0101 0XX0 1000
+ *____________________________________________________________________________
+ */
+
int
cl_avr::ret(t_mem code)
{
+ t_addr a;
+
+ pop_addr(&a);
+ PC= rom->validate_address(a);
+ tick(3);
return(resGO);
}
+/*
+ * Return from Interrupt
+ * RETI
+ * 1001 0101 0XX1 1000
+ *____________________________________________________________________________
+ */
+
int
cl_avr::reti(t_mem code)
{
+ t_addr a;
+
+ pop_addr(&a);
+ PC= rom->validate_address(a);
+ t_mem sreg= ram->read(SREG);
+ sreg|= BIT_I;
+ ram->write(SREG, sreg);
+ tick(3);
return(resGO);
}
int
cl_avr::rjmp_k(t_mem code)
{
- long k= code & 0xfff, pc;
+ long k= code & 0xfff;
if (k & 0x800)
k|= -4096;
- pc= PC+k;
- if (pc < 0)
- pc= rom->size + pc;
- PC= pc % rom->size;
+ PC= rom->validate_address((signed)PC + (signed)k);
tick(1);
return(resGO);
}
+/*
+ * Relative Call to Subroutine
+ * RCALL k
+ * 1101 kkkk kkkk kkkk -1K<=k<=+1k
+ *____________________________________________________________________________
+ */
+
int
cl_avr::rcall_k(t_mem code)
{
+ t_addr k;
+
+ push_addr(PC);
+ k= code & 0xfff;
+ if (k & 0x800)
+ k|= ~0xfff;
+ PC= rom->validate_address((signed)PC + (signed)k);
+ tick(2);
+
return(resGO);
}
i++;
if (dt[i].mnemonic != NULL)
{
- PC= (PC + dt[i].length) % get_mem_size(MEM_ROM);
+ PC= rom->validate_address(PC + dt[i].length);
tick(1);
}
else
k= ((code&0x1f0)>>3)|(code&1);
k= (k<<16)|fetch();
- PC= k;
- //FIXME: analyze
+ PC= rom->validate_address(k);
tick(2);
return(resGO);
}
k= (((code&0x1f0)>>3)|(code&1))*0x10000;
k= k + fetch();
-
+ push_addr(PC);
+ PC= rom->validate_address(k);
tick(3);
return(resGO);
}
{
if (code&0x200)
k|= -128;
- PC= (PC+k) % get_mem_size(MEM_ROM);
+ PC= rom->validate_address((signed)PC+k);
tick(1);
}
return(resGO);
{
if (code&0x200)
k|= -128;
- PC= (PC+k) % get_mem_size(MEM_ROM);
+ PC= rom->validate_address((signed)PC+k);
tick(1);
}
return(resGO);
i++;
if (dt[i].mnemonic != NULL)
{
- PC= (PC + dt[i].length) % get_mem_size(MEM_ROM);
+ PC= rom->validate_address(PC + dt[i].length);
tick(1);
}
else
i++;
if (dt[i].mnemonic != NULL)
{
- PC= (PC + dt[i].length) % get_mem_size(MEM_ROM);
+ PC= rom->validate_address(PC + dt[i].length);
tick(1);
}
else