Merge branch ucsim-034-pre3 to main trunk; new version 0.4
[fw/sdcc] / sim / ucsim / xa.src / regsxa.h
diff --git a/sim/ucsim/xa.src/regsxa.h b/sim/ucsim/xa.src/regsxa.h
new file mode 100644 (file)
index 0000000..ee7134b
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Simulator of microcontrollers (regsxa.h)
+ *
+ * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
+ *
+ * Written by Karl Bongers karl@turbobit.com
+ * 
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ *
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM 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.
+
+UCSIM 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 UCSIM; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+#ifndef REGSAVR_HEADER
+#define REGSAVR_HEADER
+
+#include "ddconfig.h"
+
+struct t_regs
+{
+  int dummy;
+};
+
+/* direct is a special code space for built-in ram and SFR, 1K size */
+#ifdef WORDS_BIGENDIAN
+#define set_word_direct(_index, _value) { \
+      mem_direct[(_index)] = (_value >> 8); \
+      mem_direct[(_index)] = (_value & 0xff); }
+
+#define get_word_direct(_index) \
+      ( (mem_direct[(_index)] << 8) | mem_direct[(_index)+1] )
+#else
+#define set_word_direct(_index, _value) { \
+      wmem_direct[(_index) >> 1] = _value; }
+#define get_word_direct(_index) (wmem_direct[(_index) >> 1] )
+#endif
+
+#define get_byte_direct(_index) (mem_direct[_index])
+
+/* store to ram */
+#define store2(addr, val) { ram->set((t_addr) (addr), val & 0xff); \
+                            ram->set((t_addr) (addr+1), (val >> 8) & 0xff); }
+#define store1(addr, val) ram->set((t_addr) (addr), val)
+
+/* get from ram */
+#define get1(addr) ram->get((t_addr) (addr))
+#define get2(addr) (ram->get((t_addr) (addr)) | (ram->get((t_addr) (addr+1)) << 8) )
+
+/* fetch from opcode code space */
+#define fetch2() ((fetch() << 8) | fetch())
+#define fetch1() fetch()
+
+/* get a 1 or 2 byte register */
+#define reg2(_index) get_reg(1, (_index))
+#define reg1(_index) (unsigned char)get_reg(0, (_index))
+
+#define set_byte_direct(_index, _value) { \
+   mem_direct[_index] = _value; \
+}
+
+#define set_reg1(_index, _value) { \
+  if ((_index) < 3) { /* banked */ \
+      mem_direct[0x400+(_index)] = _value; \
+  } else { /* non-banked */ \
+      mem_direct[0x400+(_index)] = _value; \
+  } \
+}
+
+#define set_reg2(_index, _value) { \
+  if ((_index) < 3) { /* banked */ \
+     set_word_direct((0x400+_index), _value); \
+  } else { /* non-banked */ \
+     set_word_direct((0x400+_index), _value); \
+  } \
+}
+
+#define set_reg(_word_flag, _index, _value) { \
+  if (_word_flag) \
+    { set_reg2((_index), _value) } \
+  else \
+    { set_reg1((_index), _value) } \
+}
+
+  /* R7 mirrors 1 of 2 real SP's */
+#define set_sp(_value) { \
+  { set_word_direct(0x400+(7*2), _value); } \
+}
+
+#define get_sp() ((TYPE_UWORD)(get_word_direct(0x400+(7*2))))
+
+// fixme: I don't know where the psw is kept, just want to compile...
+#define get_psw() ((TYPE_UWORD)(get_word_direct(0x400+(0x80*2))))
+
+/* we also need to set flags, this scheme no setup well to do this yet... */
+#define add1(_a, _b) ( (unsigned char)((_a) + (_b)) )
+#define add2(_a, _b) ( (unsigned short)((_a) + (_b)) )
+
+#define addc1(_a, _b) ( (unsigned char)((_a) + (_b)) )
+#define addc2(_a, _b) ( (unsigned short)((_a) + (_b)) )
+
+#if 0
+--------------------------------------------------------------------
+Notes:
+ Register layout:
+
+f: {unused slot(word accessable only) for R8-R15}
+e: R7h,R7l  Stack pointer, ptr to USP(PSW.SM=0), or SSP(PSW.SM=1)
+c: R6h,R6l
+a: R5h,R5l
+8: R4h,R4l
+below are the banked registers which mirror(B0..B3) depending on
+PSW.(RS0,RS1)
+6: R3h,R3l
+4: R2h,R2l
+2: R1h,R1l
+0: R0h,R0l
+
+Registers are all bit addressable as:
+2: bx1f,bx1e...b8(R0h)  bx17,bx16..bx10(R0l)
+0: bxf,bxe...b8(R0h)  b7,b6..b0(R0l)
+
+Memory is little endian:
+addr0: LSB
+addr1: MSB
+
+Data word access limited to word boundaries.  If non-word address used,
+then will act as lesser word alignment used(addr b0=0).
+(note: trigger an exception in simulator if otherwise).
+
+Internal memory takes precedence over external memory, unless
+explicit movx used.
+
+64K segment memory layout, bank registers used include:
+DS(data segment) and ES(extra segment) and forms high byte of
+24 bit address.  Stack is in DS, so ES typically used to access
+user data.
+
+SFR(1K direct space) is above normal 1K direct address space(0-3FFH)
+between 400H to 7FFH.
+
+Branch targets must reside on even boundaries
+(note: trigger an exception in simulator if otherwise).
+
+MOVC instructions use either PC(SSEL.4=0) or CS(SSEL.4=1) register.
+
+Core SFRs:
+PCON, SCR, SSEL, PSWH, PSWL, CS, ES, DS
+(1K SFR space)
+400H-43FH are bit or byte accesable.
+400H-5FFH is for built in SFR hardware.
+600H-7FFH is for external SFR hardware access.
+SFR access is independent of segment regs.
+SFR inacessable from indirect addressing(must use direct-addr in opcodes).
+
+Bit space:
+0 to ffH - R0 to R15
+100H to 1ffH - 20h to 3fH(direct ram, relative to DS)
+200H to 3FFH - 400H to 43FH(on board SFRs)
+
+PSW Flags: Carry(C), Aux Carry(AC), Overflow(V), Negative(N), Zero(Z).
+
+Stack ptr is pre-decremented, followed by load(word operation),
+default SPs are set to 100H.  So first PUSH would go to FEH-FFH.
+
+#endif
+
+
+// PSW bits...
+#define BIT_C  0x80
+#define BIT_AC 0x40
+#define BIT_V  0x04
+#define BIT_N  0x02
+#define BIT_Z  0x01
+
+#endif
+/* End of xa.src/regsxa.h */