This source file includes following definitions.
- initPageTables
- addSDW
- stack
- bload
- msave
- mrestore
- segment_loader
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <unistd.h>
18 #include <errno.h>
19 #include <string.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #if !defined(NO_LOCALE)
24 # if defined(__APPLE__)
25 # include <xlocale.h>
26 # endif
27 # include <locale.h>
28 #endif
29
30 #include "dps8.h"
31 #include "dps8_sys.h"
32 #include "dps8_cpu.h"
33 #include "dps8_scu.h"
34 #include "dps8_iom.h"
35 #include "dps8_cable.h"
36 #include "dps8_state.h"
37 #include "dps8_utils.h"
38
39 #include "segldr.h"
40
41 #if defined(NO_LOCALE)
42 # define xstrerror_l strerror
43 #endif
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 #define ADDR_BOOT 02000
65 #define ADDR_DSPT 04000
66 #define ADDR_DSP 06000
67 #define ADDR_PGS 07000
68 #define ADDR_SEGS 0100000
69
70 #define MAX_SEG_NO 0377
71
72
73
74
75
76
77
78
79
80
81
82 static word24 nextSegAddr = ADDR_SEGS;
83 static word24 nextPageAddr = ADDR_PGS;
84
85 static void initPageTables (void)
86 {
87 for (uint addr = ADDR_DSPT; addr < ADDR_SEGS; addr ++)
88 M[addr] = 0;
89
90 uint x1 = 0;
91 word36 * ptwp = (word36 *) M + x1 + ADDR_DSPT;
92 putbits36_18 (ptwp, 0, ADDR_DSP >> 6);
93 putbits36_1 (ptwp, 26, 0);
94 putbits36_1 (ptwp, 29, 0);
95 putbits36_1 (ptwp, 29, 0);
96 putbits36_1 (ptwp, 33, 1);
97 putbits36_2 (ptwp, 34, 0);
98 }
99
100 static void addSDW (word24 addr, long segnum, long length)
101 {
102
103
104
105
106 long npages = (long)(length / 1024);
107
108
109 word14 bound = (word14)(((length + 15) >> 4) + 1);
110
111
112 word24 y1 = (word24)((2u * segnum) % 1024u);
113
114
115 word24 pgTblAddr = (word24)(nextPageAddr);
116 nextPageAddr += 1024;
117
118
119
120 word24 sdw0 = ADDR_DSP + y1 + 0;
121 word24 sdw1 = ADDR_DSP + y1 + 1;
122
123
124 putbits36_24 ((word36 *) & M[sdw0], 0, pgTblAddr);
125
126
127
128
129 putbits36_3 ((word36 *) & M[sdw0], 24, 0);
130 putbits36_3 ((word36 *) & M[sdw0], 27, 0);
131 putbits36_3 ((word36 *) & M[sdw0], 30, 0);
132 putbits36_1 ((word36 *) & M[sdw0], 33, 1);
133 putbits36_2 ((word36 *) & M[sdw0], 34, 0);
134 putbits36_1 ((word36 *) & M[sdw1], 0, 0);
135 putbits36_14 ((word36 *) & M[sdw1], 1, bound);
136 putbits36_1 ((word36 *) & M[sdw1], 15, 1);
137 putbits36_1 ((word36 *) & M[sdw1], 16, 1);
138 putbits36_1 ((word36 *) & M[sdw1], 17, 1);
139 putbits36_1 ((word36 *) & M[sdw1], 18, 0);
140 putbits36_1 ((word36 *) & M[sdw1], 19, 0);
141 putbits36_1 ((word36 *) & M[sdw1], 20, 1);
142 putbits36_1 ((word36 *) & M[sdw1], 21, 1);
143 putbits36_14 ((word36 *) & M[sdw1], 21, 0);
144
145
146
147 for (word24 pg = 0; pg <= npages; pg ++)
148 {
149
150 word24 ptw = pgTblAddr + pg;
151 word18 pgAddr = (addr + pg * 1024) >> 6;
152 putbits36_18 ((word36 *) & M[ptw], 0, pgAddr);
153 putbits36_1 ((word36 *) & M[ptw], 26, 0);
154 putbits36_1 ((word36 *) & M[ptw], 29, 0);
155 putbits36_1 ((word36 *) & M[ptw], 29, 0);
156 putbits36_1 ((word36 *) & M[ptw], 33, 1);
157 putbits36_2 ((word36 *) & M[ptw], 34, 0);
158
159 }
160 }
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 static t_stat stack (char * p2, char * p3)
194 {
195
196 char * endptr;
197 long segnum = strtol (p2, & endptr, 8);
198 if (* endptr)
199 {
200 if (running_perf_test == true)
201 exit(1);
202 return SCPE_ARG;
203 }
204 if (segnum < 0 || segnum > MAX_SEG_NO)
205 {
206 sim_printf ("Segment number is limited to 0 to 0377\r\n");
207 if (running_perf_test == true)
208 exit(1);
209 return SCPE_ARG;
210 }
211
212 long len = strtol (p3, & endptr, 8);
213 if (* endptr)
214 {
215 if (running_perf_test == true)
216 exit(1);
217 return SCPE_ARG;
218 }
219 if (len < 1 || len > 255)
220 {
221 sim_printf ("Segment length is limited to 1 to 0377\r\n");
222 if (running_perf_test == true)
223 exit(1);
224 return SCPE_ARG;
225 }
226
227 long length = len * 1024;
228
229
230 addSDW (nextSegAddr, segnum, length);
231
232 sim_printf ("Placed stack (%lo) at %o length %lo allocated %lo\r\n",
233 (unsigned long) segnum, nextSegAddr, (unsigned long) len, length);
234
235 nextSegAddr += length;
236
237 return SCPE_OK;
238 }
239
240 static t_stat bload (char * p2, char * p3)
241 {
242
243 long segnum;
244 if (strcasecmp ("boot", p2) == 0)
245 {
246 segnum = -1;
247 }
248 else
249 {
250 char * endptr;
251 segnum = strtol (p2, & endptr, 8);
252 if (* endptr)
253 {
254 if (running_perf_test == true)
255 exit(1);
256 return SCPE_ARG;
257 }
258 if (segnum < 0 || segnum > MAX_SEG_NO)
259 {
260 sim_printf ("Segment number is limited to 0 to 0377\r\n");
261 if (running_perf_test == true)
262 exit(1);
263 return SCPE_ARG;
264 }
265 }
266
267
268 int deckfd = open (p3, O_RDONLY);
269 if (deckfd < 0)
270 {
271 if (errno) sim_printf ("Error: %s\r\n", xstrerror_l(errno));
272 sim_printf ("Unable to open '%s'\r\n", p3);
273 if (running_perf_test == true)
274 exit(1);
275
276 return SCPE_ARG;
277 }
278
279
280 word24 addr;
281 word24 startAddr;
282 if (segnum < 0)
283 addr = 0;
284 else
285 addr = nextSegAddr;
286
287 startAddr = addr;
288
289 for (;;)
290 {
291 ssize_t sz;
292
293 uint8_t bytes [9];
294 (void)memset (bytes, 0, 9);
295 sz = read (deckfd, bytes, 9);
296 if (sz == 0)
297 break;
298
299 word36 even = extr36 (bytes, 0);
300 word36 odd = extr36 (bytes, 1);
301
302 M[addr ++] = even;
303 M[addr ++] = odd;
304 }
305 word24 length = addr - startAddr;
306
307 word24 lengthp;
308 if (segnum >= 0)
309 {
310
311 addSDW (startAddr, segnum, length);
312
313
314 lengthp = (length + 01777) & 077776000;
315
316
317 nextSegAddr += lengthp;
318 }
319 else
320 {
321 lengthp = 04000;
322 addSDW (0, 0, lengthp);
323 }
324
325 sim_printf ("Loaded %s (%lo) at %o length %o allocated %o\r\n",
326 p3, segnum < 0 ? 0 : (unsigned long) segnum, startAddr, length, lengthp);
327 close (deckfd);
328 return SCPE_OK;
329 }
330
331 #define msize (MEMSIZE * sizeof (word36))
332
333 static t_stat msave (char * p2, word24 sz)
334 {
335 uint wrsz = sz * sizeof (word36);
336 int fd = open (p2, O_WRONLY | O_CREAT, 0664);
337 if (fd < 0)
338 {
339 if (errno) sim_printf ("Error: %s\r\n", xstrerror_l(errno));
340 sim_printf ("Unable to open '%s'\r\n", p2);
341 if (running_perf_test == true)
342 exit(1);
343 return SCPE_ARG;
344 }
345 ssize_t n = write (fd, (void *) M, wrsz);
346 if (n != wrsz)
347 {
348 if (errno) sim_printf ("Error: %s\r\n", xstrerror_l(errno));
349 sim_printf ("Unable to write '%s'\r\n", p2);
350 if (running_perf_test == true)
351 exit(1);
352 (void) close (fd);
353 return SCPE_ARG;
354 }
355 (void) close (fd);
356 return SCPE_OK;
357 }
358
359 t_stat mrestore (char * p2)
360 {
361 int fd = open (p2, O_RDONLY);
362 if (fd < 0)
363 {
364 if (errno) sim_printf ("Error: %s\r\n", xstrerror_l(errno));
365 sim_printf ("Unable to open '%s'\r\n", p2);
366 if (running_perf_test == true)
367 exit(1);
368 return SCPE_ARG;
369 }
370 ssize_t n = read (fd, (void *) M, msize);
371 if (n < 1)
372 {
373 if (errno) sim_printf ("Error: %s\r\n", xstrerror_l(errno));
374 sim_printf ("Unable to read '%s'\r\n", p2);
375 (void) close (fd);
376 if (running_perf_test == true)
377 exit(1);
378 return SCPE_ARG;
379 }
380 #if defined(WIN_STDIO)
381 sim_printf ("Read %llu bytes (%llu pages, %llu segments)\r\n",
382 #else
383 sim_printf ("Read %'llu bytes (%'llu pages, %'llu segments)\r\n",
384 #endif
385 (unsigned long long) n,
386 (unsigned long long) (n / sizeof (word36)),
387 (unsigned long long) (n / sizeof (36) / 1024));
388 (void) close (fd);
389 return SCPE_OK;
390 }
391
392 t_stat segment_loader (int32 arg, const char * buf)
393 {
394 size_t bufl = strlen (buf) + 1;
395 char p1 [bufl], p2 [bufl], p3 [bufl];
396 int nParams = sscanf (buf, "%s %s %s", p1, p2, p3);
397 if (nParams <= 0)
398 goto err;
399 if (strncasecmp ("init", p1, strlen(p1)) == 0)
400 {
401 if (nParams != 1)
402 goto err;
403 nextSegAddr = ADDR_SEGS;
404 initPageTables ();
405 }
406 else if (strcasecmp ("bload", p1) == 0)
407 {
408 if (nParams != 3)
409 goto err;
410 return bload (p2, p3);
411 }
412 else if (strcasecmp ("stack", p1) == 0)
413 {
414 if (nParams != 3)
415 goto err;
416 return stack (p2, p3);
417 }
418 else if (strcasecmp ("msave", p1) == 0)
419 {
420 if (nParams != 2)
421 goto err;
422 return msave (p2, nextSegAddr);
423 }
424 else if (strcasecmp ("mrestore", p1) == 0)
425 {
426 if (nParams != 2)
427 goto err;
428 return mrestore (p2);
429 }
430 else
431 goto err;
432 return SCPE_OK;
433 err:
434 sim_msg ("Usage:\r\n"
435 " sl init initialize\r\n"
436 " sl bload <segno> <filename>\r\n");
437 if (running_perf_test == true)
438 exit(0);
439 return SCPE_ARG;
440 }
441
442 #if defined(PERF_STRIP)
443 extern DEVICE opc_dev;
444 int main (int argc, char * argv[])
445 {
446 # if !defined(NO_LOCALE)
447 (void)setlocale(LC_ALL, "");
448 # endif
449 running_perf_test = true;
450 void dps8_init_strip (void);
451 dps8_init_strip ();
452 cpus[0].tweaks.enable_emcall = 1;
453 opc_dev.numunits = 1;
454 cpu_reset_unit_idx (0, false);
455 mrestore ("strip.mem");
456 threadz_sim_instr ();
457 return 0;
458 }
459 #endif