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