; Exam2019H31春P3 対象ビット列を全部0にする。
;あるいは対象ビット列を全部１にする。
MAIN START
	LAD GR7,      BITAREA1
	ST GR7,ADRBAREA
   		 LAD   GR1  ,  ADRBAREA
	CALL BITSON
	;----------------
	LAD     GR7,  	BITAREA2
	ST GR7,ADRBAREA
	LAD GR1,ADRBAREA
	CALL BITSOFF
	;------------------
	LAD GR7,BITAREA3
	ST GR7,ADRBAREA
	LAD GR1,ADRBAREA
	CALL BITSON
	RET
ADRBAREA DS 1
BITPOS 	DC 18
LEN 	DC 32
BITAREA1 DC 0, 0, 0, 0
BITAREA2 DC #FFFF,#FFFF,#FFFF,#FFFF
BITAREA3 DC #A84D,#94CF,#72B5,#3E61 
	END
;--------------------
; 対象ビット列の全ビットを１にする処理のためのプログラム
BITSON 	START
	RPUSH
	LAD GR7,SETOP
	CALL BITSOP
	RPOP
	RET
	END
;-------------------------------
;対象ビット列の全ビットをゼロにする処理のためのプログラム
BITSOFF 	START
	RPUSH
	LAD GR7,RESETOP
	CALL BITSOP
	RPOP
	RET
	END
;---------------
BITSOP START
	RPUSH
	LD GR3,1,GR1 ; GR3 ビット位置(BITPOS)
;ビット位置を、相対アドレス（ＧＲ２）と
;ビットインデックス（ＧＲ３）に変換する。
	LD   GR2,GR3
	SRL GR2,4 ; a オ
	; ビット位置割る１６の商が相対アドレス GR2
 	AND GR3,=#000F
	; ビット位置を１６で割った余りがビットインデックと同じである。
	LD GR4,2,GR1 ; GR4: ビット長（初期値）
;（ビットインデックス＋ビット長)＞＝１６の間、ビット操作を行う
LOOP	LD GR0,GR4
	ADDL GR0,GR3
	CPL GR0,BITSPW
	JMI BREAK
	LD GR5,BITSPW ; GR5: 語内で対象となるビット数
	LD 		GR3,GR3
	JZE FULL
	;ビットインデックスがゼロならば、
	;一語１６ビット全部(FULL)にビット操作を行う。
	SUBL GR5,GR3 ; b オ ビットインデックス分だけ減らす。
	SUBL GR3,GR3 ; GR3 <-- 0
FULL 	SUBL GR4,GR5 ; 操作するビット数だけビット長を減らす。
	;---------------------
	LD GR0, = 1 ; ビットマスク作成開始
	SLL GR0,0,GR5
	SUBL GR0,   =1 ; GR0: ビットマスク作成完了
	;-----------------------
	CALL 0,GR7
	ADDL GR2, =1 ; GR2: 次の語の相対アドレス
	JUMP LOOP
BREAK	LD GR4,GR4 ;操作の対象となる未処理のビットあり？
	JZE FIN; c オ
;未操作のビット数分の右詰めのビットマスクを生成し、
;必要なビット数だけ左へシフト
	;-----------------------
	LD GR0,=1 ; ビットマスク作成開始
	SLL GR0,  0,   GR4
	SUBL GR0,=1 ; ビットマスク GR0　
	; ビットマスクの必要な数のビット列は作成できたが、
	; 適切な位置つまり左詰めに移動させる必要がある。
	;----------------------
	LD GR5,BITSPW
	SUBL GR5,GR3
	 SUBL GR5,GR4 ; d カ
	SLL GR0,0,GR5 ; GR0:　ビットマスク
	; 左詰めに移動させたのでビットマスク作成完了
	;----------------------------
	CALL 0,GR7
FIN	RPOP
	RET
BITSPW DC 16 ;一語のビット数
	END
;---------------------
; ビットマスクを使い対象ビット列を全部１にする
SETOP 	START
	RPUSH
	LD GR3,0,GR1
	; BITAREA のアドレス取得
	ADDL GR3,GR2
	; 相対アドレス GR2を加算して
	; 操作対象アドレス GR3を確定する。
	OR    GR0   ,0  ,    GR3 ;
	; 操作対象アドレス GR3の内容に対して
	; ビットマスク GR0 を当てる。
	ST GR0,0,GR3
	; 操作終了したので、結果を
	; 操作対象アドレスに戻す。
	RPOP
	RET
	END
;------------------------------
; 題意により作成したプログラム
; SETOPと同種だが反対にビットマスクを使い対象ビット列を全部0にする
RESETOP START
	RPUSH
	LD GR3,0,GR1
	; BITAREA のアドレス取得
	ADDL GR3,GR2
	; 相対アドレス GR2を加算して
	; 操作対象アドレス GR3を確定する。
	;------------------------
	XOR GR0,=#FFFF
	; ビットマスクGR0の１と０を反転させる。
	AND GR0,0,GR3 ;
	; 操作対象アドレス GR3の内容に対して
	; ビットマスク GR0 を当てる。
	ST GR0,0,GR3
	; 操作終了したので、結果を
	; 操作対象アドレスに戻す。
	RPOP
	RET
	END
;-----------------------------
