2 * Simulator of microcontrollers (regsxa.h)
4 * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7 * Other contributors include:
8 * Karl Bongers karl@turbobit.com,
13 /* This file is part of microcontroller simulator: ucsim.
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.
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.
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
32 //#define REGS_OFFSET 0x400
34 #ifndef REGSAVR_HEADER
35 #define REGSAVR_HEADER
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.
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) )
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) )
59 #define store2(addr, val) { ram->set((t_addr) (addr), (val) & 0xff); \
60 ram->set((t_addr) (addr+1), ((val) >> 8) & 0xff); }
61 #define store1(addr, val) ram->set((t_addr) (addr), val)
64 #define get1(addr) ram->get((t_addr) (addr))
65 #define get2(addr) (ram->get((t_addr) (addr)) | (ram->get((t_addr) (addr+1)) << 8) )
68 #define getcode1(addr) rom->get((t_addr) (addr))
69 #define getcode2(addr) (rom->get((t_addr) (addr)) | (rom->get((t_addr) (addr+1)) << 8) )
71 /* fetch from opcode code space */
72 #define fetch2() ((fetch() << 8) | fetch())
73 #define fetch1() fetch()
75 /* get a 1 or 2 byte register */
76 #define reg2(_index) get_reg(1, (_index<<1)) /* function in inst.cc */
77 #define reg1(_index) (unsigned char)get_reg(0, (_index))
79 #define set_reg1(_index, _value) { \
80 set_byte_direct((REGS_OFFSET+(_index<<1)), _value); \
83 #define set_reg2(_index, _value) { \
84 set_word_direct( (REGS_OFFSET+(_index<<1)), _value); \
87 #define set_reg(_word_flag, _index, _value) { \
89 { set_reg2((_index), _value) } \
91 { set_reg1((_index), _value) } \
94 /* R7 mirrors 1 of 2 real SP's
95 note: we will probably need a real function here...
97 #define set_sp(_value) { \
98 { set_word_direct(REGS_OFFSET+(7*2), _value); } \
101 #define get_sp() ((TYPE_UWORD)(get_word_direct(REGS_OFFSET+(7*2))))
103 /* the program status word */
105 #define get_psw() ((TYPE_UWORD)(get_word_direct(PSW)))
106 #define set_psw(_flags) set_word_direct(PSW, _flags)
108 /* the system configuration register */
110 #define get_scr() get_byte_direct(SCR)
111 #define set_scr(scr) set_byte_direct(SCR, scr)
113 // PSW bits...(note: consider replacing with Bit defines used in s51.src code)
119 #define BIT_ALL (BIT_C | BIT_AC | BIT_V | BIT_N | BIT_Z)
123 --------------------------------------------------------------------
126 This user guide has got the detailed information on the XA chip.
128 http://www.semiconductors.philips.com/acrobat/various/XA_USER_GUIDE_1.pdf
130 f: {unused slot(word accessable only) for R8-R15}
131 e: R7h,R7l Stack pointer, ptr to USP(PSW.SM=0), or SSP(PSW.SM=1)
135 below are the banked registers which mirror(B0..B3) depending on
142 Registers are all bit addressable as:
143 2: bx1f,bx1e...b8(R0h) bx17,bx16..bx10(R0l)
144 0: bxf,bxe...b8(R0h) b7,b6..b0(R0l)
146 Memory is little endian:
150 Data word access limited to word boundaries. If non-word address used,
151 then will act as lesser word alignment used(addr b0=0).
153 Internal memory takes precedence over external memory, unless
156 64K segment memory layout, bank registers used include:
157 DS(data segment) and ES(extra segment) and forms high byte of
158 24 bit address. Stack is in DS, so ES typically used to access
161 SFR(1K direct space) is above normal 1K direct address space(0-3FFH)
162 between 400H to 7FFH.
164 Branch targets must reside on even boundaries
166 MOVC instructions use either PC(SSEL.4=0) or CS(SSEL.4=1) register.
169 PCON, SCR, SSEL, PSWH, PSWL, CS, ES, DS
171 400H-43FH are bit or byte accesable.
172 400H-5FFH is for built in SFR hardware.
173 600H-7FFH is for external SFR hardware access.
174 SFR access is independent of segment regs.
175 SFR inacessable from indirect addressing(must use direct-addr in opcodes).
179 100H to 1ffH - 20h to 3fH(direct ram, relative to DS)
180 200H to 3FFH - 400H to 43FH(on board SFRs)
182 PSW Flags: Carry(C), Aux Carry(AC), Overflow(V), Negative(N), Zero(Z).
184 Stack ptr is pre-decremented, followed by load(word operation),
185 default SPs are set to 100H. So first PUSH would go to FEH-FFH.
189 When we speak of direct memory space we refer to opcodes like
191 The "direct" part is always composed of 11 bits in the opcode.
192 So the total size of "direct" space is 2K bytes.
194 1.) This direct memory space contains the SFRs starting at 0x400 offset.
196 Internal onchip memory(SFRs and onchip RAM) always override
197 external memory. Read the specific Chip documentation for the
198 location of SFRs and RAM.
200 The codes space is independent.
202 The registers: 4 banks of 8 bytes(R0-R3), R4-R7 8 bytes, and stack
203 pointers are self contained and not part of any address space.
204 (The CS,ES,DS appear to reside in SFR space).
206 This is still confusing, let take some examples.
208 ---------------------------
209 XA-G49 chip has 2k bytes built in RAM.
211 According to the XA-G49 datasheet:
213 With the DS set to 0, then all indirect address references
214 between 0-7FFH reference the onchip 2K RAM. Direct address
215 references below 0x400 access onchip 2K RAM.
217 With the DS not set to 0, then all indirect address references
218 between 0-7FFH reference external memory. Direct address
219 references below 0x400 access external memory.
221 Any direct address references between 400H and 7FFH access the SFRs
222 regardless of the segment register contents.
224 To access any external memory which overlaps the 2K onchip memory
225 ues the MOVX instruction.
227 ---------------------------
228 Proposed segment layout use for SDCC/XA compiler:
230 XDATA -> external memory(use indirect addressing, ignore direct
231 addressing, ignore any overlap with onchip memory).
233 IDATA -> onchip memory(use indirect addressing, ignore direct
234 addressing, assume small model where DS,ES always 0).
236 DATA -> SFR memory access using direct addressing.
238 CODE -> Far calls/returns are available.
240 (Johan, Im just trying to spell this out explicitly for
241 my own understanding.)
243 ---------------------------
244 Proposed segment layout use for ucSim XA simulator.
246 ram -> external memory.
248 rom -> external/internal code.
250 sfr -> SFR register space. Include registers/register banks here
251 in some unused location to provide a means to dump all the register
252 file contents using the "ds" command. Could make sfr memory larger
253 than 0x800, and use the space above 0x800 to hold registers/sp-s.
255 idata -> onchip memory.
257 I think we can determine the size of idata memory at run time, so
258 this could allow for various sized onchip memorys. So indirect
259 memory accesses like this:
260 set_indirect1(addr, value) {
261 if (addr < mem_size(idata)) {
262 set_idata(addr,value);
264 set_xdata(addr,value);
268 ----------------------------------------------
273 /* End of xa.src/regsxa.h */