1 /*
2 * vim: filetype=c:tabstop=4:ai:expandtab
3 * SPDX-License-Identifier: ICU
4 * scspell-id: 506d89bb-f62d-11ec-b87a-80ee73e9b8e7
5 *
6 * ---------------------------------------------------------------------------
7 *
8 * Copyright (c) 2013-2017 Charles Anthony
9 * Copyright (c) 2021-2022 The DPS8M Development Team
10 *
11 * All rights reserved.
12 *
13 * This software is made available under the terms of the ICU
14 * License, version 1.8.1 or later. For more details, see the
15 * LICENSE.md file at the top-level directory of this distribution.
16 *
17 * ---------------------------------------------------------------------------
18 */
19
20 // Appending unit stuff .......
21
22 // Once segno and offset are formed in TPR.SNR and TPR.CA, respectively, the
23 // process of generating the 24-bit absolute main memory address can involve a
24 // number of different and distinct appending unit cycles.
25 //
26 // The operation of the appending unit is shown in the flowchart in Figure 5-4.
27 // This flowchart assumes that directed faults, store faults, and parity faults
28 // do not occur.
29 //
30 // A segment boundary check is made in every cycle except PSDW. If a boundary
31 // violation is detected, an access violation, out of segment bounds, fault is
32 // generated and the execution of the instruction interrupted. The occurrence
33 // of any fault interrupts the sequence at the point of occurrence. The
34 // operating system software should store the control unit data for possible
35 // later continuation and attempt to resolve the fault condition.
36 //
37 // The value of the associative memories may be seen in the flowchart by
38 // observing the number of appending unit cycles bypassed if an SDW or PTW is
39 // found in the associative memories.
40 //
41 // There are nine different appending unit cycles that involve accesses to main
42 // memory. Two of these (FANP, FAP) generate the 24-bit absolute main memory
43 // address and initiate a main memory access for the operand, indirect word, or
44 // instruction pair; five (NSDW, PSDW, PTW, PTW2, and DSPTW) generate a main
45 // memory access to fetch an SDW or PTW; and two (MDSPTW and MPTW) generate a
46 // main memory access to update page status bits (PTW.U and PTW.M) in a PTW.
47 // The cycles are defined in Table 5-1.
48
49 // enum _appendingUnit_cycle_type {
50 // apuCycle_APPUNKNOWN = 0, // unknown
51 //
52 // apuCycle_FIAP, // Fetch instruction
53 //
54 // apuCycle_FANP, // Final address nonpaged.
55 // // Generates the 24-bit absolute main memory address and
56 // // initiates a main memory access to an unpaged segment for
57 // // operands, indirect words, or instructions.
58 //
59 // apuCycle_FAP, // Final address paged
60 // // Generates the 24-bit absolute main memory address and
61 // // initiates a main memory access to a paged segment for
62 // // operands, indirect words, or instructions.
63 //
64 // apuCycle_NSDW, // Nonpaged SDW Fetch
65 // // Fetches an SDW from an unpaged descriptor segment.
66 //
67 // apuCycle_PSDW, // Paged SDW Fetch
68 // // Fetches an SDW from a paged descriptor segment.
69 //
70 // apuCycle_PTWfetch, // PTW fetch
71 // // Fetches a PTW from a page table other than a descriptor
72 // // segment page table and sets the page accessed bit (PTW.U).
73 //
74 // apuCycle_PTW2, // Prepage PTW fetch
75 // // Fetches the next PTW from a page table other than a
76 // // descriptor segment page table during hardware prepaging for
77 // // certain uninterruptible EIS instructions. This cycle does
78 // // not load the next PTW into the appending unit. It merely
79 // // assures that the PTW is not faulted (PTW.F = 1) and that
80 // // the target page will be in main memory when and if needed
81 // // by the instruction.
82 //
83 // apuCycle_DSPTW, // Descriptor segment PTW fetch
84 // // Fetches a PTW from a descriptor segment page table.
85 //
86 // apuCycle_MDSPTW, // Modify DSPTW
87 // // Sets the page accessed bit (PTW.U) in the PTW for a page
88 // // in a descriptor segment page table. This cycle always
89 // // immediately follows a DSPTW cycle.
90 //
91 // apuCycle_MPTW // Modify PTW
92 // // Sets the page modified bit (PTW.M) in the PTW for a page
93 // // in other than a descriptor segment page table.
94 // };
95
96 // These bits are aligned to match the CU word 0 APU status bit positions.
97 // This produces some oddness in the scu save/restore code.
98
99 typedef enum apuStatusBits
100 {
101 apuStatus_PI_AP = 1u << (35 - 24), // -AP Instruction fetch append cycle
102 apuStatus_DSPTW = 1u << (35 - 25), // Fetch descriptor segment PTW
103 apuStatus_SDWNP = 1u << (35 - 26), // Fetch SDW non paged
104 apuStatus_SDWP = 1u << (35 - 27), // Fetch SDW paged
105 apuStatus_PTW = 1u << (35 - 28), // Fetch PTW
106 apuStatus_PTW2 = 1u << (35 - 29), // Fetch prepage PTW
107 apuStatus_FAP = 1u << (35 - 30), // Fetch final address - paged
108 apuStatus_FANP = 1u << (35 - 31), // Fetch final address - nonpaged
109 apuStatus_FABS = 1u << (35 - 32), // Fetch final address - absolute
110
111 // XXX these don't seem like the right solution.
112 // XXX there are MDSPTW and MPTW bits in the APU history
113 // register, but not in the CU.
114
115 apuStatus_MDSPTW = 1u << (35 - 25), // Fetch descriptor segment PTW
116 apuStatus_MPTW = 1u << (35 - 28) // Fetch PTW
117 } apuStatusBits;
118
119 static inline void set_apu_status (apuStatusBits status)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
120 {
121 word12 FCT = cpu.cu.APUCycleBits & MASK3;
122 cpu.cu.APUCycleBits = (status & 07770) | FCT;
123 }
124
125 #ifdef TESTING
126 t_stat dump_sdwam (void);
127 #endif
128 word24 do_append_cycle (processor_cycle_type thisCycle,
129 word36 * data, uint nWords);
130 void do_ldbr (word36 * Ypair);
131 void do_sdbr (word36 * Ypair);
132 void do_camp (word36 Y);
133 void do_cams (word36 Y);
134 #ifdef TESTING
135 int dbgLookupAddress (word18 segno, word18 offset, word24 * finalAddress,
136 char * * msg);
137 #endif
138 sdw0_s * getSDW (word15 segno);
139
140 static inline void fauxDoAppendCycle (processor_cycle_type thisCycle)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
141 {
142 cpu.apu.lastCycle = thisCycle;
143 }