1 /* Module 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 <stdio.h>
21 #include <stdlib.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24
25 #include "mem_mmu.h"
26
27
28 BYTE ram[MEMSIZE*1024]; /* the whole memory space */
29
30
31 #ifdef MMU /* <------------------------- only if MMU is selected ------------ */
32
33 #include "simz80.h" /* for the definitions of the Z80 registers */
34
35 pagetab_struct MMUtable[MMUTABLES]; /* MMU page tables (default 8) */
36 pagetab_struct *mmu; /* Pointer to selected MMU-pagetable */
37 pagetab_struct *dmmu = &MMUtable[0]; /* Pointer to destination MMU-pagetbl */
38 pagetab_struct *mmuget,*mmuput; /* Pointer for get/put */
39 int mmutab; /* choosen MMU-pagetable */
40
41 /*------------------------------------------- initMEM ------------------*/
42 void
initMEM()43 initMEM()
44 {
45 int p;
46
47 for (p=0; p<RAMPAGES; p++) { /* initialize all Pages and */
48 memset(PP(p), p, YAZEPAGESIZE*1024 ); /* fill the page with the No. */
49 /* of the page */
50 /*
51 #ifdef MMUTEST
52 printf("init page %3d, ",p);
53 #endif
54 */
55 }
56 /*
57 #ifdef MMUTEST
58 puts("");
59 #endif
60 */
61 } /* END of initMEM */
62
63 /*------------------------------------------- initMMU ------------------*/
64 void
initMMU()65 initMMU()
66 {
67 int c,m;
68
69 /* initialice whole MMU-table */
70 /* points all page points of any table to the first 64 KByte of RAM */
71 for (m=0; m<MMUTABLES; m++)
72 for (c=0; c<(MMUPAGEPOINTERS); ++c)
73 MMUtable[m].page[c] = PP(c);
74
75 #ifdef MMUTEST
76 /* for testing choose bank 7 */
77 if (MMUTABLES <7)
78 ChooseMMUtab(1);
79 else
80 ChooseMMUtab(7);
81 if (MEMSIZE >= 192) {
82 mmu->page[11] = PP(16); /* B000H point to 10000H */
83 mmu->page[10] = PP(32); /* A000H point to 20000H */
84 mmu->page[ 9] = PP(19); /* 9000H point to 13000H */
85 mmu->page[ 8] = PP(18); /* 8000H point to 12000H */
86 mmu->page[ 7] = PP(0x1E); /* 7000H point to 1E000H */
87 mmu->page[ 6] = PP(0x1D); /* 6000H point to 1D000H */
88 mmu->page[ 5] = PP(47); /* 5000H point to 2F000H */
89 mmu->page[ 4] = PP(44); /* 4000H point to 2C000H */
90 mmu->page[ 3] = PP(1); /* 3000H point to 2A000H */
91 mmu->page[ 1] = PP(42); /* 3000H point to 2A000H */
92 /* mmu->page[ 0] = PP(41); \* 3000H point to 29000H */
93 }
94
95 /***** extra test for the MMU-Tables
96 for (m=0; m<MMUTABLES; m++) {
97 printf("MMUTEST: MMUtable[%d]\n\n",m);
98 for (c=0; c<64/4; ++c) {
99 printf("MMUtable[%d].page[%2d] = 0x%X",
100 m, c, MMUtable[m].page[c]-ram);
101 printf("\t(0x%lX)\n",(long unsigned int) MMUtable[m].page[c]);
102 }
103 printf("\nMMUTEST: END of MMUtable[%d]:\n\n",m);
104 }
105 *****/
106 #else
107 ChooseMMUtab(0); /* choose mmutable 0 (default) */
108 #endif
109
110 #ifdef MMUTEST
111 #ifndef SHOWMMU
112 #define SHOWMMU
113 #endif
114 #endif
115
116 #ifdef SHOWMMU
117 printMMU(); /* */
118 #else
119 printf("RAM: %d KByte, %d KByte YAZEPAGESIZE, %d PAGES\r\n",
120 MEMSIZE, YAZEPAGESIZE, RAMPAGES);
121 printf("MMU: %d TABLES, %d PAGEPOINTERS per TABLE, ",
122 MMUTABLES, MMUPAGEPOINTERS);
123 printf("selected MMU-PAGETABLE: T%02d\r\n\n", mmutab);
124 #endif
125
126 } /* END of initMMU() */
127
128
129 /*------------------------------------------- loadMMU ------------------
130 load a MMU-Table with the PP's which are given by a Table, which are
131 adressed by HL. The structure of the table is :
132
133 first-Byte: adr of MMUtable
134 2..16: 16 bytes which will translated in pointers
135 and put in to the MMUTab.
136
137 return-codes (reg A & HL):
138 A = 0 All is OK.
139 A = 0xFE: PagePointer is wrong (out of Memory). HL points
140 to the wrong PP.
141 A = 0xFF: MMUtable (first Byte) numbers an MMUtable which
142 does not exist.
143 */
144
145 /* Z80 registers */
146 #define AF af[af_sel]
147 #define HL regs[regs_sel].hl
148
149 void
loadMMU()150 loadMMU()
151 {
152 static pagetab_struct * p_mmu;
153 static int i,h_mmut,page;
154 FASTREG tmp2;
155
156 if ( (h_mmut= GetBYTE_pp(HL)) < MMUTABLES ) {
157 Sethreg(AF, 0x00); /* 0x00 default OK */
158 p_mmu = &MMUtable[ h_mmut ]; /* get pointer to Table */
159 for (i=0; i<MMUPAGEPOINTERS; i++)
160 if ( (page = GetBYTE_pp(HL)) < RAMPAGES ) {
161 p_mmu->page[i] = PP( page );
162 } else {
163 Sethreg(AF, 0xfe); /* 0xfe not OK */
164 HL--; /* Points HL-Register to the wrong byte */
165 #ifdef MMUTEST
166 printf("\r\nYAZE: Load-MMU-Table %d : Page No. %d for "
167 "the %d. pagepointer is wrong!\r\n",h_mmut,page,i);
168 printf(" posible max. number "
169 "is %d\n",RAMPAGES-1);
170 #endif
171 break; /* for */
172 }
173 } else {
174 Sethreg(AF, 0xff); /* 0xff not OK */
175 HL--; /* Points HL-Register to the wrong byte */
176 #ifdef MMUTEST
177 printf("\r\nYAZE: Load-MMU-Table %d <-- Number for the selected "
178 "table is out of range!\r\n",h_mmut);
179 #endif
180 }
181 } /* END of loadMMU() */
182
183
184 /*------------------------------------------- printMMU -----------------*/
185 void
printMMU()186 printMMU()
187 {
188 int c,m,i;
189 printf("RAM: %d KByte, %d KByte YAZEPAGESIZE, %d PAGES\r\n",
190 MEMSIZE, YAZEPAGESIZE, RAMPAGES);
191 printf("MMU: %d TABLES, %d PAGEPOINTERS per TABLE, ",
192 MMUTABLES, MMUPAGEPOINTERS);
193 printf("selected MMU-PAGETABLE: T%02d\r\n\n", mmutab);
194
195 /*
196 puts("Z80-\\ T00 T01 T02 T03 T04 T05 T06 T07"
197 " T08 T09 T10 T11 T12 T13 T14 T15\r\n");
198 */
199 printf("Z80-\\ ");
200 for (m=0; m<MMUTABLES; m++)
201 if (m== mmutab)
202 printf(" T%02d ",m);
203 else
204 printf(" T%02d",m);
205 puts("\r");
206 puts("ADDR \\-----------------------------------------------------------"
207 "---------\r");
208 for (c=0; c<64/4; ++c) {
209 printf("%04X :",c*(YAZEPAGESIZE*1024));
210 for (m=0; m<MMUTABLES; m++) {
211 if (m == mmutab) printf(" >");
212 else if (m != mmutab+1) printf(" ");
213 if ((i=((MMUtable[m].page[c]-ram)>>12)) <= 0xFFFF ) {
214 printf("%3X",i);
215 } else {
216 printf(" %5X ",i);
217 }
218 if (m == mmutab) printf("< ");
219 }
220 puts("\r");
221 }
222 puts("-----------------------------------------------------------------"
223 "---------\r");
224 } /* END of printMMU() */
225
226 #endif /* MMU <------------------------- only if MMU is selected ------------ */
227
228 /*--------------------------- END of Module mem_mmu.c -----------------------*/
229