1 /* Header file for the Memory and the Memory Management Unit (MMU).
2    Module MEM_MMU.[hc] Copyright (C) 1998/1999 by Andreas Gerlich (agl)
3 
4 This file is part of yaze-ag - yet another Z80 emulator by ag.
5 
6 Yaze-ag is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2 of the License, or (at your
9 option) any later version.
10 
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 
20 #include "ytypes.h"
21 /* Definitions for BYTE and WORD moved to ytypes.h for separate inclusion
22    to reduce coupling between modules. */
23 
24 /* FASTREG needs to be at least 16 bits wide and efficient for the
25    host architecture */
26 #if UINT_MAX >= 65535
27 typedef unsigned int	FASTREG;
28 #else
29 typedef unsigned long	FASTREG;
30 #endif
31 
32 /* FASTWORK needs to be wider than 16 bits and efficient for the host
33    architecture */
34 #if UINT_MAX > 65535
35 typedef unsigned int	FASTWORK;
36 #else
37 typedef unsigned long	FASTWORK;
38 #endif
39 
40 
41 /*-------------------------------- definitions for memory space --------*/
42 
43 #define Z80MEMSIZE 64		/* logical Addressspace of the Z80 */
44 
45 #ifndef MEMSIZE			/* if MEMSIZE are not given */
46  #ifdef MMU
47   #define MEMSIZE 16*Z80MEMSIZE	/* default with MMU: MEMSIZE = 8*Z80MEMSIZE */
48  #else
49   #define MEMSIZE Z80MEMSIZE	/* default without MMU: MEMSIZE = Z80MEMSIZE */
50  #endif
51 #endif
52 
53 extern BYTE ram[MEMSIZE*1024];	/* RAM which is present */
54 
55 /*---------------------------------- definitions for MMU tables --------*/
56 
57 #ifdef MMU
58 
59  #ifndef MMUTABLES
60   #define MMUTABLES 16			 /* default: 16 MMU page tables */
61  #endif
62 
63  #ifndef YAZEPAGESIZE
64   #define YAZEPAGESIZE 4			/* Pagesize 4 KByte */
65  #endif			     /* if you want to modify then it is also	*/
66 			     /* nessasary to modify the section		*/
67 			     /* "central definitions for memory access"	*/
68 
69  #define RAMPAGES MEMSIZE/YAZEPAGESIZE		/* No. of pages of RAM  */
70 
71  #define MMUPAGEPOINTERS Z80MEMSIZE/YAZEPAGESIZE	/* No. of Page-Pointers */
72 
73  typedef struct {
74 	BYTE *page[MMUPAGEPOINTERS];	/* page table for Z80 (64KB)	*/
75  } pagetab_struct;
76 
77  extern pagetab_struct MMUtable[MMUTABLES];/* MMU page tables		    */
78  extern pagetab_struct *mmu;		  /* Pointers to one MMU-pagetable */
79  extern pagetab_struct *dmmu;		 /* ^ to destination MMU-pagetbl  */
80  extern pagetab_struct *mmuget,*mmuput; /* Pointer for get/put		 */
81  extern int mmutab;		       /* selected MMU-pagetable	*/
82 
83 							  /* choose	*/
84  #define ChooseMMUtab(mmut)  mmu=&MMUtable[mmutab=mmut]  /* mmutable	*/
85 
86  #define PP(cp) (ram + ((cp)<<12))	/* calculate page pointer	*/
87 
88 #endif
89 
90 
91 /*----------------------- central definitions for memory access -----------*/
92 
93 #ifdef MMU
94  /* The following macros are necessary for Access to Memory through a
95     MMU-table : */
96 					/* normal access to Memory: */
97  #define RAM(a)		 *( (mmu->page[(((a)&0xffff)>>12)]) + ((a)&0x0fff) )
98 
99 				/* normal access to Memory with MMUpointer: */
100  #define MRAM(xmmu,a)	 *((xmmu->page[(((a)&0xffff)>>12)]) + ((a)&0x0fff) )
101 
102 
103 					/* after access make a++ */
104  #define RAM_pp(a)	 *(tmp2=(a++), \
105 			   (mmu->page[((tmp2&0xffff)>>12)]) + (tmp2&0x0fff) )
106 				/* with MMUpointer; after access make a++ */
107  #define MRAM_pp(xmmu,a) *(tmp2=(a++), \
108 			    (xmmu->page[((tmp2&0xffff)>>12)]) + (tmp2&0x0fff) )
109 
110 
111 					/* after access make a-- */
112  #define RAM_mm(a)	 *(tmp2=(a--), \
113 			   (mmu->page[((tmp2&0xffff)>>12)]) + (tmp2&0x0fff) )
114 				/* with MMUpointer; after access make a-- */
115  #define MRAM_mm(xmmu,a) *(tmp2=(a--), \
116 			    (xmmu->page[((tmp2&0xffff)>>12)]) + (tmp2&0x0fff) )
117 
118 
119  /* before access make --a */
120  #define mm_RAM(a)	 *(tmp2=(--a), \
121 			   (mmu->page[((tmp2&0xffff)>>12)]) + (tmp2&0x0fff) )
122  /* before access make --a */
123  #define mm_MRAM(xmmu,a) *(tmp2=(--a), \
124 			    (xmmu->page[((tmp2&0xffff)>>12)]) + (tmp2&0x0fff) )
125 
126 #else
127  /* ram access without MMU, like Version 1.05/1.06/1.10 */
128  #define RAM(a)		 ram[(a)&0xffff]
129  #define MRAM(xmmu,a)	 ram[(a)&0xffff]
130 
131  #define RAM_pp(a)	 ram[(a++)&0xffff]
132  #define MRAM_pp(xmmu,a) ram[(a++)&0xffff]
133 
134  #define RAM_mm(a)	 ram[(a--)&0xffff]
135  #define MRAM_mm(xmmu,a) ram[(a--)&0xffff]
136 
137  #define mm_RAM(a)	 ram[(--a)&0xffff]
138  #define mm_MRAM(xmmu,a) ram[(--a)&0xffff]
139 #endif
140 
141 /* Some important macros. They are the interface between an access from
142    the simz80-/yaze-Modules and the method of the memory access: */
143 
144 #define GetBYTE(a)	RAM(a)
145 #define GetBYTE_pp(a)	RAM_pp(a)
146 #define GetBYTE_mm(a)	RAM_mm(a)
147 #define mm_GetBYTE(a)	mm_RAM(a)
148 #define PutBYTE(a, v)	RAM(a) = v
149 #define PutBYTE_pp(a,v)	RAM_pp(a) = v
150 #define PutBYTE_mm(a,v)	RAM_mm(a) = v
151 #define GetWORD(a)	(RAM(a) | (RAM((a)+1) << 8))
152 
153 /* don't work: #define GetWORD_pppp(a)	(RAM_pp(a) + (RAM_pp(a) << 8)) */
154 /* make once more a try at 18.10.1999/21:45 ... with the following macro:  */
155 /* works also not #define GetWORD_pppp(a) (RAM_pp(a) | (RAM_pp(a) << 8))  */
156 /* I dont know what the optimizer do with such macro.
157    If someone knows about it - I'am very interessed to that knowledge.
158  */
159 
160 #define PutWORD(a, v)							\
161     do { RAM(a) = (BYTE)(v);						\
162 	 RAM((a)+1) = (v) >> 8;						\
163      } while (0)
164 
165 
166 /*------------------- Some macros for manipulating Z80-memory : -------*/
167 
168 #define memcpy_get_z(d,s,n)						\
169     do { size_t len = n;						\
170 	 size_t source = s;						\
171          BYTE *p1 = d;							\
172          while (len--) *p1++ = GetBYTE_pp(source);			\
173     } while (0)
174 
175 
176 #define memcpy_M_get_z(xm,d,s,n)					\
177     do { size_t len = n;						\
178 	 size_t source = s;						\
179 	 BYTE *p1 = d;							\
180 	 while (len--) *p1++ = MRAM_pp(xm,source);			\
181     } while (0)
182 
183 
184 #define memcpy_put_z(d,s,n)						\
185     do { size_t len = n;						\
186 	 size_t dest = d;						\
187          BYTE *p1 = s;							\
188          while (len--) PutBYTE_pp(dest,*p1++);				\
189     } while (0)
190 
191 
192 #define memcpy_M_put_z(xm,d,s,n)					\
193     do { size_t len = n;						\
194 	 size_t dest = d;						\
195          BYTE *p1 = s;							\
196 	 while (len--) MRAM_pp(xm,dest) = *p1++;			\
197     } while (0)
198 
199 
200 #define memset_M_z(xm,p,v,n)						\
201     do { size_t len = n;						\
202          while (len--) MRAM_pp(xm,p) = v;				\
203     } while (0)
204 
205 
206 #define memset_z(p,v,n)							\
207     do { size_t len = n;						\
208          while (len--) PutBYTE_pp(p,v);					\
209     } while (0)
210 
211 
212 /*-------------------- Some macros for unix-memory operations : -------*/
213 
214 #ifdef BSD
215 #if defined(sun)
216 #include <memory.h>
217 #include <string.h>
218 #endif
219 #ifndef strchr
220 #define strchr index
221 #endif
222 #ifndef strrchr
223 #define strrchr rindex
224 #endif
225 #define memclr(p,n)     bzero(p,n)
226 #define memcpy(t,f,n)   bcopy(f,t,n)
227 #define memcmp(p1,p2,n) bcmp(p1,p2,n)
228 #define memset(p,v,n)                                                   \
229     do { size_t len = n;                                                \
230          char *p1 = p;                                                  \
231          while (len--) *p1++ = v;                                       \
232     } while (0)
233 #else
234 #include <string.h>
235 #define memclr(p,n)     (void) memset(p,0,n)
236 #endif
237 
238 
239 /*-------------------------------------------- prototyping -------------*/
240 void initMEM();
241 void initMMU();
242 void loadMMU();
243 void printMMU();
244