Merge pull request #3 from schuay/not_known
[simavr] / simavr / sim / sim_regbit.h
index 1f74197..4852b56 100644 (file)
 
 #include "sim_avr.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define ARRAY_SIZE(_aa) (sizeof(_aa) / sizeof((_aa)[0]))
 
-/*
- * this 'structure' is a packed representation of an IO register 'bit'
- * (or consecutive bits). This allows a way to set/get/clear them.
- * gcc is happy passing these as register value, so you don't need to
- * use a pointer when passing them along to functions.
- *
- * 9 bits ought to be enough, as it's the maximum I've seen (atmega2560)
- */
-typedef struct avr_regbit_t {
-       unsigned long reg : 9, bit : 3, mask : 8;
-} avr_regbit_t;
 
 /*
  * These accessors are inlined and are used to perform the operations on
@@ -67,6 +60,19 @@ static inline uint8_t avr_regbit_setto(avr_t * avr, avr_regbit_t rb, uint8_t v)
        return (avr->data[a] >> rb.bit) & rb.mask;
 }
 
+/*
+ * Set the 'raw' bits, if 'v' is the unshifted value of the bits
+ */
+static inline uint8_t avr_regbit_setto_raw(avr_t * avr, avr_regbit_t rb, uint8_t v)
+{
+       uint8_t a = rb.reg;
+       if (!a)
+               return 0;
+       uint8_t m = rb.mask << rb.bit;
+       avr_core_watch_write(avr, a, (avr->data[a] & ~(m)) | ((v) & m));
+       return (avr->data[a]) & (rb.mask << rb.bit);
+}
+
 static inline uint8_t avr_regbit_get(avr_t * avr, avr_regbit_t rb)
 {
        uint8_t a = rb.reg;
@@ -76,6 +82,18 @@ static inline uint8_t avr_regbit_get(avr_t * avr, avr_regbit_t rb)
        return (avr->data[a] >> rb.bit) & rb.mask;
 }
 
+/*
+ * Return the bit(s) 'in position' instead of zero based
+ */
+static inline uint8_t avr_regbit_get_raw(avr_t * avr, avr_regbit_t rb)
+{
+       uint8_t a = rb.reg;
+       if (!a)
+               return 0;
+       //uint8_t m = rb.mask << rb.bit;
+       return (avr->data[a]) & (rb.mask << rb.bit);
+}
+
 static inline uint8_t avr_regbit_clear(avr_t * avr, avr_regbit_t rb)
 {
        uint8_t a = (rb.reg);
@@ -104,5 +122,8 @@ static inline uint8_t avr_regbit_get_array(avr_t * avr, avr_regbit_t *rb, int co
 #define AVR_IO_REGBIT(_io, _bit) { . reg = (_io), .bit = (_bit), .mask = 1 }
 #define AVR_IO_REGBITS(_io, _bit, _mask) { . reg = (_io), .bit = (_bit), .mask = (_mask) }
 
+#ifdef __cplusplus
+};
+#endif
 
 #endif /* __SIM_REGBIT_H__ */