X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=ROM2%2Fasm.h;h=0dac1b0b15b070dc10b7ab32a2fe393c9e105b24;hb=77f2f2b514bc8b3a5e4c23ab02afc16bdcedb3c6;hp=14e01eda610d9b9795f88ab29dc7f7e330af2403;hpb=7154b91d747c839ace03f0d4198fed36bf5a167b;p=uccvend-snackrom.git diff --git a/ROM2/asm.h b/ROM2/asm.h index 14e01ed..0dac1b0 100644 --- a/ROM2/asm.h +++ b/ROM2/asm.h @@ -7,24 +7,39 @@ * always be an immediate value. Using "g" makes the compiler be quiet, but * 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_ */