/* The "g" below really should be an "i", but gcc doesn't believe that it will
* always be an immediate value. Using "g" makes the compiler be quiet, but
- * the assembler will fail if the value is not an immediate.
+ * the assembler should fail if the value is not an immediate.
*/
-extern inline void bset(void* addr, u8 mask) {
+extern inline void bset(const void* addr, const u8 mask) {
+ /* The assembly breaks when gcc tries to optimise consecutive calls to
+ * bset/bclr on the same memory address. Sigh. Either turn off optimisation
+ * (-O1 without -Os works), or we do it the dumb way.
+ */
+ //*(u8*)addr |= mask;
asm volatile (
"ldx %0\n"
- "bset 00,x,%1"
- : /* outputs */
- : "p" (addr), "g" (mask) /* inputs */
+ "bset 00,x,%1\n"
+ : "=m" (addr) /* outputs */
+ : "g" (mask) /* inputs */
: "x" /* altered registers */
- );
+ );
}
-extern inline void bclr(void* addr, u8 mask) {
+extern inline void bclr(const void* addr, const u8 mask) {
+ /* same issue as above */
+ //*(u8*)addr &= ~mask;
asm volatile (
"ldx %0\n"
- "bclr 00,x,%1"
- : /* outputs */
- : "p" (addr), "g" (mask) /* inputs */
+ "bclr 00,x,%1\n"
+ : "=m" (addr) /* outputs */
+ : "g" (mask) /* inputs */
: "x" /* altered registers */
- );
+ );
+}
+
+extern inline void lock() {
+ asm volatile ("sei");
+}
+
+extern inline void unlock() {
+ asm volatile ("cli");
}
#endif /* _ASM_H_ */