-;GR1の値とGR2の値の積をGR0に格納
+;;; -32767〜32767の範囲にある正数のかけ算(筆算方式)を行う
+;;; 入力 GR1:被乗数 GR2:乗数
+;;; 出力 GR0:積
+;;; 被乗数または乗数が-32768の場合は、オーバーフロー
+;;; 積が-32767未満または32767より大きい場合は、GR0は積の下位16ビットになり、オーバーフロー
MULA START
RPUSH
XOR GR0,GR0 ; 積
+ AND GR1,GR1 ; (GR1 = 0)の場合、終了
+ JZE FIN ; ↓
+ AND GR2,GR2 ; (GR2 = 0)の場合、終了
+ JZE FIN ; ↓
LAD GR3,1 ; 対象ビット
XOR GR4,GR4 ; マイナスフラグ
-CHK1 CALL CHKVAL ; (GR1 < 0)の場合は正負を反転させ、GR0 <- 1
- JOV MFIN
- LD GR4,GR0 ; マイナスフラグをオン
-CHK2 PUSH 0,GR1 ; GR1を退避
- LD GR1,GR2 ; GR2をGR1へロード
- CALL CHKVAL ; (GR1 < 0)の場合は正負を反転させ、GR0 <- 1
- JOV C2OV
- LD GR2,GR1 ; GR1をGR2へロード
- XOR GR4,GR0 ; マイナスフラグを反転
-C2FIN POP GR1 ; GR1を復元
- XOR GR0,GR0 ; GR0を初期化
- JUMP MLOOP ; MLOOPへジャンプ
-C2OV POP GR1 ; GR1を復元
- JUMP MFIN ; MFINへジャンプ
-MLOOP PUSH 0,GR3 ; ループ先頭。GR2の、GR3が示したビットが0の場合、MNEXTへジャンプ
+CHK1 AND GR1,GR1 ; (GR1 > 0)の場合は、CHK2へジャンプ
+ JPL CHK2 ; ↓
+ XOR GR1,ALLON ; GR1の正負を反転
+ ADDA GR1,ONE ; ↓
+ JOV FIN ; (GR1 = -32768)の場合は終了
+ XOR GR4,ONE ; GR4 <- 1
+CHK2 AND GR2,GR2 ; (GR1 > 0)の場合は、LOOPへジャンプ
+ JPL LOOP ; ↓
+ XOR GR2,ALLON ; GR2の正負を反転
+ ADDA GR2,ONE ; ↓
+ JOV FIN ; (GR2 = -32768)の場合は終了
+ XOR GR4,ONE ; マイナスフラグを反転
+LOOP PUSH 0,GR3 ; ループ先頭。GR2のビット中でGR3の示したものが0の場合、NEXTへジャンプ
AND GR3,GR2 ; ↓
POP GR3 ; ↓
- JZE MNEXT ; ↓
+ JZE NEXT ; ↓
ADDA GR0,GR1 ; GR0 <- GR0 + GR1
- JOV MFIN ; オーバーフローした場合、ループ脱出
-MNEXT SLA GR3,1 ; GR3を1回左シフト
+ JOV FIN ; オーバーフローした場合、終了
+NEXT SLA GR3,1 ; GR3を1回左シフト
AND GR3,GR3 ; (GR3 = 0)の場合、ループ脱出
- JZE MMIN ; ↓
+ JZE MIN ; ↓
CPL GR3,GR2 ; (GR3 > GR2)の場合、ループ脱出
- JPL MMIN ; ↓
+ JPL MIN ; ↓
SLA GR1,1 ; GR1を1回左シフト
- JOV MFIN ; オーバーフローした場合、ループ脱出
- JUMP MLOOP ; ループ終端
-MMIN AND GR4,GR4 ; マイナスフラグがオフの場合、MFINへジャンプ
- JZE MFIN ; ↓
- LD GR1,GR0 ; GR1にGR0をロード
- CALL MABS ; GR1の正負を反転
- JOV MFIN ; オーバーフロー(GR1 = -32768)の場合、MFINへジャンプ
- LD GR0,GR1 ; GR0にGR1をロード
-MFIN RPOP
- RET
- END
-;;; GR1が0未満の場合は、絶対値に変換し、GR0に1を設定
-CHKVAL START
- LAD GR0,0
- AND GR1,GR1 ; (GR1 >= 0)の場合は、CFINへジャンプ
- JPL CFIN ; ↓
- JZE CFIN ; ↓
- LAD GR0,1 ; GR0に1をロード
- CALL MABS ; GR1を絶対値に変換
-CFIN RET
- END
-;;; GR1の値の正負を反転させる。
-;;; 例: -10 -> 10、10 -> -10
-MABS START
- XOR GR1,=#FFFF ; GR1のビット値を反転
- ADDA GR1,=1 ; GR1 <- GR1 + 1
+ JOV FIN ; オーバーフローした場合、終了
+ JUMP LOOP ; ループ終端
+MIN AND GR4,GR4 ; マイナスフラグがオフの場合、終了
+ JZE FIN ; ↓
+ XOR GR0,ALLON ; GR1の正負を反転
+ ADDA GR0,ONE ; ↓
+FIN RPOP
RET
+ONE DC 1
+ALLON DC #FFFF
END