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 return SCPE_ARG;
364 }
365 (void) close (fd);
366 return SCPE_OK;
367 }
368
369 t_stat mrestore (char * p2)
370 {
371 int fd = open (p2, O_RDONLY);
372 if (fd < 0)
373 {
374 if (errno) sim_printf ("Error: %s\n", xstrerror_l(errno));
375 sim_printf ("Unable to open '%s'\n", p2);
376 #if defined(PERF_STRIP)
377 exit(1);
378
379 #endif
380 return SCPE_ARG;
381 }
382 ssize_t n = read (fd, (void *) M, msize);
383 if (n < 1)
384 {
385 if (errno) sim_printf ("Error: %s\n", xstrerror_l(errno));
386 sim_printf ("Unable to read '%s'\n", p2);
387 (void) close (fd);
388 #if defined(PERF_STRIP)
389 exit(1);
390
391 #endif
392 return SCPE_ARG;
393 }
394 #if defined(WIN_STDIO)
395 sim_printf ("Read %llu bytes (%llu pages, %llu segments)\n",
396 #else
397 sim_printf ("Read %'llu bytes (%'llu pages, %'llu segments)\n",
398 #endif
399 (unsigned long long) n,
400 (unsigned long long) (n / sizeof (word36)),
401 (unsigned long long) (n / sizeof (36) / 1024));
402 (void) close (fd);
403 return SCPE_OK;
404 }
405
406 t_stat segment_loader (int32 arg, const char * buf)
407 {
408 size_t bufl = strlen (buf) + 1;
409 char p1 [bufl], p2 [bufl], p3 [bufl];
410 int nParams = sscanf (buf, "%s %s %s", p1, p2, p3);
411 if (nParams <= 0)
412 goto err;
413 if (strncasecmp ("init", p1, strlen(p1)) == 0)
414 {
415 if (nParams != 1)
416 goto err;
417 nextSegAddr = ADDR_SEGS;
418 initPageTables ();
419 }
420 else if (strcasecmp ("bload", p1) == 0)
421 {
422 if (nParams != 3)
423 goto err;
424 return bload (p2, p3);
425 }
426 else if (strcasecmp ("stack", p1) == 0)
427 {
428 if (nParams != 3)
429 goto err;
430 return stack (p2, p3);
431 }
432 else if (strcasecmp ("msave", p1) == 0)
433 {
434 if (nParams != 2)
435 goto err;
436 return msave (p2, nextSegAddr);
437 }
438 else if (strcasecmp ("mrestore", p1) == 0)
439 {
440 if (nParams != 2)
441 goto err;
442 return mrestore (p2);
443 }
444 else
445 goto err;
446 return SCPE_OK;
447 err:
448 sim_msg ("Usage:\n"
449 " sl init initialize\n"
450 " sl bload <segno> <filename>\n");
451 #if defined(PERF_STRIP)
452 exit(0);
453
454 #endif
455 return SCPE_ARG;
456 }
457
458 #if defined(PERF_STRIP)
459 extern DEVICE opc_dev;
460 int main (int argc, char * argv[])
461 {
462 (void)setlocale(LC_ALL, "");
463 void dps8_init_strip (void);
464 dps8_init_strip ();
465 cpus[0].tweaks.enable_emcall = 1;
466 opc_dev.numunits = 1;
467 cpu_reset_unit_idx (0, false);
468 mrestore ("strip.mem");
469 threadz_sim_instr ();
470 return 0;
471 }
472 #endif