2 * Simulator of microcontrollers (regsxa.h)
4 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
6 * Written by Karl Bongers karl@turbobit.com
8 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
12 /* This file is part of microcontroller simulator: ucsim.
14 UCSIM is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 UCSIM is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with UCSIM; see the file COPYING. If not, write to the Free
26 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
30 #ifndef REGSAVR_HEADER
31 #define REGSAVR_HEADER
40 /* direct is a special code space for built-in ram and SFR, 1K size */
41 #ifdef WORDS_BIGENDIAN
42 #define set_word_direct(_index, _value) { \
43 mem_direct[(_index)] = (_value >> 8); \
44 mem_direct[(_index)] = (_value & 0xff); }
46 #define get_word_direct(_index) \
47 ( (mem_direct[(_index)] << 8) | mem_direct[(_index)+1] )
49 #define set_word_direct(_index, _value) { \
50 wmem_direct[(_index) >> 1] = _value; }
51 #define get_word_direct(_index) (wmem_direct[(_index) >> 1] )
54 #define get_byte_direct(_index) (mem_direct[_index])
57 #define store2(addr, val) { ram->set((t_addr) (addr), val & 0xff); \
58 ram->set((t_addr) (addr+1), (val >> 8) & 0xff); }
59 #define store1(addr, val) ram->set((t_addr) (addr), val)
62 #define get1(addr) ram->get((t_addr) (addr))
63 #define get2(addr) (ram->get((t_addr) (addr)) | (ram->get((t_addr) (addr+1)) << 8) )
65 /* fetch from opcode code space */
66 #define fetch2() ((fetch() << 8) | fetch())
67 #define fetch1() fetch()
69 /* get a 1 or 2 byte register */
70 #define reg2(_index) get_reg(1, (_index))
71 #define reg1(_index) (unsigned char)get_reg(0, (_index))
73 #define set_byte_direct(_index, _value) { \
74 mem_direct[_index] = _value; \
77 #define set_reg1(_index, _value) { \
78 if ((_index) < 3) { /* banked */ \
79 mem_direct[0x400+(_index)] = _value; \
80 } else { /* non-banked */ \
81 mem_direct[0x400+(_index)] = _value; \
85 #define set_reg2(_index, _value) { \
86 if ((_index) < 3) { /* banked */ \
87 set_word_direct((0x400+_index), _value); \
88 } else { /* non-banked */ \
89 set_word_direct((0x400+_index), _value); \
93 #define set_reg(_word_flag, _index, _value) { \
95 { set_reg2((_index), _value) } \
97 { set_reg1((_index), _value) } \
100 /* R7 mirrors 1 of 2 real SP's */
101 #define set_sp(_value) { \
102 { set_word_direct(0x400+(7*2), _value); } \
105 #define get_sp() ((TYPE_UWORD)(get_word_direct(0x400+(7*2))))
107 // fixme: I don't know where the psw is kept, just want to compile...
108 #define get_psw() ((TYPE_UWORD)(get_word_direct(0x400+(0x80*2))))
110 /* we also need to set flags, this scheme no setup well to do this yet... */
111 #define add1(_a, _b) ( (unsigned char)((_a) + (_b)) )
112 #define add2(_a, _b) ( (unsigned short)((_a) + (_b)) )
114 #define addc1(_a, _b) ( (unsigned char)((_a) + (_b)) )
115 #define addc2(_a, _b) ( (unsigned short)((_a) + (_b)) )
118 --------------------------------------------------------------------
122 f: {unused slot(word accessable only) for R8-R15}
123 e: R7h,R7l Stack pointer, ptr to USP(PSW.SM=0), or SSP(PSW.SM=1)
127 below are the banked registers which mirror(B0..B3) depending on
134 Registers are all bit addressable as:
135 2: bx1f,bx1e...b8(R0h) bx17,bx16..bx10(R0l)
136 0: bxf,bxe...b8(R0h) b7,b6..b0(R0l)
138 Memory is little endian:
142 Data word access limited to word boundaries. If non-word address used,
143 then will act as lesser word alignment used(addr b0=0).
144 (note: trigger an exception in simulator if otherwise).
146 Internal memory takes precedence over external memory, unless
149 64K segment memory layout, bank registers used include:
150 DS(data segment) and ES(extra segment) and forms high byte of
151 24 bit address. Stack is in DS, so ES typically used to access
154 SFR(1K direct space) is above normal 1K direct address space(0-3FFH)
155 between 400H to 7FFH.
157 Branch targets must reside on even boundaries
158 (note: trigger an exception in simulator if otherwise).
160 MOVC instructions use either PC(SSEL.4=0) or CS(SSEL.4=1) register.
163 PCON, SCR, SSEL, PSWH, PSWL, CS, ES, DS
165 400H-43FH are bit or byte accesable.
166 400H-5FFH is for built in SFR hardware.
167 600H-7FFH is for external SFR hardware access.
168 SFR access is independent of segment regs.
169 SFR inacessable from indirect addressing(must use direct-addr in opcodes).
173 100H to 1ffH - 20h to 3fH(direct ram, relative to DS)
174 200H to 3FFH - 400H to 43FH(on board SFRs)
176 PSW Flags: Carry(C), Aux Carry(AC), Overflow(V), Negative(N), Zero(Z).
178 Stack ptr is pre-decremented, followed by load(word operation),
179 default SPs are set to 100H. So first PUSH would go to FEH-FFH.
192 /* End of xa.src/regsxa.h */