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