Setting and clearing bits in a byte
Most console structs keep their booleans packed into a byte of flags, and the code that touches them is a load, one bitwise instruction, and a store back. The whole idiom fits in four instructions and you will read it constantly.
Setting a bit is orr. The constant goes into a register first, because Thumb's orr is register-to-register only:
0 ldrb r2, [r0, #2]
2 mov r1, #32
4 orr r1, r2
6 strb r1, [r0, #2]
8 bx lr
Clearing one is where expectations go wrong. ARM has bic — bit clear, a & ~b in a single instruction — so &= ~mask looks like an obvious use for it. Here is what a constant clear actually compiles to:
0 ldrb r2, [r0, #2]
2 mov r1, #239
4 and r1, r2
6 strb r1, [r0, #2]
8 bx lr
Both of those act on d->bits, a u8 field at offset 2 of a four-byte struct. The second one clears bit 4. Because the field is a byte, the compiler knows the complement only has to be right in eight bits, and ~16 narrowed to a byte is 239 — a plain mov #imm8. Complementing at compile time is free, so and wins and bic never appears. Every constant clear on a byte field looks like this, with the complement of the mask sitting in the mov.
bic does show up, and the condition for it is precise: the mask has to be something the compiler cannot fold, so the complement has to happen at runtime. That is what the target below does. The two instructions in front of its load tell you how wide that mask was.
Your task
Write func_0827241c to reproduce the target assembly.