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 (void) close (fd);
376 #ifdef 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", strerror(errno));
386 sim_printf ("Unable to read '%s'\n", p2);
387 (void) close (fd);
388 #ifdef PERF_STRIP
389 exit(1);
390
391 #endif
392 return SCPE_ARG;
393 }
394 #ifdef 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 #ifdef PERF_STRIP
452 exit(0);
453
454 #endif
455 return SCPE_ARG;
456 }
457
458 #ifdef PERF_STRIP
459 extern DEVICE opc_dev;
460 int main (int argc, char * argv[])
461 {
462 setlocale(LC_NUMERIC, "");
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