#include "xacl.h"
#include "regsxa.h"
+
+void cl_xa::store1(t_addr addr, unsigned char val)
+{
+ if (addr < 0x2000) {
+ set_idata1(addr, val);
+ } else {
+ set_xdata1(addr, val);
+ }
+}
+
+void cl_xa::store2(t_addr addr, unsigned char val)
+{
+ if (addr < 0x2000) {
+ set_idata2(addr, val);
+ } else {
+ set_xdata2(addr, val);
+ }
+}
+
+unsigned char cl_xa::get1(t_addr addr)
+{
+ if (addr < 0x2000) {
+ return get_idata1(addr);
+ } else {
+ return get_xdata1(addr);
+ }
+}
+
+unsigned short cl_xa::get2(t_addr addr)
+{
+ if (addr < 0x2000) {
+ return get_idata2(addr);
+ } else {
+ return get_xdata2(addr);
+ }
+}
+
int cl_xa::get_reg(int word_flag, unsigned int index)
{
- //if (index < 3) { /* banked */
- // if (word_flag)
- // return get_word_direct(0x400+index);
- // else
- // return mem_direct[0x400+index];
- //} else { /* non-banked */
- if (word_flag)
- return get_word_direct(0x400+index);
- else
- return mem_direct[0x400+index];
- //}
+ int result;
+
+ if (word_flag) {
+ result = get_word_direct(index);
+ }
+ else {
+ result = get_byte_direct(index);
+ }
+ return result;
+}
+
+bool cl_xa::get_bit(int bit) {
+ short offset=0;
+ unsigned char result;
+
+ if (bit>=0x200) {
+ // in sfr space
+ bit-=0x200;
+ offset=0x400;
+ }
+ result = get_byte_direct(offset + (bit/8)) & (1 << (bit%8));
+ return result;
+ //return mem_direct[offset + (bit/8)] & (1 << (bit%8));
+}
+
+void cl_xa::set_bit(int bit, int value) {
+ int i;
+ short offset=0;
+ if (bit>=0x200) {
+ // in sfr space
+ bit-=0x200;
+ offset=0x400;
+ }
+
+ i = get_byte_direct(offset + (bit/8));
+ if (value) {
+ set_byte_direct(offset + (bit/8), i | (1 << (bit%8)) );
+ //mem_direct[offset + (bit/8)] |= (1 << (bit%8));
+ } else {
+ set_byte_direct(offset + (bit/8), i & ~(1 << (bit%8)) );
+ //mem_direct[offset + (bit/8)] &= ~(1 << (bit%8));
+ }
}
#define RI_F0 ((code >> 4) & 0xf)
int cl_xa::inst_BR(uint code, int operands)
{
short jmpAddr = fetch1()*2;
- PC=(PC+jmpAddr)&0xfffffffe;
+ PC=(PC+jmpAddr)&0xfffffe;
return(resGO);
}
{
int jmpaddr;
unsigned int sp;
+ bool pageZero=get_scr()&1;
switch(operands) {
case REL16:
{
jmpaddr = (signed short)fetch2();
- sp = get_sp() - 4;
+ sp = get_sp() - (pageZero ? 2 : 4);
set_sp(sp);
- store2(sp, PC);
- store2(sp+2, 0); /* segment(not sure about ordering...) */
+ store2(sp, PC&0xffff);
+ if (!pageZero) {
+ store2(sp+2, (PC>>16)&0xff);
+ }
jmpaddr *= 2;
- PC = (PC + jmpaddr) & 0xfffffffe;
+ PC = (PC + jmpaddr) & 0xfffffe;
}
break;
case IREG:
{
- sp = get_sp() - 2;
+ sp = get_sp() - (pageZero ? 2 : 4);
set_sp(sp);
- store2(sp, PC);
-#if 0 // only in huge model
- store2(sp+2, ...
-#endif
+ store2(sp, PC&0xffff);
+ if (!pageZero) {
+ store2(sp+2, (PC>>16)&0xff);
+ }
jmpaddr = reg2(RI_07);
jmpaddr *= 2;
- PC = (PC + jmpaddr) & 0xfffffffe;
+ PC = (PC + jmpaddr) & 0xfffffe;
}
break;
- /* fixme 2 more... */ /* johan: which ones? */
}
return(resGO);
}
unsigned short tmp = mov2(0, reg2(RI_F0)-1);
set_reg2(RI_F0, tmp);
if (tmp != 0)
- PC = (PC + addr) & 0xfffffffe;
+ PC = (PC + addr) & 0xfffffe;
} else {
unsigned char tmp = mov1(0, reg1(RI_F0)-1);
set_reg1(RI_F0, tmp);
if (tmp != 0)
- PC = (PC + addr) & 0xfffffffe;
+ PC = (PC + addr) & 0xfffffe;
}
}
break;
case REL16:
{
jmpAddr = (signed short)fetch2()*2;
- PC = (PC + jmpAddr) & 0xfffffffe;
+ PC = (PC + jmpAddr) & 0xfffffe;
}
break;
case IREG:
}
}
break;
- // fixme, 2 more
+ case A_APLUSDPTR:
+ { /* R4l=ACC, R6=DPTR */
+ unsigned int addr = (PC & 0xff0000) | (reg1(4) + reg2(6));
+ unsigned short result;
+ unsigned char flags;
+ flags = get_psw();
+
+ flags &= ~(BIT_Z | BIT_N); /* clear these bits */
+ result = getcode1(addr);
+ set_reg1( 4, result);
+ if (result == 0) flags |= BIT_Z;
+ if (result & 0x80) flags |= BIT_N;
+ set_psw(flags);
+ }
+ break;
+ case A_APLUSPC:
+ { /* R4l=ACC, R6=DPTR */
+ unsigned int addr = (PC + reg1(4));
+ unsigned short result;
+ unsigned char flags;
+ flags = get_psw();
+
+ flags &= ~(BIT_Z | BIT_N); /* clear these bits */
+ result = getcode1(addr);
+ set_reg1( 4, result);
+ if (result == 0) flags |= BIT_Z;
+ if (result & 0x80) flags |= BIT_N;
+ set_psw(flags);
+ }
+ break;
}
return(resGO);
}
{
unsigned int retaddr;
unsigned short sp;
+ bool pageZero=get_scr()&1;
+
sp = get_sp();
retaddr = get2(sp);
-#if 0 // only in huge model
- retaddr |= get2(sp+2) << 16;
-#endif
- set_sp(sp+2);
+ if (!pageZero) {
+ retaddr |= get2(sp+2) << 16;
+ set_sp(sp+4);
+ } else {
+ set_sp(sp+2);
+ }
PC = retaddr;
return(resGO);
}
int cl_xa::inst_RETI(uint code, int operands)
{
+ unsigned int retaddr;
+ unsigned short sp;
+ bool pageZero=get_scr()&1;
+
+ sp = get_sp();
+ set_psw(get2(sp));
+ retaddr = get2(sp+2);
+ if (!pageZero) {
+ retaddr |= get2(sp+4) << 16;
+ set_sp(sp+6);
+ } else {
+ set_sp(sp+4);
+ }
+ PC = retaddr;
return(resGO);
}
int cl_xa::inst_RL(uint code, int operands)