ビット操作

*val に bitfield があり、指定 bit を toggle し、その結果の bit で表示する文字列を変更するという処理。

void hoge(uint8_t *const val, enum config_bit bit, 
	uint16_t text_offset, const char *const str[])
{
	const uint8_t v = 1 << bit;
	const char *s = str[0];
	*val ^= v;
	if((*val & v) != 0){
		s = str[1];
	}
	string_write(s, text_offset, TEXT_COLOR_YAMADA);
}

m68k-xxx-gcc は bset, bclr, bchg など破壊的 bittest を使うと期待したんだが、ソース通りに eor と and を使っていた。むーん。

	moveq	#1,d1
	move.l	28(sp),d0
	lsl.l	d0,d1 ;v = 1 << bit;
	move.l	(a3),a1 ;*s = str[0]
	move.b	(a2),d0
	eor.b	d1,d0
	move.b	d0,(a2) ;*val ^= v
	and.b	d1,d0
	beq	.L3 ;(*val & v) != 0; 以下略
	move.l	4(a3),a1
.L3:
	pea	17408.w
	move.w	a0,-(sp)
	clr.w	-(sp)
	move.l	a1,-(sp)
	jsr	string_write
	lea	(12,sp),sp

わたしの期待は下記だった。 bchg の z フラグは変更前の値に反映するので注意。bclr は使うかもしれんが、 bchg はコンパイラには実装されづらいわな。

	move.l	(a3),a1 ;*s = str[0]
	move.l	28(sp),d0
	bchg.b	d0,(A2) ;v = 1 << bit; (*val & v) != 0; *val ^= v;
	beq	.L3
	moveq	#1,d1
	move.l	28(sp),d0
	move.l	4(a3),a1