Imported Upstream version 2.9.0
[debian/cc1111] / sim / ucsim / xa.src / regsxa.h
1 /*
2  * Simulator of microcontrollers (regsxa.h)
3  *
4  * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt.
5  *
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  * Other contributors include:
8  *   Karl Bongers karl@turbobit.com,
9  *   Johan Knol 
10  *
11  */
12
13 /* This file is part of microcontroller simulator: ucsim.
14
15 UCSIM is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
19
20 UCSIM is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with UCSIM; see the file COPYING.  If not, write to the Free
27 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
28 02111-1307, USA. */
29 /*@1@*/
30
31 #define REGS_OFFSET 0x800
32
33 #ifndef REGSAVR_HEADER
34 #define REGSAVR_HEADER
35
36 #include "ddconfig.h"
37
38 struct t_regs
39 {
40   int dummy;
41 };
42
43 /* these macros suck, what was I thinking?  Try to make it go fast
44    at the our expense?  Daniels going to hate me if I continue to
45    clutter up his nice C++ with old crusty C macros :)  Karl.
46 */
47
48 /* store to sfr */
49 #define set_word_direct(addr, val) { sfr->set((t_addr) (addr), (val) & 0xff); \
50                             sfr->set((t_addr) (addr+1), ((val) >> 8) & 0xff); }
51 #define set_byte_direct(addr, val) sfr->set((t_addr) (addr), (val) )
52
53 /* get from sfr */
54 #define get_byte_direct(addr) sfr->get((t_addr) (addr))
55 #define get_word_direct(addr) (sfr->get((t_addr) (addr)) | (sfr->get((t_addr) (addr+1)) << 8) )
56
57 /* store to idata(onchip) ram */
58 #define set_idata2(addr, val) { iram->set((t_addr) (addr), (val) & 0xff); \
59                             iram->set((t_addr) (addr+1), ((val) >> 8) & 0xff); }
60 #define set_idata1(addr, val) iram->set((t_addr) (addr), (val) )
61
62 /* get from idata(onchip) ram */
63 #define get_idata1(addr) iram->get((t_addr) (addr))
64 #define get_idata2(addr) (iram->get((t_addr) (addr)) | (iram->get((t_addr) (addr+1)) << 8) )
65
66 /* store to xdata(external) ram */
67 #define set_xdata2(addr, val) { ram->set((t_addr) (addr), (val) & 0xff); \
68                             ram->set((t_addr) (addr+1), ((val) >> 8) & 0xff); }
69 #define set_xdata1(addr, val) ram->set((t_addr) (addr), val)
70
71 /* get from xdata(external) ram */
72 #define get_xdata1(addr) ram->get((t_addr) (addr))
73 #define get_xdata2(addr) (ram->get((t_addr) (addr)) | (ram->get((t_addr) (addr+1)) << 8) )
74
75 /* get from code */
76 #define getcode1(addr) rom->get((t_addr) (addr))
77 #define getcode2(addr) (rom->get((t_addr) (addr)) | (rom->get((t_addr) (addr+1)) << 8) )
78
79 /* fetch from opcode code space */
80 #define fetch2() ((fetch() << 8) | fetch())
81 #define fetch1() fetch()
82
83 /* get a 1 or 2 byte register */
84 #define reg2(_index) get_reg(1, REGS_OFFSET + (_index<<1)) /* function in inst.cc */
85 #define reg1(_index) (unsigned char)get_reg(0, REGS_OFFSET + (_index))
86
87 #define set_reg1(_index, _value) { \
88   set_byte_direct((REGS_OFFSET+(_index)), _value); \
89 }
90
91 #define set_reg2(_index, _value) { \
92      set_word_direct( (REGS_OFFSET+(_index<<1)), _value); \
93 }
94
95 #define set_reg(_word_flag, _index, _value) { \
96   if (_word_flag) \
97     { set_reg2((_index), _value) } \
98   else \
99     { set_reg1((_index), _value) } \
100 }
101
102 /* R7 mirrors 1 of 2 real SP's
103   note: we will probably need a real function here...
104  */
105 #define set_sp(_value) { \
106   { set_word_direct(REGS_OFFSET+(7*2), _value); } \
107 }
108
109 #define get_sp() ((TYPE_UWORD)(get_word_direct(REGS_OFFSET+(7*2))))
110
111 /* the program status word */
112 #define PSW 0x400
113 #define get_psw() ((TYPE_UWORD)(get_word_direct(PSW)))
114 #define set_psw(_flags) set_word_direct(PSW, _flags)
115
116 /* the system configuration register */
117 #define SCR 0x440
118 #define get_scr() get_byte_direct(SCR)
119 #define set_scr(scr) set_byte_direct(SCR, scr)
120
121 // PSW bits...(note: consider replacing with Bit defines used in s51.src code)
122 #define BIT_C  0x80
123 #define BIT_AC 0x40
124 #define BIT_V  0x04
125 #define BIT_N  0x02
126 #define BIT_Z  0x01
127 #define BIT_ALL (BIT_C | BIT_AC | BIT_V | BIT_N | BIT_Z)
128
129
130 #if 0
131 --------------------------------------------------------------------
132 Developer Notes.
133
134 This user guide has got the detailed information on the XA chip. 
135
136 http://www.semiconductors.philips.com/acrobat/various/XA_USER_GUIDE_1.pdf
137
138 f: {unused slot(word accessable only) for R8-R15}
139 e: R7h,R7l  Stack pointer, ptr to USP(PSW.SM=0), or SSP(PSW.SM=1)
140 c: R6h,R6l
141 a: R5h,R5l
142 8: R4h,R4l
143 below are the banked registers which mirror(B0..B3) depending on
144 PSW.(RS0,RS1)
145 6: R3h,R3l
146 4: R2h,R2l
147 2: R1h,R1l
148 0: R0h,R0l
149
150 Registers are all bit addressable as:
151 2: bx1f,bx1e...b8(R0h)  bx17,bx16..bx10(R0l)
152 0: bxf,bxe...b8(R0h)  b7,b6..b0(R0l)
153
154 Memory is little endian:
155 addr0: LSB
156 addr1: MSB
157
158 Data word access limited to word boundaries.  If non-word address used,
159 then will act as lesser word alignment used(addr b0=0).
160
161 Internal memory takes precedence over external memory, unless
162 explicit movx used.
163
164 64K segment memory layout, bank registers used include:
165 DS(data segment) and ES(extra segment) and forms high byte of
166 24 bit address.  Stack is in DS, so ES typically used to access
167 user data.
168
169 SFR(1K direct space) is above normal 1K direct address space(0-3FFH)
170 between 400H to 7FFH.
171
172 Branch targets must reside on even boundaries
173
174 MOVC instructions use either PC(SSEL.4=0) or CS(SSEL.4=1) register.
175
176 Core SFRs:
177 PCON, SCR, SSEL, PSWH, PSWL, CS, ES, DS
178 (1K SFR space)
179 400H-43FH are bit or byte accesable.
180 400H-5FFH is for built in SFR hardware.
181 600H-7FFH is for external SFR hardware access.
182 SFR access is independent of segment regs.
183 SFR inacessable from indirect addressing(must use direct-addr in opcodes).
184
185 Bit space:
186 0 to ffH - R0 to R15
187 100H to 1ffH - 20h to 3fH(direct ram, relative to DS)
188 200H to 3FFH - 400H to 43FH(on board SFRs)
189
190 PSW Flags: Carry(C), Aux Carry(AC), Overflow(V), Negative(N), Zero(Z).
191
192 Stack ptr is pre-decremented, followed by load(word operation),
193 default SPs are set to 100H.  So first PUSH would go to FEH-FFH.
194
195 DIRECT MEMORY SPACE
196
197 When we speak of direct memory space we refer to opcodes like
198 MOV Rd, direct
199 The "direct" part is always composed of 11 bits in the opcode.
200 So the total size of "direct" space is 2K bytes.
201
202 1.) This direct memory space contains the SFRs starting at 0x400 offset.
203
204 Internal onchip memory(SFRs and onchip RAM) always override
205 external memory.  Read the specific Chip documentation for the
206 location of SFRs and RAM.
207
208 The codes space is independent.
209
210 The registers: 4 banks of 8 bytes(R0-R3), R4-R7 8 bytes, and stack
211 pointers are self contained and not part of any address space.
212 (The CS,ES,DS appear to reside in SFR space).
213
214 This is still confusing, let take some examples.
215
216 ---------------------------
217 XA-G49 chip has 2k bytes built in RAM.
218
219 According to the XA-G49 datasheet:
220
221 With the DS set to 0, then all indirect address references
222 between 0-7FFH reference the onchip 2K RAM.  Direct address
223 references below 0x400 access onchip 2K RAM.
224
225 With the DS not set to 0, then all indirect address references
226 between 0-7FFH reference external memory.  Direct address
227 references below 0x400 access external memory.
228
229 Any direct address references between 400H and 7FFH access the SFRs
230 regardless of the segment register contents.
231
232 To access any external memory which overlaps the 2K onchip memory
233 ues the MOVX instruction.
234
235 ---------------------------
236 Proposed segment layout use for SDCC/XA compiler:
237
238 XDATA -> external memory(use indirect addressing, ignore direct
239    addressing, ignore any overlap with onchip memory).
240
241 IDATA -> onchip memory(use indirect addressing, ignore direct
242    addressing, assume small model where DS,ES always 0).
243
244 DATA -> SFR memory access using direct addressing.
245
246 CODE -> Far calls/returns are available.
247
248 (Johan, Im just trying to spell this out explicitly for
249 my own understanding.)
250
251 ---------------------------
252 Proposed segment layout use for ucSim XA simulator.
253
254 ram -> external memory.
255
256 rom -> external/internal code.
257
258 sfr -> SFR register space.  Include registers/register banks here
259 in some unused location to provide a means to dump all the register
260 file contents using the "ds" command.  Could make sfr memory larger
261 than 0x800, and use the space above 0x800 to hold registers/sp-s.
262
263 idata -> onchip memory.
264
265 I think we can determine the size of idata memory at run time, so
266 this could allow for various sized onchip memorys.  So indirect
267 memory accesses like this:
268 set_indirect1(addr, value) {
269   if (addr < mem_size(idata)) {
270     set_idata(addr,value);
271   } else {
272     set_xdata(addr,value);
273   }
274 }
275
276 ----------------------------------------------
277 #endif
278
279
280 #endif
281 /* End of xa.src/regsxa.h */