This source file includes following definitions.
- x_mkdir_p
- dump_flags
- dps8_strupr
- get_iwb_info
- disassemble
- get_mod_string
- Add36b
- Sub36b
- Add18b
- Sub18b
- Add72b
- Sub72b
- compl36
- compl18
- copyBytes
- copyChars
- putByte
- putChar
- convert_to_word72
- convert_to_word36
- cmp36
- cmp18
- cmp36wl
- cmp72
- strlower
- strmask
- rtrim
- ltrim
- trim
- stripquotes
- cfg_parse
- cfg_parse_done
- strdupesc
- extrASCII36
- extr36
- putASCII36
- put36
- extractASCII36FromBuffer
- extractWord36FromBuffer
- insertASCII36toBuffer
- insertWord36toBuffer
- print_uint128o_r
- print_int128o
- print_uint128_r
- print_int128
- timespec_diff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <ctype.h>
20 #include <errno.h>
21 #include <signal.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26
27 #if defined(__MINGW64__) || defined(__MINGW32__)
28 # include <direct.h>
29 #endif
30
31 #include "dps8.h"
32 #include "dps8_sys.h"
33 #include "dps8_iom.h"
34 #include "dps8_cable.h"
35 #include "dps8_cpu.h"
36 #include "dps8_faults.h"
37 #include "dps8_scu.h"
38 #include "dps8_ins.h"
39 #include "dps8_opcodetable.h"
40 #include "dps8_utils.h"
41
42 #define DBG_CTR 1
43
44 #define FREE(p) do \
45 { \
46 free((p)); \
47 (p) = NULL; \
48 } while(0)
49
50
51
52
53
54 #if defined(__MINGW64__) || defined(__MINGW32__)
55 # define MKDIR(p, m) _mkdir(p)
56 # define IS_SEP(c) ((c) == '/' || (c) == '\\')
57 #else
58 # define MKDIR(p, m) mkdir((p), (m))
59 # define IS_SEP(c) ((c) == '/')
60 #endif
61
62 #ifndef XMKDIR_PERM
63 # define XMKDIR_PERM 0700
64 #endif
65
66 int
67 x_mkdir_p (const char * path)
68 {
69 if (! path || ! * path)
70 {
71 errno = EINVAL;
72 return -1;
73 }
74
75 size_t len = strnlen (path, SIR_MAXPATH);
76 if (len >= SIR_MAXPATH)
77 {
78 errno = ENAMETOOLONG;
79 return -1;
80 }
81
82 char opath [SIR_MAXPATH];
83 memcpy (opath, path, len + 1);
84
85 #if defined(__MINGW64__) || defined(__MINGW32__)
86
87 if (len >= 3 && ((opath [0] >= 'A' && opath [0] <= 'Z') ||
88 (opath [0] >= 'a' && opath [0] <= 'z')) &&
89 opath [1] == ':' && IS_SEP (opath [2]))
90 {
91 errno = EINVAL;
92 return -1;
93 }
94
95
96 if (len >= 2 && IS_SEP (opath [0]) && IS_SEP (opath [1]))
97 {
98 errno = EINVAL;
99 return -1;
100 }
101
102
103 for (char * q = opath; * q; q++)
104 if (* q == '/')
105 * q = '\\';
106 #endif
107
108
109 while (len > 1 && IS_SEP (opath [len - 1]))
110 opath [--len] = '\0';
111
112
113 char * p = opath;
114 while (IS_SEP(* p))
115 p++;
116
117 for (; * p; p++)
118 {
119 if (IS_SEP(* p))
120 {
121 * p = '\0';
122 if (opath [0] != '\0')
123 {
124 if (MKDIR (opath, XMKDIR_PERM) == -1
125 && errno != EEXIST
126 #if defined(EISDIR)
127 && errno != EISDIR
128 #endif
129 )
130 return -1;
131 }
132 #if defined(__MINGW64__) || defined(__MINGW32__)
133 * p = '\\';
134 #else
135 * p = '/';
136 #endif
137
138 while (IS_SEP (*(p + 1)))
139 p++;
140 }
141 }
142
143 if (MKDIR (opath, XMKDIR_PERM) == -1
144 && errno != EEXIST
145 #if defined(EISDIR)
146 && errno != EISDIR
147 #endif
148 )
149 return -1;
150
151 return 0;
152 }
153
154 char * dump_flags(char * buffer, word18 flags)
155 {
156 (void)sprintf(buffer, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
157 flags & I_HEX ? "Hex " : "",
158 flags & I_ABS ? "Abs " : "",
159 flags & I_MIF ? "MIF " : "",
160 flags & I_TRUNC ? "Trunc " : "",
161 flags & I_NBAR ? "~BAR " : "",
162 flags & I_PMASK ? "PMask " : "",
163 flags & I_PERR ? "PErr" : "",
164 flags & I_TALLY ? "Tally " : "",
165 flags & I_OMASK ? "OMASK " : "",
166 flags & I_EUFL ? "EUFL " : "",
167 flags & I_EOFL ? "EOFL " : "",
168 flags & I_OFLOW ? "Ovr " : "",
169 flags & I_CARRY ? "Carry " : "",
170 flags & I_NEG ? "Neg " : "",
171 flags & I_ZERO ? "Zero " : ""
172 );
173 return buffer;
174 }
175
176 static char * dps8_strupr(char *str)
177 {
178 char *s;
179
180 for(s = str; *s; s++)
181 *s = (char) toupper((unsigned char)*s);
182 return str;
183 }
184
185
186
187 static struct opcode_s unimplented = {"(unimplemented)", 0, 0, 0, 0};
188
189 struct opcode_s * get_iwb_info (DCDstruct * i)
190 {
191 struct opcode_s * p = &opcodes10[i->opcode10];
192 return p->mne ? p : &unimplented;
193 }
194
195 char *disassemble(char * result, word36 instruction)
196 {
197 uint32 opcode = GET_OP(instruction);
198 uint32 opcodeX = GET_OPX(instruction);
199 uint32 opcode10 = opcode | (opcodeX ? 01000 : 0);
200 word18 address = GET_ADDR(instruction);
201 word1 a = GET_A(instruction);
202
203 word6 tag = GET_TAG(instruction);
204
205
206 strcpy(result, "???");
207
208
209 if (opcodes10[opcode10].mne)
210 strcpy(result, opcodes10[opcode10].mne);
211
212
213
214 char buff[256];
215
216 if (a)
217 {
218 int n = (address >> 15) & 07;
219 int offset = address & 077777;
220
221 (void)sprintf (buff, " pr%d|%o", n, offset);
222 strcat (result, buff);
223
224 } else {
225 (void)sprintf (buff, " %06o", address);
226 strcat (result, buff);
227 }
228
229 strcpy(buff, "");
230 for(uint n = 0 ; n < 0100 ; n++)
231 if (extMods[n].mod)
232 if(n == tag)
233 {
234 strncpy(buff, extMods[n].mod, sizeof(buff) - 1);
235 buff[sizeof(buff) - 1] = '\0';
236 break;
237 }
238
239 if (strlen(buff))
240 {
241 strcat(result, ",");
242 strcat(result, buff);
243 }
244
245 return dps8_strupr(result);
246 }
247
248
249
250
251
252
253
254
255 char *get_mod_string(char * msg, word6 tag)
256 {
257 strcpy(msg, "none");
258
259 if (tag >= 0100)
260 {
261 (void)sprintf (msg, "getModReg(tag out-of-range %o)", tag);
262 } else {
263 for(uint n = 0 ; n < 0100 ; n++)
264 if (extMods[n].mod)
265 if(n == tag)
266 {
267 strcpy(msg, extMods[n].mod);
268 break;
269 }
270
271 }
272 return msg;
273 }
274
275
276
277
278
279
280 word36 Add36b (cpu_state_t * cpup, word36 op1, word36 op2, word1 carryin, word18 flagsToSet, word18 * flags, bool * ovf)
281 {
282 CPT (cpt2L, 17);
283 sim_debug (DBG_TRACEEXT, & cpu_dev,
284 "Add36b op1 %012"PRIo64" op2 %012"PRIo64" carryin %o flagsToSet %06o flags %06o\r\n",
285 op1, op2, carryin, flagsToSet, * flags);
286
287
288
289
290 word38 op1e = op1 & MASK36;
291 word38 op2e = op2 & MASK36;
292 word38 ci = carryin ? 1 : 0;
293
294
295 if (op1e & SIGN36)
296 op1e |= BIT37;
297 if (op2e & SIGN36)
298 op2e |= BIT37;
299
300
301 word38 res = op1e + op2e + ci;
302
303
304 bool r37 = res & BIT37 ? true : false;
305 bool r36 = res & SIGN36 ? true : false;
306
307
308 bool r38 = res & BIT38 ? true : false;
309
310
311 * ovf = r37 ^ r36;
312
313
314 bool cry = r38;
315
316
317 res &= MASK36;
318
319 #if defined(PANEL68)
320 if (cry) CPT (cpt2L, 28);
321 if (ovf) CPT (cpt2L, 29);
322 if (!res) CPT (cpt2L, 30);
323 if (res & SIGN36) CPT (cpt2L, 31);
324 #endif
325
326 if (flagsToSet & I_CARRY)
327 {
328 if (cry)
329 SETF (* flags, I_CARRY);
330 else
331 CLRF (* flags, I_CARRY);
332 }
333
334 if (chkOVF (cpup) && (flagsToSet & I_OFLOW))
335 {
336 if (* ovf)
337 SETF (* flags, I_OFLOW);
338 }
339
340 if (flagsToSet & I_ZERO)
341 {
342 if (res)
343 CLRF (* flags, I_ZERO);
344 else
345 SETF (* flags, I_ZERO);
346 }
347
348 if (flagsToSet & I_NEG)
349 {
350 if (res & SIGN36)
351 SETF (* flags, I_NEG);
352 else
353 CLRF (* flags, I_NEG);
354 }
355
356 sim_debug (DBG_TRACEEXT, & cpu_dev, "Add36b res %012"PRIo64" flags %06o ovf %o\r\n", res, * flags, * ovf);
357 return res;
358 }
359
360 word36 Sub36b (cpu_state_t * cpup, word36 op1, word36 op2, word1 carryin, word18 flagsToSet, word18 * flags, bool * ovf)
361 {
362 CPT (cpt2L, 18);
363
364
365
366
367
368
369
370
371
372 word38 op1e = op1 & MASK36;
373 word38 op2e = op2 & MASK36;
374
375 word38 ci = carryin ? 0 : 1;
376
377
378 if (op1e & SIGN36)
379 op1e |= BIT37;
380 if (op2e & SIGN36)
381 op2e |= BIT37;
382
383
384
385
386 word38 res = (word38) (((word38s) op1e) - ((word38s) op2e) - ((word38) ci));
387
388
389 bool r37 = (res & BIT37) ? true : false;
390 bool r36 = (res & SIGN36) ? true : false;
391
392
393 bool r38 = res & BIT38 ? true : false;
394
395
396 res &= MASK36;
397
398
399 * ovf = r37 ^ r36;
400
401
402 bool cry = r38;
403
404 #if defined(PANEL68)
405 if (cry) CPT (cpt2L, 28);
406 if (ovf) CPT (cpt2L, 29);
407 if (!res) CPT (cpt2L, 30);
408 if (res & SIGN36) CPT (cpt2L, 31);
409 #endif
410
411 if (flagsToSet & I_CARRY)
412 {
413 if (cry)
414 CLRF (* flags, I_CARRY);
415 else
416 SETF (* flags, I_CARRY);
417 }
418
419 if (chkOVF (cpup) && (flagsToSet & I_OFLOW))
420 {
421 if (* ovf)
422 SETF (* flags, I_OFLOW);
423 }
424
425 if (flagsToSet & I_ZERO)
426 {
427 if (res)
428 CLRF (* flags, I_ZERO);
429 else
430 SETF (* flags, I_ZERO);
431 }
432
433 if (flagsToSet & I_NEG)
434 {
435 if (res & SIGN36)
436 SETF (* flags, I_NEG);
437 else
438 CLRF (* flags, I_NEG);
439 }
440
441 return res;
442 }
443
444 word18 Add18b (cpu_state_t * cpup, word18 op1, word18 op2, word1 carryin, word18 flagsToSet, word18 * flags, bool * ovf)
445 {
446 CPT (cpt2L, 19);
447
448
449
450
451 word20 op1e = op1 & MASK18;
452 word20 op2e = op2 & MASK18;
453 word20 ci = carryin ? 1 : 0;
454
455
456 if (op1e & SIGN18)
457 op1e |= BIT19;
458 if (op2e & SIGN18)
459 op2e |= BIT19;
460
461
462 word20 res = op1e + op2e + ci;
463
464
465 bool r19 = (res & BIT19) ? true : false;
466 bool r18 = (res & SIGN18) ? true : false;
467
468
469 bool r20 = res & BIT20 ? true : false;
470
471
472 res &= MASK18;
473
474
475 * ovf = r19 ^ r18;
476
477
478 bool cry = r20;
479
480 #if defined(PANEL68)
481 if (cry) CPT (cpt2L, 28);
482 if (ovf) CPT (cpt2L, 29);
483 if (!res) CPT (cpt2L, 30);
484 if (res & SIGN36) CPT (cpt2L, 31);
485 #endif
486
487 if (flagsToSet & I_CARRY)
488 {
489 if (cry)
490 SETF (* flags, I_CARRY);
491 else
492 CLRF (* flags, I_CARRY);
493 }
494
495 if (chkOVF (cpup) && (flagsToSet & I_OFLOW))
496 {
497 if (* ovf)
498 SETF (* flags, I_OFLOW);
499 }
500
501 if (flagsToSet & I_ZERO)
502 {
503 if (res)
504 CLRF (* flags, I_ZERO);
505 else
506 SETF (* flags, I_ZERO);
507 }
508
509 if (flagsToSet & I_NEG)
510 {
511 if (res & SIGN18)
512 SETF (* flags, I_NEG);
513 else
514 CLRF (* flags, I_NEG);
515 }
516
517 return (word18) res;
518 }
519
520 word18 Sub18b (cpu_state_t * cpup, word18 op1, word18 op2, word1 carryin, word18 flagsToSet, word18 * flags, bool * ovf)
521 {
522 CPT (cpt2L, 20);
523
524
525
526
527
528
529
530
531
532 word20 op1e = op1 & MASK18;
533 word20 op2e = op2 & MASK18;
534
535 word20 ci = carryin ? 0 : 1;
536
537
538 if (op1e & SIGN18)
539 op1e |= BIT19;
540 if (op2e & SIGN18)
541 op2e |= BIT19;
542
543
544
545
546 word20 res = (word20) (((word20s) op1e) - ((word20s) op2e) - ((word20s) ci));
547
548
549 bool r19 = res & BIT19 ? true : false;
550 bool r18 = res & SIGN18 ? true : false;
551
552
553 bool r20 = res & BIT20 ? true : false;
554
555
556 res &= MASK18;
557
558
559 * ovf = r19 ^ r18;
560
561
562 bool cry = r20;
563
564 #if defined(PANEL68)
565 if (cry) CPT (cpt2L, 28);
566 if (ovf) CPT (cpt2L, 29);
567 if (!res) CPT (cpt2L, 30);
568 if (res & SIGN36) CPT (cpt2L, 31);
569 #endif
570
571 if (flagsToSet & I_CARRY)
572 {
573 if (cry)
574 CLRF (* flags, I_CARRY);
575 else
576 SETF (* flags, I_CARRY);
577 }
578
579 if (chkOVF (cpup) && (flagsToSet & I_OFLOW))
580 {
581 if (* ovf)
582 SETF (* flags, I_OFLOW);
583 }
584
585 if (flagsToSet & I_ZERO)
586 {
587 if (res)
588 CLRF (* flags, I_ZERO);
589 else
590 SETF (* flags, I_ZERO);
591 }
592
593 if (flagsToSet & I_NEG)
594 {
595 if (res & SIGN18)
596 SETF (* flags, I_NEG);
597 else
598 CLRF (* flags, I_NEG);
599 }
600
601 return res;
602 }
603
604 word72 Add72b (cpu_state_t * cpup, word72 op1, word72 op2, word1 carryin, word18 flagsToSet, word18 * flags, bool * ovf)
605 {
606 CPT (cpt2L, 21);
607
608
609
610
611 #if defined(NEED_128)
612 word74 op1e = and_128 (op1, MASK72);
613 word74 op2e = and_128 (op2, MASK72);
614 word74 ci = construct_128 (0, carryin ? 1 : 0);
615 #else
616 word74 op1e = op1 & MASK72;
617 word74 op2e = op2 & MASK72;
618 word74 ci = carryin ? 1 : 0;
619 #endif
620
621
622 #if defined(NEED_128)
623 if (isnonzero_128 (and_128 (op1e, SIGN72)))
624 op1e = or_128 (op1e, BIT73);
625 if (isnonzero_128 (and_128 (op2e, SIGN72)))
626 op2e = or_128 (op2e, BIT73);
627 #else
628 if (op1e & SIGN72)
629 op1e |= BIT73;
630 if (op2e & SIGN72)
631 op2e |= BIT73;
632 #endif
633
634
635 #if defined(NEED_128)
636 word74 res = add_128 (op1e, add_128 (op2e, ci));
637 #else
638 word74 res = op1e + op2e + ci;
639 #endif
640
641
642 #if defined(NEED_128)
643 bool r73 = isnonzero_128 (and_128 (res, BIT73));
644 bool r72 = isnonzero_128 (and_128 (res, SIGN72));
645 #else
646 bool r73 = res & BIT73 ? true : false;
647 bool r72 = res & SIGN72 ? true : false;
648 #endif
649
650
651 #if defined(NEED_128)
652 bool r74 = isnonzero_128 (and_128 (res, BIT74));
653 #else
654 bool r74 = res & BIT74 ? true : false;
655 #endif
656
657
658 #if defined(NEED_128)
659 res = and_128 (res, MASK72);
660 #else
661 res &= MASK72;
662 #endif
663
664
665 * ovf = r73 ^ r72;
666
667
668 bool cry = r74;
669
670 #if defined(PANEL68)
671 if (cry) CPT (cpt2L, 28);
672 if (ovf) CPT (cpt2L, 29);
673 if (!res) CPT (cpt2L, 30);
674 if (res & SIGN36) CPT (cpt2L, 31);
675 #endif
676
677 if (flagsToSet & I_CARRY)
678 {
679 if (cry)
680 SETF (* flags, I_CARRY);
681 else
682 CLRF (* flags, I_CARRY);
683 }
684
685 if (chkOVF (cpup) && (flagsToSet & I_OFLOW))
686 {
687 if (* ovf)
688 SETF (* flags, I_OFLOW);
689 }
690
691 if (flagsToSet & I_ZERO)
692 {
693 #if defined(NEED_128)
694 if (isnonzero_128 (res))
695 #else
696 if (res)
697 #endif
698 CLRF (* flags, I_ZERO);
699 else
700 SETF (* flags, I_ZERO);
701 }
702
703 if (flagsToSet & I_NEG)
704 {
705 #if defined(NEED_128)
706 if (isnonzero_128 (and_128 (res, SIGN72)))
707 #else
708 if (res & SIGN72)
709 #endif
710 SETF (* flags, I_NEG);
711 else
712 CLRF (* flags, I_NEG);
713 }
714
715 return res;
716 }
717
718 word72 Sub72b (cpu_state_t * cpup, word72 op1, word72 op2, word1 carryin, word18 flagsToSet, word18 * flags, bool * ovf)
719 {
720 CPT (cpt2L, 22);
721 #if defined(NEED_128)
722 sim_debug (DBG_TRACEEXT, & cpu_dev,
723 "Sub72b op1 %012"PRIo64"%012"PRIo64" op2 %012"PRIo64"%012"PRIo64" carryin %o flagsToSet %06o flags %06o\r\n",
724 (word36) ((rshift_128 (op1, 36).l) & MASK36),
725 (word36) (op1.l & MASK36),
726 (word36) (rshift_128 (op2, 36).l & MASK36),
727 (word36) (op2.l & MASK36),
728 carryin, flagsToSet, * flags);
729 #else
730 sim_debug (DBG_TRACEEXT, & cpu_dev,
731 "Sub72b op1 %012"PRIo64"%012"PRIo64" op2 %012"PRIo64"%012"PRIo64" carryin %o flagsToSet %06o flags %06o\r\n",
732 (word36) ((op1 >> 36) & MASK36),
733 (word36) (op1 & MASK36),
734 (word36) ((op2 >> 36) & MASK36),
735 (word36) (op2 & MASK36),
736 carryin, flagsToSet, * flags);
737 #endif
738
739
740
741
742
743
744
745
746
747 #if defined(NEED_128)
748 word74 op1e = and_128 (op1, MASK72);
749 word74 op2e = and_128 (op2, MASK72);
750 #else
751 word74 op1e = op1 & MASK72;
752 word74 op2e = op2 & MASK72;
753 #endif
754
755 #if defined(NEED_128)
756 word74 ci = construct_128 (0, carryin ? 0 : 1);
757 #else
758 word74 ci = carryin ? 0 : 1;
759 #endif
760
761
762 #if defined(NEED_128)
763 if (isnonzero_128 (and_128 (op1e, SIGN72)))
764 op1e = or_128 (op1e, BIT73);
765 if (isnonzero_128 (and_128 (op2e, SIGN72)))
766 op2e = or_128 (op2e, BIT73);
767 #else
768 if (op1e & SIGN72)
769 op1e |= BIT73;
770 if (op2e & SIGN72)
771 op2e |= BIT73;
772 #endif
773
774
775 #if defined(NEED_128)
776 sim_debug (DBG_TRACEEXT, & cpu_dev,
777 "Sub72b op1e %012"PRIo64"%012"PRIo64" op2e %012"PRIo64"%012"PRIo64" carryin %o flagsToSet %06o flags %06o\r\n",
778 (word36) ((rshift_128 (op1e, 36).l) & MASK36),
779 (word36) (op1e.l & MASK36),
780 (word36) (rshift_128 (op2e, 36).l & MASK36),
781 (word36) (op2e.l & MASK36),
782 carryin, flagsToSet, * flags);
783 #else
784 sim_debug (DBG_TRACEEXT, & cpu_dev,
785 "Sub72b op1e %012"PRIo64"%012"PRIo64" op2e %012"PRIo64"%012"PRIo64" carryin %o flagsToSet %06o flags %06o\r\n",
786 (word36) ((op1e >> 36) & MASK36),
787 (word36) (op1e & MASK36),
788 (word36) ((op2e >> 36) & MASK36),
789 (word36) (op2e & MASK36),
790 carryin, flagsToSet, * flags);
791 #endif
792 #if defined(NEED_128)
793 word74 res = subtract_128 (subtract_128 (op1e, op2e), ci);
794 #else
795
796
797 word74 res = (word72) (((word72s) op1e) - ((word72s) op2e) - ((word72s) ci));
798 #endif
799 #if defined(NEED_128)
800 sim_debug (DBG_TRACEEXT, & cpu_dev, "Sub72b res %012"PRIo64"%012"PRIo64" flags %06o ovf %o\r\n",
801 (word36) (rshift_128 (res, 36).l & MASK36), (word36) (res.l & MASK36), * flags, * ovf);
802 #else
803 sim_debug (DBG_TRACEEXT, & cpu_dev, "Sub72b res %012"PRIo64"%012"PRIo64" flags %06o ovf %o\r\n",
804 (word36) ((res >> 36) & MASK36), (word36) (res & MASK36), * flags, * ovf);
805 #endif
806
807
808 #if defined(NEED_128)
809 bool r73 = isnonzero_128 (and_128 (res, BIT73));
810 bool r72 = isnonzero_128 (and_128 (res, SIGN72));
811 #else
812 bool r73 = res & BIT73 ? true : false;
813 bool r72 = res & SIGN72 ? true : false;
814 #endif
815
816
817 #if defined(NEED_128)
818 bool r74 = isnonzero_128 (and_128 (res, BIT74));
819 #else
820 bool r74 = res & BIT74 ? true : false;
821 #endif
822
823
824 #if defined(NEED_128)
825 res = and_128 (res, MASK72);
826 #else
827 res &= MASK72;
828 #endif
829
830
831 * ovf = r73 ^ r72;
832
833
834 bool cry = r74;
835
836 #if defined(PANEL68)
837 if (cry) CPT (cpt2L, 28);
838 if (ovf) CPT (cpt2L, 29);
839 if (!res) CPT (cpt2L, 30);
840 if (res & SIGN36) CPT (cpt2L, 31);
841 #endif
842
843 if (flagsToSet & I_CARRY)
844 {
845 if (cry)
846 CLRF (* flags, I_CARRY);
847 else
848 SETF (* flags, I_CARRY);
849 }
850
851 if (chkOVF (cpup) && (flagsToSet & I_OFLOW))
852 {
853 if (* ovf)
854 SETF (* flags, I_OFLOW);
855 }
856
857 if (flagsToSet & I_ZERO)
858 {
859 #if defined(NEED_128)
860 if (isnonzero_128 (res))
861 #else
862 if (res)
863 #endif
864 CLRF (* flags, I_ZERO);
865 else
866 SETF (* flags, I_ZERO);
867 }
868
869 if (flagsToSet & I_NEG)
870 {
871 #if defined(NEED_128)
872 if (isnonzero_128 (and_128 (res, SIGN72)))
873 #else
874 if (res & SIGN72)
875 #endif
876 SETF (* flags, I_NEG);
877 else
878 CLRF (* flags, I_NEG);
879 }
880
881 #if defined(NEED_128)
882 sim_debug (DBG_TRACEEXT, & cpu_dev, "Sub72b res %012"PRIo64"%012"PRIo64" flags %06o ovf %o\r\n",
883 (word36) (rshift_128 (res, 36).l & MASK36), (word36) (res.l & MASK36), * flags, * ovf);
884 #else
885 sim_debug (DBG_TRACEEXT, & cpu_dev, "Sub72b res %012"PRIo64"%012"PRIo64" flags %06o ovf %o\r\n",
886 (word36) ((res >> 36) & MASK36), (word36) (res & MASK36), * flags, * ovf);
887 #endif
888 return res;
889 }
890
891
892 word36 compl36(cpu_state_t * cpup, word36 op1, word18 *flags, bool * ovf)
893 {
894 CPT (cpt2L, 23);
895
896
897 op1 &= DMASK;
898
899
900
901 word36 res = ((word36) (- ((word36s) op1))) & DMASK;
902
903 * ovf = op1 == MAXNEG;
904
905 #if defined(PANEL68)
906 if (* ovf) CPT (cpt2L, 29);
907 if (!res) CPT (cpt2L, 30);
908 if (res & SIGN36) CPT (cpt2L, 31);
909 #endif
910
911 if (chkOVF (cpup) && * ovf)
912 SETF(*flags, I_OFLOW);
913
914 if (res & SIGN36)
915 SETF(*flags, I_NEG);
916 else
917 CLRF(*flags, I_NEG);
918
919 if (res == 0)
920 SETF(*flags, I_ZERO);
921 else
922 CLRF(*flags, I_ZERO);
923
924 return res;
925 }
926
927
928 word18 compl18(cpu_state_t * cpup, word18 op1, word18 *flags, bool * ovf)
929 {
930 CPT (cpt2L, 24);
931
932
933 op1 &= MASK18;
934
935
936
937 word18 res = ((word18) (- (word18s) op1)) & MASK18;
938
939 * ovf = op1 == MAX18NEG;
940 #if defined(PANEL68)
941 if (* ovf) CPT (cpt2L, 29);
942 if (!res) CPT (cpt2L, 30);
943 if (res & SIGN18) CPT (cpt2L, 31);
944 #endif
945
946 if (chkOVF (cpup) && * ovf)
947 SETF(*flags, I_OFLOW);
948 if (res & SIGN18)
949 SETF(*flags, I_NEG);
950 else
951 CLRF(*flags, I_NEG);
952
953 if (res == 0)
954 SETF(*flags, I_ZERO);
955 else
956 CLRF(*flags, I_ZERO);
957
958 return res;
959 }
960
961 void copyBytes(int posn, word36 src, word36 *dst)
962 {
963 word36 mask = 0;
964
965 if (posn & 8)
966 mask |= 0777000000000LL;
967
968 if (posn & 4)
969 mask |= 0000777000000LL;
970
971 if (posn & 2)
972 mask |= 0000000777000LL;
973
974 if (posn & 1)
975 mask |= 0000000000777LL;
976
977 word36 byteVals = src & mask;
978
979
980 *dst &= ~mask;
981
982
983 *dst |= byteVals;
984 }
985
986 void copyChars(int posn, word36 src, word36 *dst)
987 {
988 word36 mask = 0;
989
990 if (posn & 32)
991 mask |= 0770000000000LL;
992
993 if (posn & 16)
994 mask |= 0007700000000LL;
995
996 if (posn & 8)
997 mask |= 0000077000000LL;
998
999 if (posn & 4)
1000 mask |= 0000000770000LL;
1001
1002 if (posn & 2)
1003 mask |= 0000000007700LL;
1004
1005 if (posn & 1)
1006 mask |= 0000000000077LL;
1007
1008 word36 byteVals = src & mask;
1009
1010
1011 *dst &= ~mask;
1012
1013
1014 *dst |= byteVals;
1015 }
1016
1017
1018
1019
1020 void putByte(word36 *dst, word9 data, int posn)
1021 {
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040 putbits36_9 (dst, (uint) posn * 9, data);
1041 }
1042
1043 void putChar(word36 *dst, word6 data, int posn)
1044 {
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069 putbits36_6 (dst, (uint) posn * 6, data);
1070 }
1071
1072 word72 convert_to_word72(word36 even, word36 odd)
1073 {
1074 #if defined(NEED_128)
1075 return or_128 (lshift_128 (construct_128 (0, even), 36), construct_128 (0, odd));
1076 #else
1077 return ((word72)even << 36) | (word72)odd;
1078 #endif
1079 }
1080
1081 void convert_to_word36 (word72 src, word36 *even, word36 *odd)
1082 {
1083 #if defined(NEED_128)
1084 *even = rshift_128 (src, 36).l & DMASK;
1085 *odd = src.l & DMASK;
1086 #else
1087 *even = (word36)(src >> 36) & DMASK;
1088 *odd = (word36)src & DMASK;
1089 #endif
1090 }
1091
1092 void cmp36(cpu_state_t * cpup, word36 oP1, word36 oP2, word18 *flags)
1093 {
1094 CPT (cpt2L, 25);
1095 L68_ (cpu.ou.cycle |= ou_GOS;)
1096 t_int64 op1 = SIGNEXT36_64(oP1 & DMASK);
1097 t_int64 op2 = SIGNEXT36_64(oP2 & DMASK);
1098
1099 word36 sign1 = (word36) op1 & SIGN36;
1100 word36 sign2 = (word36) op2 & SIGN36;
1101
1102 if ((! sign1) && sign2)
1103 CLRF (* flags, I_ZERO | I_NEG | I_CARRY);
1104
1105 else if (sign1 == sign2)
1106 {
1107 if (op1 > op2)
1108 {
1109 CPT (cpt2L, 28);
1110 SETF (* flags, I_CARRY);
1111 CLRF (* flags, I_ZERO | I_NEG);
1112 }
1113 else if (op1 == op2)
1114 {
1115 CPT (cpt2L, 28);
1116 CPT (cpt2L, 30);
1117 SETF (* flags, I_ZERO | I_CARRY);
1118 CLRF (* flags, I_NEG);
1119 }
1120 else
1121 {
1122 CPT (cpt2L, 31);
1123 SETF (* flags, I_NEG);
1124 CLRF (* flags, I_ZERO | I_CARRY);
1125 }
1126 }
1127 else
1128 {
1129 CPT (cpt2L, 28);
1130 CPT (cpt2L, 31);
1131 SETF (* flags, I_CARRY | I_NEG);
1132 CLRF (* flags, I_ZERO);
1133 }
1134 }
1135
1136 void cmp18(cpu_state_t * cpup, word18 oP1, word18 oP2, word18 *flags)
1137 {
1138 CPT (cpt2L, 26);
1139 L68_ (cpu.ou.cycle |= ou_GOS;)
1140 int32 op1 = SIGNEXT18_32 (oP1 & MASK18);
1141 int32 op2 = SIGNEXT18_32 (oP2 & MASK18);
1142
1143 word18 sign1 = (word18) op1 & SIGN18;
1144 word18 sign2 = (word18) op2 & SIGN18;
1145
1146 if ((! sign1) && sign2)
1147 CLRF (* flags, I_ZERO | I_NEG | I_CARRY);
1148
1149 else if (sign1 == sign2)
1150 {
1151 if (op1 > op2)
1152 {
1153 CPT (cpt2L, 28);
1154 SETF (* flags, I_CARRY);
1155 CLRF (* flags, I_ZERO | I_NEG);
1156 }
1157 else if (op1 == op2)
1158 {
1159 CPT (cpt2L, 28);
1160 CPT (cpt2L, 30);
1161 SETF (* flags, I_ZERO | I_CARRY);
1162 CLRF (* flags, I_NEG);
1163 }
1164 else
1165 {
1166 CPT (cpt2L, 31);
1167 SETF (* flags, I_NEG);
1168 CLRF (* flags, I_ZERO | I_CARRY);
1169 }
1170 }
1171 else
1172 {
1173 CPT (cpt2L, 28);
1174 CPT (cpt2L, 31);
1175 SETF (* flags, I_CARRY | I_NEG);
1176 CLRF (* flags, I_ZERO);
1177 }
1178 }
1179
1180 void cmp36wl(cpu_state_t * cpup, word36 A, word36 Y, word36 Q, word18 *flags)
1181 {
1182 CPT (cpt2L, 26);
1183
1184
1185
1186
1187 L68_ (cpu.ou.cycle |= ou_GOS;)
1188 t_int64 As = (word36s) SIGNEXT36_64(A & DMASK);
1189 t_int64 Ys = (word36s) SIGNEXT36_64(Y & DMASK);
1190 t_int64 Qs = (word36s) SIGNEXT36_64(Q & DMASK);
1191 bool Z = (As <= Ys && Ys <= Qs) || (As >= Ys && Ys >= Qs);
1192
1193 SCF(Z, *flags, I_ZERO);
1194
1195 if (!(Q & SIGN36) && (Y & SIGN36) && (Qs > Ys))
1196 CLRF(*flags, I_NEG | I_CARRY);
1197 else if (((Q & SIGN36) == (Y & SIGN36)) && (Qs >= Ys))
1198 {
1199 CPT (cpt2L, 28);
1200 SETF(*flags, I_CARRY);
1201 CLRF(*flags, I_NEG);
1202 } else if (((Q & SIGN36) == (Y & SIGN36)) && (Qs < Ys))
1203 {
1204 CPT (cpt2L, 31);
1205 CLRF(*flags, I_CARRY);
1206 SETF(*flags, I_NEG);
1207 } else if ((Q & SIGN36) && !(Y & SIGN36) && (Qs < Ys))
1208 {
1209 CPT (cpt2L, 28);
1210 CPT (cpt2L, 31);
1211 SETF(*flags, I_NEG | I_CARRY);
1212 }
1213 }
1214
1215 void cmp72(cpu_state_t * cpup, word72 op1, word72 op2, word18 *flags)
1216 {
1217 CPT (cpt2L, 27);
1218
1219
1220 L68_ (cpu.ou.cycle |= ou_GOS;)
1221 #if defined(NEED_128)
1222 sim_debug (DBG_TRACEEXT, & cpu_dev, "op1 %016"PRIx64"%016"PRIx64"\r\n", op1.h, op1.l);
1223 sim_debug (DBG_TRACEEXT, & cpu_dev, "op2 %016"PRIx64"%016"PRIx64"\r\n", op2.h, op2.l);
1224 int128 op1s = SIGNEXT72_128 (and_128 (op1, MASK72));
1225 int128 op2s = SIGNEXT72_128 (and_128 (op2, MASK72));
1226 sim_debug (DBG_TRACEEXT, & cpu_dev, "op1s %016"PRIx64"%016"PRIx64"\r\n", op1s.h, op1s.l);
1227 sim_debug (DBG_TRACEEXT, & cpu_dev, "op2s %016"PRIx64"%016"PRIx64"\r\n", op2s.h, op2s.l);
1228 #else
1229 sim_debug (DBG_TRACEEXT, & cpu_dev, "op1 %016"PRIx64"%016"PRIx64"\r\n", (uint64_t) (op1>>64), (uint64_t) op1);
1230 sim_debug (DBG_TRACEEXT, & cpu_dev, "op2 %016"PRIx64"%016"PRIx64"\r\n", (uint64_t) (op2>>64), (uint64_t) op2);
1231 int128 op1s = SIGNEXT72_128 (op1 & MASK72);
1232 int128 op2s = SIGNEXT72_128 (op2 & MASK72);
1233 sim_debug (DBG_TRACEEXT, & cpu_dev, "op1s %016"PRIx64"%016"PRIx64"\r\n", (uint64_t) (op1s>>64), (uint64_t) op1s);
1234 sim_debug (DBG_TRACEEXT, & cpu_dev, "op2s %016"PRIx64"%016"PRIx64"\r\n", (uint64_t) (op2s>>64), (uint64_t) op2s);
1235 #endif
1236 #if defined(NEED_128)
1237 if (isgt_s128 (op1s, op2s))
1238 #else
1239 if (op1s > op2s)
1240 #endif
1241 {
1242 #if defined(NEED_128)
1243 if (isnonzero_128 (and_128 (op2, SIGN72)))
1244 #else
1245 if (op2 & SIGN72)
1246 #endif
1247 CLRF (* flags, I_CARRY);
1248 else
1249 {
1250 CPT (cpt2L, 28);
1251 SETF (* flags, I_CARRY);
1252 }
1253 CLRF (* flags, I_ZERO | I_NEG);
1254 }
1255 #if defined(NEED_128)
1256 else if (iseq_128 (cast_128 (op1s), cast_128 (op2s)))
1257 #else
1258 else if (op1s == op2s)
1259 #endif
1260 {
1261 CPT (cpt2L, 28);
1262 CPT (cpt2L, 30);
1263 SETF (* flags, I_CARRY | I_ZERO);
1264 CLRF (* flags, I_NEG);
1265 }
1266 else
1267 {
1268 CPT (cpt2L, 31);
1269 #if defined(NEED_128)
1270 if (isnonzero_128 (and_128 (op1, SIGN72)))
1271 #else
1272 if (op1 & SIGN72)
1273 #endif
1274 {
1275 CPT (cpt2L, 28);
1276 SETF (* flags, I_CARRY);
1277 }
1278 else
1279 CLRF (* flags, I_CARRY);
1280 CLRF (* flags, I_ZERO);
1281 SETF (* flags, I_NEG);
1282 }
1283 }
1284
1285
1286
1287
1288
1289 char * strlower(char *q)
1290 {
1291 char *s = q;
1292
1293 while (*s) {
1294 if (isupper((unsigned char)*s))
1295 *s = (char) tolower(*s);
1296 s++;
1297 }
1298 return q;
1299 }
1300
1301
1302 #define STAR 0
1303 #define NOTSTAR 1
1304 #define RESET 2
1305
1306 int strmask (char * str, char * mask)
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324 {
1325 char * sp, * mp, * reset_string, * reset_mask, * sn;
1326 int state;
1327
1328 sp = str;
1329 mp = mask;
1330
1331 while (1)
1332 {
1333 switch (* mp)
1334 {
1335 case '\0':
1336 return * sp ? false : true;
1337
1338 case '?':
1339 sp ++;
1340 mp ++;
1341 break;
1342
1343 default:
1344 if (* mp == * sp)
1345 {
1346 sp ++;
1347 mp ++;
1348 break;
1349 }
1350 else
1351 {
1352 return false;
1353 }
1354
1355 case '*':
1356 if (* (mp + 1) == '\0')
1357 {
1358 return true;
1359 }
1360 if ((sn = strchr (sp, * (mp + 1))) == NULL)
1361 {
1362 return false;
1363 }
1364
1365
1366
1367 reset_mask = mp;
1368 reset_string = sn + 1;
1369
1370 mp = mp + 2;
1371 sp = sn + 1;
1372 state = NOTSTAR;
1373 while (state == NOTSTAR)
1374 {
1375 switch (* mp)
1376 {
1377 case '\0':
1378 if (* sp == '\0')
1379 return false;
1380 else
1381 state = RESET;
1382 break;
1383 case '?':
1384 sp ++;
1385 mp ++;
1386 break;
1387 default:
1388 if (* mp == * sp)
1389 {
1390 sp ++;
1391 mp ++;
1392 }
1393 else
1394 state = RESET;
1395 break;
1396 case '*':
1397 state = STAR;
1398 break;
1399 }
1400 }
1401
1402 if (state == RESET)
1403 {
1404 sp = reset_string;
1405 mp = reset_mask;
1406 }
1407 break;
1408 }
1409 }
1410 #if defined(SUNLINT) || !defined(__SUNPRO_C) && !defined(__SUNPRO_CC)
1411
1412 return false;
1413 #endif
1414 }
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514 char *rtrim(char *s)
1515 {
1516 if (! s)
1517 return s;
1518 int index;
1519
1520
1521 for (index = (int)strlen(s) - 1; index >= 0 && isspace((unsigned char)s[index]); index--)
1522 {
1523 s[index] = '\0';
1524 }
1525 return(s);
1526 }
1527
1528 char *ltrim(char *s)
1529
1530
1531
1532 {
1533 char *p;
1534 if (s == NULL)
1535 return NULL;
1536
1537
1538 for (p = s; isspace((unsigned char)*p) && *p != '\0'; p++)
1539 ;
1540
1541
1542 memmove(s, p, strlen(p) + 1);
1543 return(s);
1544 }
1545
1546 char *trim(char *s)
1547 {
1548 return ltrim(rtrim(s));
1549 }
1550
1551 char *
1552 stripquotes(char *s)
1553 {
1554 if (! s || ! *s)
1555 return s;
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565 int nLast = (int)strlen(s) - 1;
1566
1567 if (s[0] == '"')
1568 s[0] = ' ';
1569 if (s[nLast] == '"')
1570 s[nLast] = ' ';
1571 return trim(s);
1572 }
1573
1574 #include <ctype.h>
1575
1576
1577
1578
1579 int cfg_parse (const char * tag, const char * cptr, config_list_t * clist, config_state_t * state, int64_t * result)
1580 {
1581 if (! cptr)
1582 return -2;
1583 char * start = NULL;
1584 if (! state -> copy)
1585 {
1586 state -> copy = strdup (cptr);
1587 if (! state->copy)
1588 {
1589 (void)fprintf (stderr, "\rFATAL: Out of memory! Aborting at %s[%s:%d]\r\n",
1590 __func__, __FILE__, __LINE__);
1591 #if defined(USE_BACKTRACE)
1592 # if defined(SIGUSR2)
1593 (void)raise(SIGUSR2);
1594
1595 # endif
1596 #endif
1597 abort();
1598 }
1599 start = state -> copy;
1600 state -> statement_save = NULL;
1601 }
1602
1603 int ret = -2;
1604
1605
1606 char * statement;
1607 statement = strtok_r (start, ";", & state -> statement_save);
1608 start = NULL;
1609 if (! statement)
1610 {
1611 ret = -1;
1612 goto done;
1613 }
1614
1615
1616 char * name_start = statement;
1617 char * name_save = NULL;
1618 char * name;
1619 name = strtok_r (name_start, "=", & name_save);
1620 if (! name)
1621 {
1622 sim_printf ("error: %s: can't parse name\r\n", tag);
1623 goto done;
1624 }
1625
1626
1627 config_list_t * p = clist;
1628 while (p -> name)
1629 {
1630 if (strcasecmp (name, p -> name) == 0)
1631 break;
1632 p ++;
1633 }
1634 if (! p -> name)
1635 {
1636 sim_printf ("error: %s: don't know name <%s>\r\n", tag, name);
1637 goto done;
1638 }
1639
1640
1641 char * value;
1642 value = strtok_r (NULL, "", & name_save);
1643 if (! value)
1644 {
1645
1646
1647 if (p -> min > p -> max && ! p -> value_list)
1648 {
1649 return (int) (p - clist);
1650 }
1651 sim_printf ("error: %s: can't parse value\r\n", tag);
1652 goto done;
1653 }
1654
1655
1656 config_value_list_t * v = p -> value_list;
1657 if (v)
1658 {
1659 while (v -> value_name)
1660 {
1661 if (strcasecmp (value, v -> value_name) == 0)
1662 break;
1663 v ++;
1664 }
1665
1666
1667 if (v -> value_name)
1668 {
1669 * result = v -> value;
1670 return (int) (p - clist);
1671 }
1672 }
1673
1674
1675 if (p -> min > p -> max)
1676 {
1677 sim_printf ("error: %s: can't parse value\r\n", tag);
1678 goto done;
1679 }
1680
1681 if (strlen (value) == 0)
1682 {
1683 sim_printf ("error: %s: missing value\r\n", tag);
1684 goto done;
1685 }
1686 char * endptr;
1687 int64_t n = strtoll (value, & endptr, 0);
1688 if (* endptr)
1689 {
1690 sim_printf ("error: %s: can't parse value\r\n", tag);
1691 goto done;
1692 }
1693
1694
1695 if (n < p -> min || n > p -> max)
1696 {
1697 sim_printf ("error: %s: value out of range\r\n", tag);
1698 goto done;
1699 }
1700
1701 * result = n;
1702 return (int) (p - clist);
1703
1704 done:
1705 FREE (state -> copy);
1706 state -> copy = NULL;
1707 return ret;
1708 }
1709
1710 void cfg_parse_done (config_state_t * state)
1711 {
1712 if (state -> copy)
1713 FREE (state -> copy);
1714 state -> copy = NULL;
1715 }
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754 char * strdupesc (const char * str)
1755 {
1756 char * buf = strdup (str);
1757 if (!buf)
1758 {
1759 (void)fprintf(stderr, "\rFATAL: Out of memory! Aborting at %s[%s:%d]\r\n",
1760 __func__, __FILE__, __LINE__);
1761 #if defined(USE_BACKTRACE)
1762 # if defined(SIGUSR2)
1763 (void)raise(SIGUSR2);
1764
1765 # endif
1766 #endif
1767 abort();
1768 }
1769 char * p = buf;
1770 while (* p)
1771 {
1772 if (* p != '\\')
1773 {
1774 p ++;
1775 continue;
1776 }
1777 if (p [1] == '\\')
1778 * p = '\\';
1779 else if (p [1] == 'a')
1780 * p = '\001';
1781 else if (p [1] == 'w')
1782 * p = '\\';
1783 else if (p [1] == 'n')
1784 * p = '\n';
1785 else if (p [1] == 't')
1786 * p = '\t';
1787 else if (p [1] == 'f')
1788 * p = '\f';
1789 else if (p [1] == 'r')
1790 * p = '\r';
1791 else if (p [1] == 'e')
1792 * p = '\005';
1793 else if (p [1] == '_')
1794
1795
1796 * p = ' ';
1797 else if (p [1] == 'c')
1798 * p = ',';
1799 else if (p [1] == 's')
1800 * p = ';';
1801 else if (p [1] == 'd')
1802 * p = '$';
1803 else if (p [1] == 'q')
1804 * p = '"';
1805 else if (p [1] == 'z')
1806 * p = '\004';
1807 else if (p [1] == 'k')
1808 * p = '^';
1809 else if (p [1] == 'x')
1810 * p = '\030';
1811 else if (p [1] == 'y')
1812 * p = '\031';
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832 else
1833 {
1834 p ++;
1835 continue;
1836 }
1837 p ++;
1838 memmove (p, p + 1, strlen (p + 1) + 1);
1839 }
1840 return buf;
1841 }
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873 static word36 extrASCII36 (uint8 * bits, uint woffset)
1874 {
1875 uint8 * p = bits + woffset * 4;
1876
1877 uint64 w;
1878 w = ((uint64) p [0]) << 27;
1879 w |= ((uint64) p [1]) << 18;
1880 w |= ((uint64) p [2]) << 9;
1881 w |= ((uint64) p [3]);
1882
1883 return (word36) (w & MASK36);
1884 }
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895 word36 extr36 (uint8 * bits, uint woffset)
1896 {
1897 uint isOdd = woffset % 2;
1898 uint dwoffset = woffset / 2;
1899 uint8 * p = bits + dwoffset * 9;
1900
1901 uint64 w;
1902 if (isOdd)
1903 {
1904 w = (((uint64) p [4]) & 0xf) << 32;
1905 w |= ((uint64) p [5]) << 24;
1906 w |= ((uint64) p [6]) << 16;
1907 w |= ((uint64) p [7]) << 8;
1908 w |= ((uint64) p [8]);
1909 }
1910 else
1911 {
1912 w = ((uint64) p [0]) << 28;
1913 w |= ((uint64) p [1]) << 20;
1914 w |= ((uint64) p [2]) << 12;
1915 w |= ((uint64) p [3]) << 4;
1916 w |= (((uint64) p [4]) >> 4) & 0xf;
1917 }
1918
1919 return (word36) (w & MASK36);
1920 }
1921
1922 static void putASCII36 (word36 val, uint8 * bits, uint woffset)
1923 {
1924 uint8 * p = bits + woffset * 4;
1925 p [0] = (val >> 27) & 0xff;
1926 p [1] = (val >> 18) & 0xff;
1927 p [2] = (val >> 9) & 0xff;
1928 p [3] = (val ) & 0xff;
1929 }
1930
1931 void put36 (word36 val, uint8 * bits, uint woffset)
1932 {
1933 uint isOdd = woffset % 2;
1934 uint dwoffset = woffset / 2;
1935 uint8 * p = bits + dwoffset * 9;
1936
1937 if (isOdd)
1938 {
1939 p [4] &= 0xf0;
1940 p [4] |= (val >> 32) & 0x0f;
1941 p [5] = (val >> 24) & 0xff;
1942 p [6] = (val >> 16) & 0xff;
1943 p [7] = (val >> 8) & 0xff;
1944 p [8] = (val >> 0) & 0xff;
1945
1946
1947
1948
1949
1950 }
1951 else
1952 {
1953 p [0] = (val >> 28) & 0xff;
1954 p [1] = (val >> 20) & 0xff;
1955 p [2] = (val >> 12) & 0xff;
1956 p [3] = (val >> 4) & 0xff;
1957 p [4] &= 0x0f;
1958 p [4] |= (val << 4) & 0xf0;
1959
1960
1961
1962
1963
1964 }
1965
1966 }
1967
1968 int extractASCII36FromBuffer (uint8 * bufp, t_mtrlnt tbc, uint * words_processed, word36 *wordp)
1969 {
1970 uint wp = * words_processed;
1971
1972
1973
1974 uint bytes_processed = wp * 4;
1975 if (bytes_processed >= tbc)
1976 return 1;
1977
1978
1979 * wordp = extrASCII36 (bufp, wp);
1980
1981
1982 (* words_processed) ++;
1983
1984 return 0;
1985 }
1986
1987 int extractWord36FromBuffer (uint8 * bufp, t_mtrlnt tbc, uint * words_processed, word36 *wordp)
1988 {
1989 uint wp = * words_processed;
1990
1991
1992
1993 uint bytes_processed = (wp * 9 + 1) / 2;
1994 if (bytes_processed >= tbc)
1995 return 1;
1996
1997
1998 * wordp = extr36 (bufp, wp);
1999
2000
2001 (* words_processed) ++;
2002
2003 return 0;
2004 }
2005
2006 int insertASCII36toBuffer (uint8 * bufp, t_mtrlnt tbc, uint * words_processed, word36 word)
2007 {
2008 uint wp = * words_processed;
2009
2010
2011
2012 uint bytes_processed = wp * 4;
2013 if (bytes_processed >= tbc)
2014 return 1;
2015
2016
2017 putASCII36 (word, bufp, wp);
2018
2019 (* words_processed) ++;
2020
2021 return 0;
2022 }
2023
2024 int insertWord36toBuffer (uint8 * bufp, t_mtrlnt tbc, uint * words_processed, word36 word)
2025 {
2026 uint wp = * words_processed;
2027
2028
2029
2030 uint bytes_processed = (wp * 9 + 1) / 2;
2031 if (bytes_processed >= tbc)
2032 return 1;
2033
2034
2035 put36 (word, bufp, wp);
2036
2037 (* words_processed) ++;
2038
2039 return 0;
2040 }
2041
2042 #if !defined(NEED_128)
2043 static void print_uint128o_r (uint128 n, char * p)
2044 {
2045 if (n == 0)
2046 return;
2047
2048 print_uint128o_r(n / 8, p);
2049 if (p)
2050 {
2051 char s [2];
2052 s [0] = n % 8 + '0';
2053 s [1] = '\0';
2054 strcat (p, s);
2055 }
2056 else
2057 sim_printf("%c", (int) (n%8+0x30));
2058 }
2059
2060 char * print_int128o (int128 n, char * p)
2061 {
2062 if (n == 0)
2063 {
2064 if (p)
2065 strcat (p, "0");
2066 else
2067 sim_printf ("0");
2068 return p;
2069 }
2070 print_uint128o_r ((uint128) n, p);
2071 return p;
2072 }
2073
2074 static void print_uint128_r (uint128 n, char * p)
2075 {
2076 if (n == 0)
2077 return;
2078
2079 print_uint128_r(n / 10, p);
2080 if (p)
2081 {
2082 char s [2];
2083 s [0] = n % 10 + '0';
2084 s [1] = '\0';
2085 strcat (p, s);
2086 }
2087 else
2088 sim_printf("%c", (int) (n%10+0x30));
2089 }
2090
2091 void print_int128 (int128 n, char * p)
2092 {
2093 if (n == 0)
2094 {
2095 if (p)
2096 strcat (p, "0");
2097 else
2098 sim_printf ("0");
2099 return;
2100 }
2101 if (n < 0)
2102 {
2103 if (p)
2104 strcat (p, "-");
2105 else
2106 sim_printf ("-");
2107 n = -n;
2108 }
2109 print_uint128_r ((uint128) n, p);
2110 }
2111 #endif
2112
2113 void timespec_diff(struct timespec * start, struct timespec * stop,
2114 struct timespec * result)
2115 {
2116 if ((stop->tv_nsec - start->tv_nsec) < 0) {
2117 result->tv_sec = stop->tv_sec - start->tv_sec - 1;
2118 result->tv_nsec = stop->tv_nsec - start->tv_nsec + 1000000000L;
2119 } else {
2120 result->tv_sec = stop->tv_sec - start->tv_sec;
2121 result->tv_nsec = stop->tv_nsec - start->tv_nsec;
2122 }
2123
2124 return;
2125 }
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159