MFMv2.0.10
Movable Feast Machine Simulator 2.0.10
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
P1Atom.h
Go to the documentation of this file.
1 /* -*- mode:C++ -*-
2  P1Atom.h A partial reimplementation, now deprecated, of the original MFM atom
3  Copyright (C) 2014 The Regents of the University of New Mexico. All rights reserved.
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
18  USA
19 */
20 
28 #ifndef P1ATOM_H
29 #define P1ATOM_H
30 
31 #include <stdio.h>
32 #include "itype.h"
33 #include "Point.h"
34 #include "BitVector.h"
35 #include "MDist.h"
36 #include "Atom.h"
37 #include "Element.h"
38 #include "Element_Empty.h"
39 #include "CoreConfig.h"
40 #include "ParamConfig.h"
41 
42 #define P1ATOM_HEADER_SIZE 16
43 #define P1ATOM_LONG_BOND_SIZE 8
44 #define P1ATOM_SHORT_BOND_SIZE 4
45 
46 
47 namespace MFM {
48 
49  template <class PC>
50  class P1Atom : public Atom< CoreConfig< P1Atom<PC>, PC> >
51  {
52  public: enum { ATOM_CATEGORY = 1 };
53  private:
54 
55  enum {
56  BITS = 64,
57  // For now we insist on exact match. Possibly longer could be
58  // supported relatively easily.
59  CONFIGURED_BITS_PER_ATOM_IS_INCOMPATIBLE_WITH_P1ATOM = 1/((PC::BITS_PER_ATOM==BITS)?1:0)
60  };
61 
62  protected:
63 
64  typedef MDist<4> MDist4;
65  typedef CoreConfig< P1Atom<PC>, PC> CC;
66 
67  /* We really don't want to allow the public to change the type of a
68  p1atom, since the type doesn't mean much without the atomic
69  header as well */
70 
71  void SetType(u32 type, u32 width)
72  {
73  this->m_bits.Write(BITS-width, width, type);
74  }
75 
76  public:
77 
78  bool IsSane() const
79  {
80  return GetBitsAllocated() <= BITS;
81  }
82 
83  bool HasBeenRepaired()
84  {
85  // We can't fix an insane atom.
86  return false;
87  }
88 
89 
90  u32 GetBitCount() const {
91  return BITS;
92  }
93 
94  u32 GetType() const {
95  s32 bitsUsed = GetBitsAllocated();
96  if (bitsUsed > BITS)
97  FAIL(ILLEGAL_STATE);
98 
99  // The up-to 31 bits left over after everything else are the type bits
100  u32 typeBits = BITS-bitsUsed;
101  if (typeBits > 31) typeBits = 31;
102  return this->m_bits.Read(BITS-typeBits,typeBits);
103  }
104 
105  void WriteStateBits(ByteSink& ostream) const
106  {
107  s32 bitsUsed = GetBitsAllocated();
108 
109  u32 typeBits = BITS - bitsUsed;
110  if(typeBits > 31) typeBits = 31;
111 
112  u32 leftoverBits = BITS - typeBits;
113 
114  for(u32 i = 0; i < leftoverBits; i++)
115  {
116  ostream.Printf("%d", this->m_bits.ReadBit(i) ? 1 : 0);
117  }
118  }
119 
120  void ReadStateBits(const char* stateStr)
121  {
122  u32 len = strlen(stateStr);
123 
124  for(u32 i = 0; i < len; i++)
125  {
126  this->m_bits.WriteBit(i, stateStr[i] == '0' ? 0 : 1);
127  }
128  }
129 
130  void ReadStateBits(const BitVector<BITS> & bv)
131  {
132  s32 bitsUsed = GetBitsAllocated();
133 
134  u32 typeBits = BITS - bitsUsed;
135  if(typeBits > 31) typeBits = 31;
136 
137  u32 leftoverBits = BITS - typeBits;
138 
139  for(u32 i = 0; i < leftoverBits; i++)
140  {
141  this->m_bits.WriteBit(i, bv.ReadBit(i));
142  }
143  }
144 
145 
146  P1Atom()
147  {
148  InitAtom(0,0,0,32);
149  }
150 
151  P1Atom(u32 type, u32 longc, u32 shortc, u32 statec)
152  {
153  InitAtom(type,longc,shortc,statec);
154  }
155 
156  void InitAtom(u32 type, u32 longc, u32 shortc, u32 statec)
157  {
158  FAIL(DEPRECATED);
159 
160  SetLongBondCount(longc);
161  SetShortBondCount(shortc);
162  SetStateBitCount(statec);
163  u32 used = GetBitsAllocated();
164 
165  if (used > BITS)
166  FAIL(ILLEGAL_ARGUMENT);
167 
168  u32 avail = BITS - used;
169  if (avail > 31) avail = 31;
170 
171  if (type >= 1u<<avail)
172  FAIL(ILLEGAL_ARGUMENT);
173  SetType(type, avail);
174 
175  if (statec > 32) {
176  SetStateField(32,statec-32,0);
177  statec = 32;
178  }
179  SetStateField(0,statec,0);
180 
181  }
182 
183  u32 GetBitsAllocated() const
184  {
185  return
186  P1ATOM_HEADER_SIZE+
187  GetLongBondCount()*P1ATOM_LONG_BOND_SIZE
188  + GetShortBondCount()*P1ATOM_SHORT_BOND_SIZE
189  + GetStateBitCount();
190  }
191 
192  u32 GetBitsAllocatedExceptState() const
193  {
194  return
195  P1ATOM_HEADER_SIZE+
196  GetLongBondCount()*P1ATOM_LONG_BOND_SIZE
197  + GetShortBondCount()*P1ATOM_SHORT_BOND_SIZE;
198  }
199 
200  u32 GetStateBitCount() const
201  { return this->m_bits.Read(2, 6); }
202 
203  void SetStateBitCount(u32 state)
204  { this->m_bits.Write(2, 6, state); }
205 
210  u32 GetStateField(u32 stateIndex, u32 stateWidth) const
211  {
212  // The state bits end at the end of the 'allocated bits'
213  u32 firstState = GetBitsAllocatedExceptState();
214  return this->m_bits.Read(firstState+stateIndex, stateWidth);
215  }
216 
222  void SetStateField(u32 stateIndex, u32 stateWidth, u32 value)
223  {
224  u32 firstState = GetBitsAllocatedExceptState();
225  return this->m_bits.Write(firstState+stateIndex, stateWidth, value);
226  }
227 
228  u32 GetLongBondCount() const
229  { return this->m_bits.Read(9, 3); }
230 
231  void SetLongBondCount(u32 count)
232  { this->m_bits.Write(9, 3, count); }
233 
234  u32 GetShortBondCount() const
235  { return this->m_bits.Read(12, 4); }
236 
237  void SetShortBondCount(u32 count)
238  { this->m_bits.Write(12, 4, count); }
239 
240  u32 GetLongBond(u32 index) const {
241  if (index>=GetLongBondCount()) return 0;
242  return this->m_bits.Read(16+index*8,8);
243  }
244  void SetLongBond(u32 index, u8 value) {
245  if (index>=GetLongBondCount()) return;
246  return this->m_bits.Write(16+index*8,8,(u32) value);
247  }
248 
249  u32 GetShortBond(u32 index) const {
250  if (index>=GetShortBondCount()) return 0;
251  u32 start = GetLongBondCount()*8+16;
252  return this->m_bits.Read(start+index*4,4);
253  }
254  void SetShortBond(u32 index, u8 value) {
255  if (index>=GetLongBondCount()) return;
256  u32 start = GetLongBondCount()*8+16;
257  return this->m_bits.Write(start+index*4,4,(u32) value);
258  }
259 
260  void ReadVariableBodyInto(u32* arr) const
261  {
262  arr[0] = this->m_bits.Read(16, 16);
263  arr[1] = this->m_bits.Read(32, 32);
264  }
265 
266  void WriteVariableBodyFrom(u32* arr)
267  {
268  this->m_bits.Write(16, 16, arr[0]);
269  this->m_bits.Write(32, 32, arr[1]);
270  }
271 
272  void PrintBits(ByteSink & ostream) const
273  { this->m_bits.Print(ostream); }
274 
275  void Print(ByteSink & ostream) const
276  {
277  u32 type = GetType();
278  u32 lbc = GetLongBondCount();
279  u32 sbc = GetShortBondCount();
280  u32 stc = GetStateBitCount();
281  u32 state = GetStateField(0,stc>32?32:stc);
282  ostream.Printf("P1[%x/%d%d/%d:%x]", type,lbc,sbc,stc,state);
283  }
284 
285 #if 0
286  /* Adds a long bond. Returns its index. */
287  u32 AddLongBond(const SPoint& offset);
288 
289  u32 AddShortBond(const SPoint& offset);
290 #endif
291 
296  bool GetLongBond(u32 index, SPoint& pt) const;
297 
302  bool GetShortBond(u32 index, SPoint& pt) const;
303 
308  bool SetLongBond(u32 index, const SPoint& pt);
309 
314  bool SetShortBond(u32 index, const SPoint& pt);
315 
316  /*
317  * Removes a long bond. Be careful; if a
318  * bond is removed, the bonds ahead of it
319  * (if they exist) will be pushed downwards.
320  * The indices of these bonds will need to
321  * be updated again afterwards.
322  */
323  void RemoveLongBond(u32 index);
324 
325  void RemoveShortBond(u32 index);
326 
327  P1Atom& operator=(const P1Atom & rhs);
328  };
329 } /* namespace MFM */
330 
331 #include "P1Atom.tcc"
332 
333 #endif /*P1ATOM_H*/
void Write(const u32 startIdx, const u32 length, const u32 value)
Definition: BitVector.tcc:99
u32 Read(const u32 startIdx, const u32 length) const
Definition: BitVector.tcc:129
Definition: Atom.h:71
void WriteBit(u32 idx, bool bit)
Definition: BitVector.tcc:41
Definition: CoreConfig.h:40
void Print(ByteSink &ostream) const
Definition: BitVector.tcc:202
void SetStateField(u32 stateIndex, u32 stateWidth, u32 value)
Definition: P1Atom.h:222
u32 GetStateField(u32 stateIndex, u32 stateWidth) const
Definition: P1Atom.h:210
Definition: ByteSink.h:47
Definition: MDist.h:69
bool ReadBit(u32 idx)
Definition: BitVector.tcc:65
Definition: P1Atom.h:50
Definition: BitVector.h:47
BitVector< BPA > m_bits
Definition: Atom.h:99