1 /* pdp10_xtnd.c: PDP-10 extended instruction simulator
3 Copyright (c) 1993-2005, Robert M Supnik
5 Permission is hereby granted, free of charge, to any person obtaining a
6 copy of this software and associated documentation files (the "Software"),
7 to deal in the Software without restriction, including without limitation
8 the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 and/or sell copies of the Software, and to permit persons to whom the
10 Software is furnished to do so, subject to the following conditions:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of Robert M Supnik shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from Robert M Supnik.
26 12-May-01 RMS Fixed compiler warning in xlate
28 Instructions handled in this module:
30 MOVSLJ move string left justified
31 MOVSO move string offset
32 MOVST move string translated
33 MOVSRJ move string right justified
34 CMPSL compare string, skip on less
35 CMPSE compare string, skip on equal
36 CMPSLE compare string, skip on less or equal
37 CMPSGE compare string, skip on greater or equal
38 CMPSN compare string, skip on unequal
39 CMPSG compare string, skip on greater
40 CVTDBO convert decimal to binary offset
41 CVTDBT convert decimal to binary translated
42 CVTBDO convert binary to decimal offset
43 CVTBDT convert binary to decimal translated
46 The PDP-10 extended instructions deal with non-binary data types,
47 particularly byte strings and decimal strings. (In the KL10, the
48 extended instructions include G floating support as well.) They
49 are very complicated microcoded subroutines that can potentially
50 run for a very long time. Accordingly, the instructions must test
51 for interrupts as well as page faults, and be prepared to restart
54 In general, the simulator attempts to keep the AC block up to date,
55 so that page fails and interrupts can be taken directly at any point.
56 If the AC block is not up to date, memory accessibility must be tested
57 before the actual read or write is done.
59 The extended instruction routine returns a status code as follows:
61 XT_NOSK no skip completion
62 XT_SKIP skip completion
63 XT_MUUO invalid extended instruction
66 #include "pdp10_defs.h"
69 #define MM_XSRC (pflgs & XSRC_PXCT)
70 #define MM_XDST (pflgs & XDST_PXCT)
71 #define MM_EA_XSRC ((pflgs & EA_PXCT) && MM_XSRC)
72 #define MM_EA_XDST ((pflgs & EA_PXCT) && MM_XDST)
74 #define XT_CMPSL 001 /* opcodes */
90 /* Translation control */
92 #define XT_LFLG 0400000000000 /* L flag */
93 #define XT_SFLG 0400000000000 /* S flag */
94 #define XT_NFLG 0200000000000 /* N flag */
95 #define XT_MFLG 0100000000000 /* M flag */
97 /* Translation table */
99 #define XT_V_CODE 15 /* translation op */
101 #define XT_BYMASK 07777 /* byte mask */
102 #define XT_DGMASK 017 /* digit mask */
103 #define XT_GETCODE(x) ((int32) (((x) >> XT_V_CODE) & XT_M_CODE))
107 #define XLNTMASK 0000777777777 /* length */
108 #define XFLGMASK 0700000000000 /* flags */
109 #define XT_MBZ 0777000000000 /* must be zero */
110 #define XT_MBZE 0047777000000 /* must be zero, edit */
112 /* Register change log */
114 #define XT_N_RLOG 5 /* entry width */
115 #define XT_M_RLOG ((1 << XT_N_RLOG) - 1) /* entry mask */
116 #define XT_O_RLOG 1 /* entry offset */
117 #define XT_INSRLOG(x,v) v = ((v << XT_N_RLOG) | (((x) + XT_O_RLOG) & XT_M_RLOG))
118 #define XT_REMRLOG(x,v) x = (v & XT_M_RLOG) - XT_O_RLOG; \
123 #define ED_V_PBYN 30 /* pattern byte # */
125 #define ED_PBYNO 0040000000000 /* overflow bit */
126 #define ED_GETPBYN(x) ((int32) (((x) >> ED_V_PBYN) & ED_M_PBYN))
127 #define ED_V_POPC 6 /* pattern byte opcode */
128 #define ED_M_PAT 0777 /* pattern byte mask */
129 #define ED_M_NUM 0077 /* number for msg, etc */
130 #define ED_PBYTE(x,y) ((int32) (((x) >> (27 - (ED_GETPBYN (y) * 9))) & ED_M_PAT))
131 #define ED_STOP 0000 /* stop */
132 #define ED_SELECT 0001 /* select source */
133 #define ED_SIGST 0002 /* start significance */
134 #define ED_FLDSEP 0003 /* field separator */
135 #define ED_EXCHMD 0004 /* exchange mark, dst */
136 #define ED_MESSAG 0100 /* message */
137 #define ED_SKPM 0500 /* skip if M */
138 #define ED_SKPN 0600 /* skip if N */
139 #define ED_SKPA 0700 /* skip always */
141 extern d10
*ac_cur
; /* current AC block */
142 extern const d10 bytemask
[64];
145 extern jmp_buf save_env
;
147 extern d10
Read (int32 ea
, int32 prv
);
148 extern void Write (int32 ea
, d10 val
, int32 prv
);
149 extern a10
calc_ea (d10 inst
, int32 prv
);
150 extern int32
test_int (void);
152 d10
incloadbp (int32 ac
, int32 pflgs
);
153 void incstorebp (d10 val
, int32 ac
, int32 pflgs
);
154 d10
xlate (d10 by
, a10 tblad
, d10
*xflgs
, int32 pflgs
);
155 void filldst (d10 fill
, int32 ac
, d10 cnt
, int32 pflgs
);
157 static const d10 pwrs10
[23][2] = {
177 29103830, 15693250560,
178 291038304, 19493552128,
179 2910383045, 23136829440,
180 29103830456, 25209864192
183 int xtend (int32 ac
, int32 ea
, int32 pflgs
)
186 d10 xinst
, xoff
, digit
, f1
, f2
, rs
[2];
189 int32 p1
= ADDAC (ac
, 1);
190 int32 p3
= ADDAC (ac
, 3);
191 int32 p4
= ADDAC (ac
, 4);
192 int32 flg
, i
, s2
, t
, pp
, pat
, xop
, xac
, ret
;
194 xinst
= Read (ea
, MM_OPND
); /* get extended instr */
195 xop
= GET_OP (xinst
); /* get opcode */
196 xac
= GET_AC (xinst
); /* get AC */
197 if (xac
|| (xop
== 0) || (xop
> XT_MOVSRJ
)) return XT_MUUO
;
198 rlog
= 0; /* clear log */
199 switch (xop
) { /* case on opcode */
201 /* String compares - checked against KS10 ucode
202 If both strings are zero length, they are considered equal.
203 Both source and destination lengths are MBZ checked.
206 AC + 1 = source1 byte pointer
207 AC + 3 = source2 length
208 AC + 4 = source2 byte pointer
211 case XT_CMPSL
: /* CMPSL */
212 case XT_CMPSE
: /* CMPSE */
213 case XT_CMPSLE
: /* CMPSLE */
214 case XT_CMPSGE
: /* CMPSGE */
215 case XT_CMPSN
: /* CMPSN */
216 case XT_CMPSG
: /* CMPSG */
217 if ((AC(ac
) | AC(p3
)) & XT_MBZ
) return XT_MUUO
; /* check length MBZ */
218 f1
= Read (ADDA (ea
, 1), MM_OPND
) & bytemask
[GET_S (AC(p1
))];
219 f2
= Read (ADDA (ea
, 2), MM_OPND
) & bytemask
[GET_S (AC(p4
))];
221 for (flg
= 0; (AC(ac
) | AC(p3
)) && (b1
== b2
); flg
++) {
222 if (flg
&& (t
= test_int ())) ABORT (t
);
223 rlog
= 0; /* clear log */
224 if (AC(ac
)) b1
= incloadbp (p1
, pflgs
); /* src1 */
226 if (AC(p3
)) b2
= incloadbp (p4
, pflgs
); /* src2 */
228 if (AC(ac
)) AC(ac
) = (AC(ac
) - 1) & XLNTMASK
;
229 if (AC(p3
)) AC(p3
) = (AC(p3
) - 1) & XLNTMASK
;
233 return (b1
< b2
)? XT_SKIP
: XT_NOSK
;
235 return (b1
== b2
)? XT_SKIP
: XT_NOSK
;
237 return (b1
<= b2
)? XT_SKIP
: XT_NOSK
;
239 return (b1
>= b2
)? XT_SKIP
: XT_NOSK
;
241 return (b1
!= b2
)? XT_SKIP
: XT_NOSK
;
243 return (b1
> b2
)? XT_SKIP
: XT_NOSK
;
248 /* Convert binary to decimal instructions - checked against KS10 ucode
249 There are no MBZ tests.
251 AC'AC + 1 = double precision integer source
252 AC + 3 = flags and destination length
253 AC + 4 = destination byte pointer
256 case XT_CVTBDO
: /* CVTBDO */
257 case XT_CVTBDT
: /* CVTBDT */
258 e1
= calc_ea (xinst
, MM_EA
); /* get ext inst addr */
259 if (xop
== XT_CVTBDO
) /* offset? */
260 xoff
= (e1
& RSIGN
)? (e1
| LMASK
): e1
; /* get offset */
261 rs
[0] = AC(ac
); /* get src opnd */
262 rs
[1] = CLRS (AC(p1
));
263 if (!TSTF (F_FPD
)) { /* set up done yet? */
264 if (TSTS (AC(ac
))) { DMOVN (rs
); } /* get abs value */
265 for (i
= 22; i
> 1; i
--) { /* find field width */
266 if (DCMPGE (rs
, pwrs10
[i
])) break;
268 if (i
> (AC(p3
) & XLNTMASK
)) return XT_NOSK
;
269 if ((i
< (AC(p3
) & XLNTMASK
)) && (AC(p3
) & XT_LFLG
)) {
270 f1
= Read (ADDA (ea
, 1), MM_OPND
);
271 filldst (f1
, p3
, (AC(p3
) & XLNTMASK
) - i
, pflgs
);
273 else AC(p3
) = (AC(p3
) & XFLGMASK
) | i
;
274 if (TSTS (AC(ac
))) AC(p3
) = AC(p3
) | XT_MFLG
;
275 if (AC(ac
) | AC(p1
)) AC(p3
) = AC(p3
) | XT_NFLG
;
276 AC(ac
) = rs
[0]; /* update state */
278 SETF (F_FPD
); /* mark set up done */
281 /* Now do actual binary to decimal conversion */
283 for (flg
= 0; AC(p3
) & XLNTMASK
; flg
++) {
284 if (flg
&& (t
= test_int ())) ABORT (t
);
285 rlog
= 0; /* clear log */
286 i
= (int32
) AC(p3
) & XLNTMASK
; /* get length */
287 if (i
> 22) i
= 22; /* put in range */
288 for (digit
= 0; (digit
< 10) && DCMPGE (rs
, pwrs10
[i
]); digit
++) {
289 rs
[0] = rs
[0] - pwrs10
[i
][0] - (rs
[1] < pwrs10
[i
][1]);
290 rs
[1] = (rs
[1] - pwrs10
[i
][1]) & MMASK
;
292 if (xop
== XT_CVTBDO
) digit
= (digit
+ xoff
) & DMASK
;
294 f1
= Read (e1
+ (int32
) digit
, MM_OPND
);
295 if ((i
== 1) && (AC(p3
) & XT_LFLG
)) f1
= f1
>> 18;
298 incstorebp (digit
, p4
, pflgs
); /* store digit */
299 AC(ac
) = rs
[0]; /* mem access ok */
300 AC(p1
) = rs
[1]; /* update state */
301 AC(p3
) = (AC(p3
) & XFLGMASK
) | ((AC(p3
) - 1) & XLNTMASK
);
303 CLRF (F_FPD
); /* clear FPD */
306 /* Convert decimal to binary instructions - checked against KS10 ucode
307 There are no MBZ tests.
309 AC = flags and source length
310 AC + 1 = source byte pointer
311 AC + 3'AC + 4 = double precision integer result
314 case XT_CVTDBT
: /* CVTDBT */
315 case XT_CVTDBO
: /* CVTDBO */
316 e1
= calc_ea (xinst
, MM_EA
); /* get ext inst addr */
317 if ((AC(ac
) & XT_SFLG
) == 0) AC(p3
) = AC(p4
) = 0; /* !S? clr res */
318 else AC(p4
) = CLRS (AC(p4
)); /* clear low sign */
319 if (xop
== XT_CVTDBO
) { /* offset? */
320 xoff
= (e1
& RSIGN
)? (e1
| LMASK
): e1
; /* get offset */
321 AC(ac
) = AC(ac
) | XT_SFLG
; /* set S flag */
323 xflgs
= AC(ac
) & XFLGMASK
; /* get xlation flags */
324 for (flg
= 0; AC(ac
) & XLNTMASK
; flg
++) {
325 if (flg
&& (t
= test_int ())) ABORT (t
);
326 rlog
= 0; /* clear log */
327 b1
= incloadbp (p1
, pflgs
); /* get byte */
328 if (xop
== XT_CVTDBO
) b1
= (b1
+ xoff
) & DMASK
;
330 b1
= xlate (b1
, e1
, &xflgs
, MM_OPND
);
331 if (b1
< 0) { /* terminated? */
332 AC(ac
) = xflgs
| ((AC(ac
) - 1) & XLNTMASK
);
333 if (TSTS (AC(p3
))) AC(p4
) = SETS (AC(p4
));
336 if (xflgs
& XT_SFLG
) b1
= b1
& XT_DGMASK
;
339 AC(ac
) = xflgs
| ((AC(ac
) - 1) & XLNTMASK
);
340 if ((b1
< 0) || (b1
> 9)) { /* bad digit? done */
341 if (TSTS (AC(p3
))) AC(p4
) = SETS (AC(p4
));
344 AC(p4
) = (AC(p4
) * 10) + b1
; /* base * 10 + digit */
345 AC(p3
) = ((AC(p3
) * 10) + (AC(p4
) >> 35)) & DMASK
;
346 AC(p4
) = AC(p4
) & MMASK
;
348 if (AC(ac
) & XT_MFLG
) {
349 AC(p4
) = -AC(p4
) & MMASK
;
350 AC(p3
) = (~AC(p3
) + (AC(p4
) == 0)) & DMASK
;
352 if (TSTS (AC(p3
))) AC(p4
) = SETS (AC(p4
));
355 /* String move instructions - checked against KS10 ucode
356 Only the destination length is MBZ checked.
358 AC = flags (MOVST only) and source length
359 AC + 1 = source byte pointer
360 AC + 3 = destination length
361 AC + 4 = destination byte pointer
364 case XT_MOVSO
: /* MOVSO */
365 case XT_MOVST
: /* MOVST */
366 case XT_MOVSRJ
: /* MOVSRJ */
367 case XT_MOVSLJ
: /* MOVSLJ */
368 if (AC(p3
) & XT_MBZ
) return XT_MUUO
; /* test dst lnt MBZ */
369 f1
= Read (ADDA (ea
, 1), MM_OPND
); /* get fill */
370 switch (xop
) { /* case on instr */
372 case XT_MOVSO
: /* MOVSO */
373 AC(ac
) = AC(ac
) & XLNTMASK
; /* trim src length */
374 xoff
= calc_ea (xinst
, MM_EA
); /* get offset */
375 if (xoff
& RSIGN
) xoff
= xoff
| LMASK
; /* sign extend 18b */
376 s2
= GET_S (AC(p4
)); /* get dst byte size */
379 case XT_MOVST
: /* MOVST */
380 e1
= calc_ea (xinst
, MM_EA
); /* get xlate tbl addr */
383 case XT_MOVSRJ
: /* MOVSRJ */
384 AC(ac
) = AC(ac
) & XLNTMASK
; /* trim src length */
385 if (AC(p3
) == 0) return (AC(ac
)? XT_NOSK
: XT_SKIP
);
386 if (AC(ac
) > AC(p3
)) { /* adv src ptr */
387 for (flg
= 0; AC(ac
) > AC(p3
); flg
++) {
388 if (flg
&& (t
= test_int ())) ABORT (t
);
389 AC(p1
) = incbp (AC(p1
));
390 AC(ac
) = (AC(ac
) - 1) & XLNTMASK
;
393 else if (AC(ac
) < AC(p3
))
394 filldst (f1
, p3
, AC(p3
) - AC(ac
), pflgs
);
397 case XT_MOVSLJ
: /* MOVSLJ */
398 AC(ac
) = AC(ac
) & XLNTMASK
; /* trim src length */
402 xflgs
= AC(ac
) & XFLGMASK
; /* get xlation flags */
403 if (AC(p3
) == 0) return (AC(ac
)? XT_NOSK
: XT_SKIP
);
404 for (flg
= 0; AC(p3
) & XLNTMASK
; flg
++) {
405 if (flg
&& (t
= test_int ())) ABORT (t
);
406 rlog
= 0; /* clear log */
407 if (AC(ac
) & XLNTMASK
) { /* any source? */
408 b1
= incloadbp (p1
, pflgs
); /* src byte */
409 if (xop
== XT_MOVSO
) { /* offset? */
410 b1
= (b1
+ xoff
) & DMASK
; /* test fit */
411 if (b1
& ~bytemask
[s2
]) {
412 AC(ac
) = xflgs
| ((AC(ac
) - 1) & XLNTMASK
);
416 else if (xop
== XT_MOVST
) { /* translate? */
417 b1
= xlate (b1
, e1
, &xflgs
, MM_OPND
);
418 if (b1
< 0) { /* upd flags in AC */
419 AC(ac
) = xflgs
| ((AC(ac
) - 1) & XLNTMASK
);
422 if (xflgs
& XT_SFLG
) b1
= b1
& XT_BYMASK
;
427 if (b1
>= 0) { /* valid byte? */
428 incstorebp (b1
, p4
, pflgs
); /* store byte */
429 AC(p3
) = (AC(p3
) - 1) & XLNTMASK
; /* update state */
431 if (AC(ac
) & XLNTMASK
) AC(ac
) = xflgs
| ((AC(ac
) - 1) & XLNTMASK
);
433 return (AC(ac
) & XLNTMASK
)? XT_NOSK
: XT_SKIP
;
435 /* Edit - checked against KS10 ucode
436 Only the flags/pattern pointer word is MBZ checked.
438 AC = flags, pattern pointer
439 AC + 1 = source byte pointer
440 AC + 3 = mark address
441 AC + 4 = destination byte pointer
444 case XT_EDIT
: /* EDIT */
445 if (AC(ac
) & XT_MBZE
) return XT_MUUO
; /* check pattern MBZ */
446 xflgs
= AC(ac
) & XFLGMASK
; /* get xlation flags */
447 e1
= calc_ea (xinst
, MM_EA
); /* get xlate tbl addr */
448 for (ppi
= 1, ret
= -1, flg
= 0; ret
< 0; flg
++, ppi
= 1) {
449 if (flg
&& (t
= test_int ())) ABORT (t
);
450 rlog
= 0; /* clear log */
451 pp
= (int32
) AC(ac
) & AMASK
; /* get pattern ptr */
452 b1
= Read (pp
, MM_OPND
); /* get pattern word */
453 pat
= ED_PBYTE (b1
, AC(ac
)); /* get pattern byte */
454 switch ((pat
< 0100)? pat
: ((pat
>> ED_V_POPC
) + 0100)) {
456 case ED_STOP
: /* stop */
457 ret
= XT_SKIP
; /* exit loop */
460 case ED_SELECT
: /* select source */
461 b1
= incloadbp (p1
, pflgs
); /* get src */
462 entad
= (e1
+ ((int32
) b1
>> 1)) & AMASK
;
463 f1
= ((Read (entad
, MM_OPND
) >> ((b1
& 1)? 0: 18)) & RMASK
);
466 (i
& 1)? xflgs
| XT_MFLG
: xflgs
& ~XT_MFLG
;
469 case 00: case 02: case 03:
470 if (xflgs
& XT_SFLG
) f1
= f1
& XT_BYMASK
;
472 f1
= Read (INCA (ea
), MM_OPND
);
475 incstorebp (f1
, p4
, pflgs
);
479 ret
= XT_NOSK
; /* exit loop */
482 case 04: case 06: case 07:
483 xflgs
= xflgs
| XT_NFLG
;
485 if ((xflgs
& XT_SFLG
) == 0) {
486 f2
= Read (ADDA (ea
, 2), MM_OPND
);
487 Write ((a10
) AC(p3
), AC(p4
), MM_OPND
);
488 if (f2
) incstorebp (f2
, p4
, pflgs
);
489 xflgs
= xflgs
| XT_SFLG
;
491 incstorebp (f1
, p4
, pflgs
);
495 xflgs
= xflgs
| XT_NFLG
;
496 ret
= XT_NOSK
; /* exit loop */
498 } /* end case xlate op */
501 case ED_SIGST
: /* start significance */
502 if ((xflgs
& XT_SFLG
) == 0) {
503 f2
= Read (ADDA (ea
, 2), MM_OPND
);
504 Write ((a10
) AC(p3
), AC(p4
), MM_OPND
);
505 if (f2
) incstorebp (f2
, p4
, pflgs
);
506 xflgs
= xflgs
| XT_SFLG
;
510 case ED_FLDSEP
: /* separate fields */
514 case ED_EXCHMD
: /* exchange */
515 f2
= Read ((int32
) (AC(p3
) & AMASK
), MM_OPND
);
516 Write ((int32
) (AC(p3
) & AMASK
), AC(p4
), MM_OPND
);
520 case (0100 + (ED_MESSAG
>> ED_V_POPC
)): /* message */
522 f1
= Read (ea
+ (pat
& ED_M_NUM
) + 1, MM_OPND
);
524 f1
= Read (ea
+ 1, MM_OPND
);
527 incstorebp (f1
, p4
, pflgs
);
530 case (0100 + (ED_SKPM
>> ED_V_POPC
)): /* skip on M */
531 if (xflgs
& XT_MFLG
) ppi
= (pat
& ED_M_NUM
) + 2;
534 case (0100 + (ED_SKPN
>> ED_V_POPC
)): /* skip on N */
535 if (xflgs
& XT_NFLG
) ppi
= (pat
& ED_M_NUM
) + 2;
538 case (0100 + (ED_SKPA
>> ED_V_POPC
)): /* skip always */
539 ppi
= (pat
& ED_M_NUM
) + 2;
542 default: /* NOP or undefined */
544 } /* end case pttrn op */
545 AC(ac
) = AC(ac
) + ((ppi
& ED_M_PBYN
) << ED_V_PBYN
);
546 AC(ac
) = AC(ac
) + (ppi
>> 2) + ((AC(ac
) & ED_PBYNO
)? 1: 0);
547 AC(ac
) = xflgs
| (AC(ac
) & ~(XT_MBZE
| XFLGMASK
));
554 /* Supporting subroutines */
556 /* Increment byte pointer, register version */
562 p
= GET_P (bp
); /* get P and S */
564 p
= p
- s
; /* adv P */
565 if (p
< 0) { /* end of word? */
566 bp
= (bp
& LMASK
) | (INCR (bp
)); /* increment addr */
567 p
= (36 - s
) & 077; /* reset P */
569 bp
= PUT_P (bp
, p
); /* store new P */
573 /* Increment and load byte, extended version - uses register log */
575 d10
incloadbp (int32 ac
, int32 pflgs
)
581 bp
= AC(ac
) = incbp (AC(ac
)); /* increment bp */
582 XT_INSRLOG (ac
, rlog
); /* log change */
583 p
= GET_P (bp
); /* get P and S */
585 ba
= calc_ea (bp
, MM_EA_XSRC
); /* calc bp eff addr */
586 wd
= Read (ba
, MM_XSRC
); /* read word */
587 wd
= (wd
>> p
) & bytemask
[s
]; /* get byte */
591 /* Increment and deposit byte, extended version - uses register log */
593 void incstorebp (d10 val
, int32 ac
, int32 pflgs
)
599 bp
= AC(ac
) = incbp (AC(ac
)); /* increment bp */
600 XT_INSRLOG (ac
, rlog
); /* log change */
601 p
= GET_P (bp
); /* get P and S */
603 ba
= calc_ea (bp
, MM_EA_XDST
); /* calc bp eff addr */
604 wd
= Read (ba
, MM_XDST
); /* read, write test */
605 mask
= bytemask
[s
] << p
; /* shift mask, val */
607 wd
= (wd
& ~mask
) | (val
& mask
); /* insert byte */
608 Write (ba
, wd
& DMASK
, MM_XDST
);
615 by = byte to translate
616 tblad = virtual address of translation table
617 *xflgs = pointer to word containing translation flags
618 prv = previous mode flag for table lookup
620 xby = >= 0, translated byte
621 < 0, terminate translation
624 d10
xlate (d10 by
, a10 tblad
, d10
*xflgs
, int32 prv
)
630 ea
= (tblad
+ ((int32
) by
>> 1)) & AMASK
;
631 tblent
= ((Read (ea
, prv
) >> ((by
& 1)? 0: 18)) & RMASK
);
632 tcode
= XT_GETCODE (tblent
); /* get xlate code */
636 return (*xflgs
& XT_SFLG
)? tblent
: by
;
642 *xflgs
= *xflgs
& ~XT_MFLG
;
643 return (*xflgs
& XT_SFLG
)? tblent
: by
;
646 *xflgs
= *xflgs
| XT_MFLG
;
647 return (*xflgs
& XT_SFLG
)? tblent
: by
;
650 *xflgs
= *xflgs
| XT_SFLG
| XT_NFLG
;
654 *xflgs
= *xflgs
| XT_NFLG
;
658 *xflgs
= (*xflgs
| XT_SFLG
| XT_NFLG
) & ~XT_MFLG
;
662 *xflgs
= *xflgs
| XT_SFLG
| XT_NFLG
| XT_MFLG
;
669 /* Fill out the destination string
673 ac = 2 word AC block (length, byte pointer)
678 void filldst (d10 fill
, int32 ac
, d10 cnt
, int32 pflgs
)
681 int32 p1
= ADDA (ac
, 1);
683 for (i
= 0; i
< cnt
; i
++) {
684 if (i
&& (t
= test_int ())) ABORT (t
);
685 rlog
= 0; /* clear log */
686 incstorebp (fill
, p1
, pflgs
);
687 AC(ac
) = (AC(ac
) & XFLGMASK
) | ((AC(ac
) - 1) & XLNTMASK
);
693 /* Clean up after page fault
696 logv = register change log
698 For each register in logv, decrement the register's contents as
699 though it were a byte pointer. Note that the KS10 does <not>
700 do a full decrement calculation but merely adds S to P.
703 void xtcln (int32 logv
)
708 XT_REMRLOG (reg
, logv
); /* get next reg */
709 if ((reg
>= 0) && (reg
< AC_NUM
)) {
710 p
= GET_P (AC(reg
)) + GET_S (AC(reg
)); /* get p + s */
711 AC(reg
) = PUT_P (AC(reg
), p
); /* p <- p + s */