forked from virtualagc/virtualagc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPAR.cpp
134 lines (134 loc) · 3.87 KB
/
PAR.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/****************************************************************************
* PAR - PARITY GENERATION AND TEST subsystem
*
* AUTHOR: John Pultorak
* DATE: 9/22/01
* FILE: PAR.cpp
*
* NOTES: see header file.
*
*****************************************************************************
*/
#include "PAR.h"
#include "SEQ.h"
#include "BUS.h"
#include "MBF.h"
#include "ADR.h"
#include "MEM.h"
regP PAR::register_P;
regP2 PAR::register_P2;
regG15 PAR::register_G15; // memory buffer register bit 15
regPALM PAR::register_PALM; // PARITY ALARM FF
unsigned PAR::conv_WP[] =
{ BX, SG, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1 };
void
PAR::execRP_WE()
{
// Write parity into memory.
MEM::MEM_PARITY_BUS = PAR::register_G15.read();
}
// IMPLEMENTATION NOTE: It has been empirically determined that the following
// control signals are mutually exclusive (there is never more than one of these
// generated at any time):
// GP, WGX, RP2, SBWG, CLG
// NOTE: WP clears register_P before writing into it. Strictly speaking, WPx isn't
// supposed to clear the register (should OR into the register), but in the counter
// sequences where WPx is used, register_P is always cleared in the previous TP by
// asserting WP with default zeroes on the write bus.
void
PAR::execWP_WP()
{
// set all bits except parity bit
register_P.writeShift(BUS::glbl_WRITE_BUS, PAR::conv_WP);
// now set parity bit; in the actual AGC, this is
// a single operation.
if (SEQ::isAsserted(RG))
register_P.writeField(16, 16, register_G15.read());
else
register_P.writeField(16, 16, 0); // clear parity bit
}
void
PAR::execWP_WPx()
{
// set all bits except parity bit
register_P.writeShift(BUS::glbl_WRITE_BUS, PAR::conv_WP);
// now set parity bit; in the actual AGC, this is
// a single operation.
if (SEQ::isAsserted(RG))
register_P.writeField(16, 16, register_G15.read());
else
register_P.writeField(16, 16, 0); // clear parity bit
}
void
PAR::execWP_WP2()
{
register_P2.write(gen1_15Parity(register_P.read()));
}
void
PAR::execWP_RP2()
{
register_G15.write(register_P2.read());
}
void
PAR::execWP_GP()
{
register_G15.write(gen1_15Parity(register_P.read()));
}
void
PAR::execWP_SBWG()
{
register_G15.write(MEM::MEM_PARITY_BUS); // load memory bit 16 (parity) into G15
}
void
PAR::execWP_WGx()
{
// This is only used in PINC, MINC, and SHINC. Does not clear G
// register; writes (ORs) into G from RWBus and writes into parity
// from 1-15 generator. All done in one operation, although I show
// it in two steps here. The sequence calls CLG in a previous TP.
register_G15.write(PAR::gen1_15Parity(register_P.read()));
}
void
PAR::execWP_CLG()
{
register_G15.write(0);
}
void
PAR::execWP_GENRST()
{
register_PALM.write(0);
}
void
PAR::execWP_TP()
{
if (ADR::GTR_27() && genP_15Parity(register_P.read()))
register_PALM.write(genP_15Parity(register_P.read()));
}
void
PAR::CLR_PALM()
{
// asynchronous clear for PARITY ALARM (from MON)
register_PALM.clear();
}
unsigned
PAR::gen1_15Parity(unsigned r)
{
//check the lower 15 bits of 'r' and return the odd parity;
//bit 16 is ignored.
unsigned evenParity = (1 & (r >> 0)) ^ (1 & (r >> 1)) ^ (1 & (r >> 2))
^ (1 & (r >> 3)) ^ (1 & (r >> 4)) ^ (1 & (r >> 5)) ^ (1 & (r >> 6))
^ (1 & (r >> 7)) ^ (1 & (r >> 8)) ^ (1 & (r >> 9)) ^ (1 & (r >> 10))
^ (1 & (r >> 11)) ^ (1 & (r >> 12)) ^ (1 & (r >> 13)) ^ (1 & (r >> 14));
return ~evenParity & 1; // odd parity
}
unsigned
PAR::genP_15Parity(unsigned r)
{
//check all 16 bits of 'r' and return the odd parity
unsigned evenParity = (1 & (r >> 0)) ^ (1 & (r >> 1)) ^ (1 & (r >> 2))
^ (1 & (r >> 3)) ^ (1 & (r >> 4)) ^ (1 & (r >> 5)) ^ (1 & (r >> 6))
^ (1 & (r >> 7)) ^ (1 & (r >> 8)) ^ (1 & (r >> 9)) ^ (1 & (r >> 10))
^ (1 & (r >> 11)) ^ (1 & (r >> 12)) ^ (1 & (r >> 13)) ^ (1 & (r >> 14))
^ (1 & (r >> 15));
return ~evenParity & 1; // odd parity
}