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