1 /* pro_reg.c: General PRO registers
2 
3    Copyright (c) 1997-2003, Tarik Isani (xhomer@isani.org)
4 
5    This file is part of Xhomer.
6 
7    Xhomer is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License version 2
9    as published by the Free Software Foundation.
10 
11    Xhomer is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with Xhomer; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20 
21 
22 #ifdef PRO
23 #include "pdp11_defs.h"
24 #include "sim_defs.h" /* For sim_gtime() */
25 
26 extern int	PC; /* from pdp11_cpu */
27 
28 int		pro_led;
29 int		pro_csr;
30 
31 #ifndef BUILTIN_ROMS
32 unsigned short	ROM[8192];
33 unsigned short	IDROM[32];
34 #else
35 #include "id.h"
36 #include "pro350.h"
37 #endif
38 unsigned short	BATRAM[50];
39 
40 
41 /* pro_rom.c: PRO 16KB Boot/diagnostic ROM, I/O address 17730000-17767777 */
42 
rom_rd(int * data,int pa,int access)43 int rom_rd (int *data, int pa, int access)
44 {
45 	*data = ROM[(pa-017730000) >> 1];
46 	return SCPE_OK;
47 }
48 
rom_wr(int data,int pa,int access)49 int rom_wr (int data, int pa, int access)
50 {
51 	return SCPE_NXM;				/* ??? invalid access */
52 }
53 
54 
55 /* Standard I/O dispatch routine, many addresses */
56 
reg_rd(int * data,int pa,int access)57 int reg_rd (int *data, int pa, int access)
58 {
59 
60 #ifdef IOTRACE
61         if (iotfptr)
62 	{
63 	  fprintf(iotfptr, "%10.0lf ",sim_gtime());
64 	  fprintf(iotfptr, "%6o ",PC);
65 	}
66 #endif
67 
68 	if ((pa>=017773600) && (pa<=017773677))	/* ID PROM */
69 	  *data = IDROM[(pa-017773600) >> 1];
70 	else if ((pa>=017773034) && (pa<=017773177)) /* Battery backed RAM */
71 	  *data = BATRAM[(pa-017773034) >> 1];
72 	else if ((pa>=017773200) && (pa<=017773213)) /* Int controllers */
73 	  *data = pro_int_rd(pa);
74 	else
75 	  switch (pa & 017777776)
76 	  {
77 	    case 017773000:
78 	    case 017773002:
79 	    case 017773004:
80 	    case 017773006:
81 	    case 017773010:
82 	    case 017773012:
83 	    case 017773014:
84 	    case 017773016:
85 	    case 017773020:
86 	    case 017773022:
87 
88 	    case 017773024:
89 	    case 017773026:
90 	    case 017773030:
91 	    case 017773032:
92 	      *data = pro_clk_rd(pa);	/* clock */
93 	      break;
94 
95 	    case 017773300:
96 	    case 017773302:
97 	    case 017773304:
98 	    case 017773306:
99 	    case 017773310:
100 	    case 017773312:
101 	    case 017773314:
102 	      *data = pro_com_rd(pa);	/* communication port */
103 	      break;
104 
105 	    case 017773400:
106 	    case 017773402:
107 	    case 017773404:
108 	    case 017773406:
109 	      *data = pro_ptr_rd(pa);	/* printer controller */
110 	      break;
111 
112 	    case 017773500:
113 	    case 017773502:
114 	    case 017773504:
115 	    case 017773506:
116 	      *data = pro_kb_rd(pa);	/* keyboard controller */
117 	      break;
118 
119 	    case 017773700:
120 	      *data = pro_csr;
121 	      break;
122 
123 	    case 017773702:
124 	      *data = PRO_OMP;	/* Option module present */
125 	      break;
126 
127 	    case 017773704:
128 	      *data = pro_led;
129 	      break;
130 
131 #if PRO_RD_PRESENT
132 	    case 017774000:
133 	    case 017774004:
134 	    case 017774006:
135 	    case 017774010:
136 	    case 017774012:
137 	    case 017774014:
138 	    case 017774016:
139 	    case 017774020:
140 	      *data = pro_rd_rd(pa);
141 	      break;
142 #endif
143 
144 #if PRO_RX_PRESENT
145 	    case 017774200:
146 	    case 017774204:
147 	    case 017774206:
148 	    case 017774210:
149 	    case 017774212:
150 	    case 017774214:
151 	    case 017774216:
152 	    case 017774220:
153 	    case 017774222:
154 	    case 017774224:
155 	      *data = pro_rx_rd(pa);
156 	      break;
157 #endif
158 
159 #if PRO_VID_PRESENT
160 	    case 017774400:
161 	    case 017774404:
162 	    case 017774406:
163 	    case 017774414:
164 	    case 017774416:
165 	    case 017774420:
166 /* EBO */
167 	    case 017774410:
168 #if PRO_EBO_PRESENT
169 	    case 017774600:
170 #endif
171 	      *data = pro_vid_rd(pa);
172 	      break;
173 #endif
174 
175 #if PRO_MEM_PRESENT
176 	    case 017775000:
177 	    case 017775004:
178 	    case 017775006:
179 	      *data = pro_mem_rd(pa);	/* memory expansion */
180 	      break;
181 #endif
182 
183 /* Option board 6 not installed
184 	    case 017775200:
185 	      break;
186 */
187 
188 	    case 017777560:
189 	    case 017777562:
190 	    case 017777564:
191 	    case 017777566:
192 
193 	      *data = pro_maint_rd(pa);	/* maintenance terminal interface */
194 	      break;
195 
196 	    case 017777750:
197 	      /* Processor maintenance register */
198 
199 	      *data = 0;
200 	      break;
201 
202 	    default:
203 	      *data = PRO_NOREG;
204 #ifdef IOTRACE
205               if (iotfptr)
206 	      {
207 	        fprintf(iotfptr, "*R %o\n",pa);
208 	        fflush(iotfptr);
209 	      }
210 #endif
211 	      return SCPE_NXM;
212 	  }
213 
214 #ifdef IOTRACE
215         if (iotfptr)
216 	{
217 	  fprintf(iotfptr, " R %o, %o\n",pa,*data);
218 	  fflush(iotfptr);
219 	}
220 #endif
221 
222 	return SCPE_OK;
223 }
224 
reg_wr(int data,int pa,int access)225 int reg_wr (int data, int pa, int access)
226 {
227 	/* XXX Writes to ID PROM *should* return NXM */
228 
229 #ifdef IOTRACE
230         if (iotfptr)
231         {
232 	  fprintf(iotfptr, "%10.0lf ",sim_gtime());
233 	  fprintf(iotfptr, "%6o",PC);
234 	  if (access == WRITEB)
235 	    fprintf(iotfptr, "B");
236 	  else
237 	    fprintf(iotfptr, " ");
238 	}
239 #endif
240 
241 	if ((pa>=017773034) && (pa<=017773177)) /* Battery backed RAM */
242 	  WRITE_WB(BATRAM[(pa-017773034) >> 1], PRO_BATRAM_W, access);
243 	else if ((pa>=017773200) && (pa<=017773213)) /* Int controllers */
244 	  pro_int_wr(data, pa, access);
245 	else
246 	  switch (pa & 017777776)
247 	  {
248 	    case 017773000:
249 	    case 017773002:
250 	    case 017773004:
251 	    case 017773006:
252 	    case 017773010:
253 	    case 017773012:
254 	    case 017773014:
255 	    case 017773016:
256 	    case 017773020:
257 	    case 017773022:
258 
259 	    case 017773024:
260 	    case 017773026:
261 	    case 017773030:
262 	    case 017773032:
263 	      pro_clk_wr(data, pa, access);
264 	      break;
265 
266 	    case 017773300:
267 	    case 017773302:
268 	    case 017773304:
269 	    case 017773306:
270 	    case 017773310:
271 	    case 017773312:
272 	    case 017773314:
273 	      pro_com_wr(data, pa, access);
274 	      break;
275 
276 	    case 017773400:
277 	    case 017773402:
278 	    case 017773404:
279 	    case 017773406:
280 	      pro_ptr_wr(data, pa, access);
281 	      break;
282 
283 	    case 017773500:
284 	    case 017773502:
285 	    case 017773504:
286 	    case 017773506:
287 	      pro_kb_wr(data, pa, access);
288 	      break;
289 
290 	    case 017773700:
291 	      WRITE_WB(pro_csr, PRO_CSR_W, access);
292 	      break;
293 
294 	    case 017773704:
295 	      WRITE_WB(pro_led, PRO_LED_W, access);
296 	      break;
297 
298 #if PRO_RD_PRESENT
299 	    case 017774002:
300 	    case 017774004:
301 	    case 017774006:
302 	    case 017774010:
303 	    case 017774012:
304 	    case 017774014:
305 	    case 017774016:
306 	    case 017774020:
307 	      pro_rd_wr(data, pa, access);
308 	      break;
309 #endif
310 
311 #if PRO_RX_PRESENT
312 	    case 017774202:
313 	    case 017774204:
314 	    case 017774206:
315 	    case 017774210:
316 	    case 017774212:
317 	    case 017774216:
318 	    case 017774220:
319 	    case 017774222:
320 	    case 017774224:
321 	    case 017774226:
322 	      pro_rx_wr(data, pa, access);
323 	      break;
324 #endif
325 
326 #if PRO_VID_PRESENT
327 	    case 017774402:
328 	    case 017774404:
329 	    case 017774406:
330 	    case 017774414:
331 	    case 017774416:
332 	    case 017774420:
333 	    case 017774422:
334 	    case 017774424:
335 	    case 017774426:
336 /* EBO */
337 	    case 017774410:
338 	    case 017774412:
339 #if PRO_EBO_PRESENT
340 	    case 017774602:
341 #endif
342 	      pro_vid_wr(data, pa, access);
343 	      break;
344 #endif
345 
346 #if PRO_MEM_PRESENT
347 	    case 017775002:
348 	    case 017775004:
349 	    case 017775006:
350 	      pro_mem_wr(data, pa, access);
351 	      break;
352 #endif
353 
354 /* Option board 6 not installed
355 	    case 017775202:
356 	      break;
357 */
358 
359 	    case 017777560:
360 	    case 017777562:
361 	    case 017777564:
362 	    case 017777566:
363 	      pro_maint_wr(data, pa, access);	/* maintenance terminal interface */
364 	      break;
365 
366 	    case 017777750:
367 	      /* Processor maintenance register */
368 
369 	      break;
370 
371 	    default:
372 #ifdef IOTRACE
373               if (iotfptr)
374               {
375 	        fprintf(iotfptr, "*W %o, %o\n",pa,data);
376 	        fflush(iotfptr);
377 	      }
378 #endif
379 	      return SCPE_NXM;
380 	  }
381 
382 #ifdef IOTRACE
383         if (iotfptr)
384         {
385 	  fprintf(iotfptr, " W %o, %o\n",pa,data);
386 	  fflush(iotfptr);
387 	}
388 #endif
389 
390 	return SCPE_OK;
391 }
392 #endif
393