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
18
19
20 #include <unistd.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
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 putbits36_24 ((word36 *) & M[sdw0], 0, pgTblAddr);
118
119
120
121
122 putbits36_3 ((word36 *) & M[sdw0], 24, 0);
123 putbits36_3 ((word36 *) & M[sdw0], 27, 0);
124 putbits36_3 ((word36 *) & M[sdw0], 30, 0);
125 putbits36_1 ((word36 *) & M[sdw0], 33, 1);
126 putbits36_2 ((word36 *) & M[sdw0], 34, 0);
127 putbits36_1 ((word36 *) & M[sdw1], 0, 0);
128 putbits36_14 ((word36 *) & M[sdw1], 1, bound);
129 putbits36_1 ((word36 *) & M[sdw1], 15, 1);
130 putbits36_1 ((word36 *) & M[sdw1], 16, 1);
131 putbits36_1 ((word36 *) & M[sdw1], 17, 1);
132 putbits36_1 ((word36 *) & M[sdw1], 18, 0);
133 putbits36_1 ((word36 *) & M[sdw1], 19, 0);
134 putbits36_1 ((word36 *) & M[sdw1], 20, 1);
135 putbits36_1 ((word36 *) & M[sdw1], 21, 1);
136 putbits36_14 ((word36 *) & M[sdw1], 21, 0);
137
138
139
140 for (word24 pg = 0; pg <= npages; pg ++)
141 {
142
143 word24 ptw = pgTblAddr + pg;
144 word18 pgAddr = (addr + pg * 1024) >> 6;
145 putbits36_18 ((word36 *) & M[ptw], 0, pgAddr);
146 putbits36_1 ((word36 *) & M[ptw], 26, 0);
147 putbits36_1 ((word36 *) & M[ptw], 29, 0);
148 putbits36_1 ((word36 *) & M[ptw], 29, 0);
149 putbits36_1 ((word36 *) & M[ptw], 33, 1);
150 putbits36_2 ((word36 *) & M[ptw], 34, 0);
151
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 static t_stat stack (char * p2, char * p3)
187 {
188
189
190 char * endptr;
191 long segnum = strtol (p2, & endptr, 8);
192 if (* endptr)
193 {
194 #ifdef 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 #ifdef 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 #ifdef 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 #ifdef 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", (unsigned long) segnum, nextSegAddr, (unsigned long) len, length);
235
236 nextSegAddr += length;
237
238 return SCPE_OK;
239 }
240
241 static t_stat bload (char * p2, char * p3)
242 {
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 #ifdef 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 #ifdef 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", strerror(errno));
278 sim_printf ("Unable to open '%s'\n", p3);
279 #ifdef 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 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", p3, segnum < 0 ? 0 : (unsigned long) segnum, startAddr, length, lengthp);
333 close (deckfd);
334 return SCPE_OK;
335 }
336
337 #define msize (MEMSIZE * sizeof (word36))
338
339 static t_stat msave (char * p2, word24 sz)
340 {
341 uint wrsz = sz * sizeof (word36);
342 int fd = open (p2, O_WRONLY | O_CREAT, 0664);
343 if (fd < 0)
344 {
345 if (errno) sim_printf ("Error: %s\n", strerror(errno));
346 sim_printf ("Unable to open '%s'\n", p2);
347 #ifdef PERF_STRIP
348 exit(1);
349
350 #endif
351 return SCPE_ARG;
352 }
353 ssize_t n = write (fd, (void *) M, wrsz);
354 if (n != wrsz)
355 {
356 if (errno) sim_printf ("Error: %s\n", strerror(errno));
357 sim_printf ("Unable to write '%s'\n", p2);
358 #ifdef PERF_STRIP
359 exit(1);
360
361 #endif
362 return SCPE_ARG;
363 }
364 (void) close (fd);
365 return SCPE_OK;
366 }
367
368 static t_stat mrestore (char * p2)
369 {
370 int fd = open (p2, O_RDONLY);
371 if (fd < 0)
372 {
373 if (errno) sim_printf ("Error: %s\n", strerror(errno));
374 sim_printf ("Unable to open '%s'\n", p2);
375 #ifdef PERF_STRIP
376 exit(1);
377
378 #endif
379 return SCPE_ARG;
380 }
381 ssize_t n = read (fd, (void *) M, msize);
382 if (n < 1)
383 {
384 if (errno) sim_printf ("Error: %s\n", strerror(errno));
385 sim_printf ("Unable to read '%s'\n", p2);
386 (void) close (fd);
387 #ifdef PERF_STRIP
388 exit(1);
389
390 #endif
391 return SCPE_ARG;
392 }
393 #ifdef WIN_STDIO
394 sim_printf ("Read %llu bytes (%llu pages, %llu segments)\n",
395 #else
396 sim_printf ("Read %'llu bytes (%'llu pages, %'llu segments)\n",
397 #endif
398 (unsigned long long) n,
399 (unsigned long long) (n / sizeof (word36)),
400 (unsigned long long) (n / sizeof (36) / 1024));
401 (void) close (fd);
402 return SCPE_OK;
403 }
404
405 t_stat segment_loader (int32 arg, const char * buf)
406 {
407 size_t bufl = strlen (buf) + 1;
408 char p1 [bufl], p2 [bufl], p3 [bufl];
409 int nParams = sscanf (buf, "%s %s %s", p1, p2, p3);
410 if (nParams <= 0)
411 goto err;
412 if (strncasecmp ("init", p1, strlen(p1)) == 0)
413 {
414 if (nParams != 1)
415 goto err;
416 nextSegAddr = ADDR_SEGS;
417 initPageTables ();
418 }
419 else if (strcasecmp ("bload", p1) == 0)
420 {
421 if (nParams != 3)
422 goto err;
423 return bload (p2, p3);
424 }
425 else if (strcasecmp ("stack", p1) == 0)
426 {
427 if (nParams != 3)
428 goto err;
429 return stack (p2, p3);
430 }
431 else if (strcasecmp ("msave", p1) == 0)
432 {
433 if (nParams != 2)
434 goto err;
435 return msave (p2, nextSegAddr);
436 }
437 else if (strcasecmp ("mrestore", p1) == 0)
438 {
439 if (nParams != 2)
440 goto err;
441 return mrestore (p2);
442 }
443 else
444 goto err;
445 return SCPE_OK;
446 err:
447 sim_msg ("Usage:\n"
448 " sl init initialize\n"
449 " sl bload <segno> <filename>\n");
450 #ifdef PERF_STRIP
451 exit(0);
452
453 #endif
454 return SCPE_ARG;
455 }
456
457 #ifdef PERF_STRIP
458 extern DEVICE opc_dev;
459 int main (int argc, char * argv[])
460 {
461 setlocale(LC_NUMERIC, "");
462 void dps8_init_strip (void);
463 dps8_init_strip ();
464 cpus[0].tweaks.enable_emcall = 1;
465 opc_dev.numunits = 1;
466 cpu_reset_unit_idx (0, false);
467 mrestore ("strip.mem");
468 threadz_sim_instr ();
469 return 0;
470 }
471 #endif