casl2libフォルダを整理
authorj8takagi <j8takagi@nifty.com>
Sat, 2 Jun 2018 07:42:30 +0000 (16:42 +0900)
committerj8takagi <j8takagi@nifty.com>
Sat, 2 Jun 2018 07:42:30 +0000 (16:42 +0900)
17 files changed:
as/casl2lib/.gitignore [new file with mode: 0644]
as/casl2lib/Makefile
as/casl2lib/casl2lib.dep [new file with mode: 0644]
as/casl2lib/diva.casl
as/casl2lib/doc/call.gv [new file with mode: 0644]
as/casl2lib/inl.casl
as/casl2lib/l2str.casl
as/casl2lib/mula.casl
as/casl2lib/outa.casl
as/casl2lib/outa_q15.casl
as/casl2lib/outb.casl
as/casl2lib/outb_w.casl
as/casl2lib/outl.casl
as/casl2lib/outl_q15.casl
as/casl2lib/outpbm.casl
as/casl2lib/pbm16.casl
as/casl2lib/str2l.casl

diff --git a/as/casl2lib/.gitignore b/as/casl2lib/.gitignore
new file mode 100644 (file)
index 0000000..04dbd3d
--- /dev/null
@@ -0,0 +1,3 @@
+*.casl
+doc/call.svg
+sample/*.pbm
index 880ba6b..1392daa 100644 (file)
@@ -1,13 +1,26 @@
-.PHONY: install-casl2lib uninstall-casl2lib
+.PHONY: all install-casl2lib uninstall-casl2lib
 
-RMF ?= rm -f
-RMDIR ?= rmdir
-ECHO ?= echo
-INSTALL ?= install
+CAT := cat
+RMF := rm -f
+RMDIR := rmdir
+ECHO := echo
+INSTALL := install
 
 prefix ?= ~
 casl2libdir ?= $(prefix)/share/casl2lib
 
+all: stdlib.casl abs.casl addl32.casl diva.casl divl.casl inl.casl l2str.casl max.casl minim.casl mula.casl mull.casl outa.casl outa_q15.casl outb.casl outb_w.casl outl.casl outl_q15.casl outpbm.casl pbm16.casl str2l.casl
+
+%.casl: src/%.casl
+       $(CAT) $^ >$@
+
+include casl2lib.dep
+
+clean:
+
+distclean:
+       $(RM) *.casl
+
 install-casl2lib: *.casl
        $(INSTALL) -d $(casl2libdir)
        $(INSTALL) $^ $(casl2libdir)/
diff --git a/as/casl2lib/casl2lib.dep b/as/casl2lib/casl2lib.dep
new file mode 100644 (file)
index 0000000..9bb2032
--- /dev/null
@@ -0,0 +1,39 @@
+stdlib.casl: src/stdlib.casl src/abs.casl src/addl32.casl src/diva.casl src/divl.casl src/inl.casl src/l2str.casl src/max.casl src/minim.casl src/mula.casl src/mull.casl src/outa.casl src/outa_q15.casl src/outb.casl src/outb_w.casl src/outl.casl src/outl_q15.casl src/outpbm.casl src/pbm16.casl src/rev.casl src/str2l.casl
+
+abs.casl: src/abs.casl
+
+addl32.casl: src/addl32.casl
+
+diva.casl: src/diva.casl divl.casl
+
+divl.casl: src/divl.casl
+
+inl.casl: src/inl.casl str2l.casl
+
+l2str.casl: src/l2str.casl divl.casl rev.casl
+
+max.casl: src/max.casl
+
+minim.casl: src/minim.casl
+
+mula.casl: src/mula.casl mull.casl
+
+mull.casl: src/mull.casl
+
+outa.casl: src/outa.casl abs.casl divl.casl
+
+outa_q15.casl: src/outa_q15.casl abs.casl mull.casl
+
+outb.casl: src/outb.casl divl.casl rev.casl
+
+outb_w.casl: src/outb_w.casl divl.casl rev.casl
+
+outl.casl: src/outl.casl divl.casl rev.casl
+
+outl_q15.casl: src/outl_q15.casl mull.casl
+
+outpbm.casl: src/outpbm.casl l2str.casl
+
+pbm16.casl: src/pbm16.casl outb.casl
+
+str2l.casl: src/str2l.casl mull.casl
index 6796eb9..9b34690 100644 (file)
@@ -39,3 +39,50 @@ FIN     POP  GR4
 ONE     DC      1
 ALLON   DC      #FFFF
         END
+;;; 0〜65535の範囲にある正数の割算(筆算方式)を行う
+;;; 入力 GR1:被除数 GR2:除数
+;;; 出力 GR0:商 GR3:剰余
+;;; (GR2 = 0)の場合、GR0 GR3とも0になり、オーバーフロー
+DIVL    START
+        PUSH    0,GR1
+        PUSH    0,GR2
+        PUSH    0,GR4
+        XOR     GR0,GR0         ; GR0:商 初期化
+        XOR     GR3,GR3         ; GR3:剰余 初期化
+        AND     GR2,GR2         ; (GR2 = 0)の場合、DIVZEROへジャンプ
+        JZE     DIVZERO         ; ↓
+        AND     GR1,GR1         ; (GR1 = 0)の場合、FINへジャンプ
+        JZE     FIN             ; ↓
+        ST      GR2,Y           ; YにGR2の初期値を保存
+        LAD     GR4,1           ; GR4:対象ビットのインデックス 初期化
+SL      CPL     GR2,GR1         ; ループ先頭。(GR2 > GR1)の場合、LOOPへループ脱出
+        JPL     LOOP            ; ↓
+        SLL     GR4,1           ; GR4を1回左シフト
+        ST      GR2,TMP         ; GR2の値をTMPに退避
+        SLL     GR2,1           ; GR2を1回左シフト
+        JOV     YOV             ; オーバーフローの場合は、YOVへジャンプ
+        JUMP    SL              ; ループ終端
+YOV     LD      GR2,TMP         ; GR2の値をTMPから復元
+        SRL     GR4,1           ; GR4を1回右シフト
+        JUMP    LPIN            ; LPINへジャンプ
+LOOP    SRL     GR4,1           ; ループ先頭。GR4を1回右シフト
+        JZE     SETMOD          ; (GR4 = 0)の場合、SETMODへループ脱出
+        SRL     GR2,1           ; GR2を1回右シフト
+        CPL     GR1,Y           ; (GR1 < Y)の場合、SETMODへループ脱出
+        JMI     SETMOD          ; ↓
+        CPL     GR1,GR2         ; (GR1 < GR2)の場合、ループ先頭へジャンプ
+        JMI     LOOP            ; ↓
+LPIN    SUBL    GR1,GR2         ; GR1 <- GR1 - GR2
+        ADDL    GR0,GR4         ; GR0 <- GR0 + GR4
+        JUMP    LOOP            ; ループ終端
+DIVZERO LAD     GR3,#8000       ; 強制的にオーバーフローを発生させ、GR3 <- 0
+        SLL     GR3,1           ; ↓
+        JUMP    FIN             ; FIN へジャンプ
+SETMOD  LD      GR3,GR1         ; GR3 <- GR1。剰余の設定
+FIN     POP     GR4
+        POP     GR2
+        POP     GR1
+        RET
+Y       DS      1
+TMP     DS      1
+        END
diff --git a/as/casl2lib/doc/call.gv b/as/casl2lib/doc/call.gv
new file mode 100644 (file)
index 0000000..2579add
--- /dev/null
@@ -0,0 +1,24 @@
+digraph sample {
+    graph [shape="" style="" color="" fillcolor="" fontname="sans-serif" fontsize="12" width="2"];
+    DIVA -> DIVL;
+    INL -> STR2L;
+    L2STR -> DIVL;
+    L2STR -> REV;
+    MULA -> MULL;
+    OUTA -> ABS;
+    OUTA -> DIVL;
+    OUTA -> REV;
+    OUTA_Q15 -> ABS;
+    OUTA_Q15 -> MULL;
+    OUTB -> DIVL;
+    OUTB -> REV;
+    OUTB_W -> DIVL;
+    OUTB_W -> REV;
+    OUTL -> DIVL;
+    OUTL -> REV;
+    OUTL_Q15 -> MULL;
+    OUTPBM -> L2STR;
+    PBM16 -> OUTB;
+    STR2L -> MULL;
+}
+
index 3587131..ec8bd8b 100644 (file)
@@ -20,3 +20,87 @@ ILEN    DS      1
 LENMAX  DC      5
 IBUF    DS      5
         END
+;;; 0〜65535の範囲にある正数のかけ算(筆算方式)を行う
+;;; 入力 GR1:被乗数 GR2:乗数
+;;; 出力 GR0:積の下位WORD GR3:積の上位WORD
+;;; 積が65535より大きい場合は、オーバーフロー
+MULL    START
+        PUSH    0,GR4
+        PUSH    0,GR5
+        XOR     GR0,GR0         ; 積
+        XOR     GR3,GR3         ; 上位word
+        XOR     GR5,GR5         ; 上位wordの一時値
+        AND     GR1,GR1         ; (GR1 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        AND     GR2,GR2         ; (GR2 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        LAD     GR4,1           ; 対象ビット
+LOOP    PUSH    0,GR4           ; ループ先頭。GR2のビット中でGR4が示すビットが0の場合、NEXTへジャンプ
+        AND     GR4,GR2         ; ↓
+        POP     GR4             ; ↓
+        JZE     NEXT1           ; ↓
+        ADDL    GR3,GR5         ; GR3 <- GR3 + GR5
+        ADDL    GR0,GR1         ; GR0 <- GR0 + GR1
+        JOV     AHB1            ; GR0がオーバーフローした場合、AHB1へジャンプ
+        JUMP    NEXT1           ; ↓
+AHB1    LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+NEXT1   SLL     GR4,1           ; GR4を1回左シフト
+        JOV     CHKOV           ; ↓
+        SLL     GR5,1           ; GR5を1回左シフト
+        CPL     GR4,GR2         ; (GR4 > GR2)の場合、CHKOVへジャンプ
+        JPL     CHKOV           ; ↓
+        SLL     GR1,1           ; GR1を1回左シフト
+        JOV     AHB2            ; GR1がオーバーフローした場合、AHBへジャンプ
+        JUMP    NEXT2           ; ↓
+AHB2    LAD     GR5,1,GR5       ; GR5 <- GR5 + 1
+NEXT2   JUMP    LOOP            ; ループ終端
+CHKOV   AND     GR3,GR3         ; GR3 = 0の場合、終了
+        JZE     FIN             ; ↓
+        LAD     GR4,#FFFF       ; GR3 <> 0の場合、オーバーフロー
+        SLL     GR4,1           ; ↓
+FIN     POP     GR5
+        POP     GR4
+        RET
+        END
+;;; 0〜65535の範囲にある正数のかけ算(筆算方式)を行う
+;;; 入力 GR1:被乗数 GR2:乗数
+;;; 出力 GR0:積の下位WORD GR3:積の上位WORD
+;;; 積が65535より大きい場合は、オーバーフロー
+MULL    START
+        PUSH    0,GR4
+        PUSH    0,GR5
+        XOR     GR0,GR0         ; 積
+        XOR     GR3,GR3         ; 上位word
+        XOR     GR5,GR5         ; 上位wordの一時値
+        AND     GR1,GR1         ; (GR1 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        AND     GR2,GR2         ; (GR2 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        LAD     GR4,1           ; 対象ビット
+LOOP    PUSH    0,GR4           ; ループ先頭。GR2のビット中でGR4が示すビットが0の場合、NEXTへジャンプ
+        AND     GR4,GR2         ; ↓
+        POP     GR4             ; ↓
+        JZE     NEXT1           ; ↓
+        ADDL    GR3,GR5         ; GR3 <- GR3 + GR5
+        ADDL    GR0,GR1         ; GR0 <- GR0 + GR1
+        JOV     AHB1            ; GR0がオーバーフローした場合、AHB1へジャンプ
+        JUMP    NEXT1           ; ↓
+AHB1    LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+NEXT1   SLL     GR4,1           ; GR4を1回左シフト
+        JOV     CHKOV           ; ↓
+        SLL     GR5,1           ; GR5を1回左シフト
+        CPL     GR4,GR2         ; (GR4 > GR2)の場合、CHKOVへジャンプ
+        JPL     CHKOV           ; ↓
+        SLL     GR1,1           ; GR1を1回左シフト
+        JOV     AHB2            ; GR1がオーバーフローした場合、AHBへジャンプ
+        JUMP    NEXT2           ; ↓
+AHB2    LAD     GR5,1,GR5       ; GR5 <- GR5 + 1
+NEXT2   JUMP    LOOP            ; ループ終端
+CHKOV   AND     GR3,GR3         ; GR3 = 0の場合、終了
+        JZE     FIN             ; ↓
+        LAD     GR4,#FFFF       ; GR3 <> 0の場合、オーバーフロー
+        SLL     GR4,1           ; ↓
+FIN     POP     GR5
+        POP     GR4
+        RET
+        END
index a3dba83..736c888 100644 (file)
@@ -39,3 +39,77 @@ PRT     LD      GR1,GR2         ; GR1に文字列のアドレスを格納
 LEN     DS      1
 NCHAR   DC      '0123456789'
         END
+;;; 0〜65535の範囲にある正数の割算(筆算方式)を行う
+;;; 入力 GR1:被除数 GR2:除数
+;;; 出力 GR0:商 GR3:剰余
+;;; (GR2 = 0)の場合、GR0 GR3とも0になり、オーバーフロー
+DIVL    START
+        PUSH    0,GR1
+        PUSH    0,GR2
+        PUSH    0,GR4
+        XOR     GR0,GR0         ; GR0:商 初期化
+        XOR     GR3,GR3         ; GR3:剰余 初期化
+        AND     GR2,GR2         ; (GR2 = 0)の場合、DIVZEROへジャンプ
+        JZE     DIVZERO         ; ↓
+        AND     GR1,GR1         ; (GR1 = 0)の場合、FINへジャンプ
+        JZE     FIN             ; ↓
+        ST      GR2,Y           ; YにGR2の初期値を保存
+        LAD     GR4,1           ; GR4:対象ビットのインデックス 初期化
+SL      CPL     GR2,GR1         ; ループ先頭。(GR2 > GR1)の場合、LOOPへループ脱出
+        JPL     LOOP            ; ↓
+        SLL     GR4,1           ; GR4を1回左シフト
+        ST      GR2,TMP         ; GR2の値をTMPに退避
+        SLL     GR2,1           ; GR2を1回左シフト
+        JOV     YOV             ; オーバーフローの場合は、YOVへジャンプ
+        JUMP    SL              ; ループ終端
+YOV     LD      GR2,TMP         ; GR2の値をTMPから復元
+        SRL     GR4,1           ; GR4を1回右シフト
+        JUMP    LPIN            ; LPINへジャンプ
+LOOP    SRL     GR4,1           ; ループ先頭。GR4を1回右シフト
+        JZE     SETMOD          ; (GR4 = 0)の場合、SETMODへループ脱出
+        SRL     GR2,1           ; GR2を1回右シフト
+        CPL     GR1,Y           ; (GR1 < Y)の場合、SETMODへループ脱出
+        JMI     SETMOD          ; ↓
+        CPL     GR1,GR2         ; (GR1 < GR2)の場合、ループ先頭へジャンプ
+        JMI     LOOP            ; ↓
+LPIN    SUBL    GR1,GR2         ; GR1 <- GR1 - GR2
+        ADDL    GR0,GR4         ; GR0 <- GR0 + GR4
+        JUMP    LOOP            ; ループ終端
+DIVZERO LAD     GR3,#8000       ; 強制的にオーバーフローを発生させ、GR3 <- 0
+        SLL     GR3,1           ; ↓
+        JUMP    FIN             ; FIN へジャンプ
+SETMOD  LD      GR3,GR1         ; GR3 <- GR1。剰余の設定
+FIN     POP     GR4
+        POP     GR2
+        POP     GR1
+        RET
+Y       DS      1
+TMP     DS      1
+        END
+;;; メモリー上にある指定されたアドレス、長さの文字列を逆順に並べ替える
+;;;     例: 12345 -> 54321、54321- -> -12345
+;;; 入力 GR1:文字列のアドレス GR2:文字列の長さ
+;;; 出力 (同上)
+REV     START
+        RPUSH
+        LAD     GR3,0           ; GR3の初期化
+PU      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
+        JZE     NEXT            ; ↓
+        LD      GR4,GR1         ; GR4 <- GR1
+        ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
+        LD      GR5,0,GR4       ; GR5 <- GR4アドレスの値
+        PUSH    0,GR5           ; GR5をプッシュ
+        LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+        JUMP    PU              ; ループ終端
+NEXT    LAD     GR3,0           ; GR3の初期化
+PO      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
+        JZE     FIN             ; ↓
+        POP     GR5             ; GR5にポップ
+        LD      GR4,GR1         ; GR4にGR1の値をコピー
+        ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
+        ST      GR5,0,GR4       ; GR4のアドレス <- GR5の値
+        LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+        JUMP    PO              ; ループ終端
+FIN     RPOP
+        RET
+        END
index 431486a..e997471 100644 (file)
@@ -39,3 +39,45 @@ FIN     RPOP
 ONE     DC      1
 ALLON   DC      #FFFF
         END
+;;; 0〜65535の範囲にある正数のかけ算(筆算方式)を行う
+;;; 入力 GR1:被乗数 GR2:乗数
+;;; 出力 GR0:積の下位WORD GR3:積の上位WORD
+;;; 積が65535より大きい場合は、オーバーフロー
+MULL    START
+        PUSH    0,GR4
+        PUSH    0,GR5
+        XOR     GR0,GR0         ; 積
+        XOR     GR3,GR3         ; 上位word
+        XOR     GR5,GR5         ; 上位wordの一時値
+        AND     GR1,GR1         ; (GR1 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        AND     GR2,GR2         ; (GR2 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        LAD     GR4,1           ; 対象ビット
+LOOP    PUSH    0,GR4           ; ループ先頭。GR2のビット中でGR4が示すビットが0の場合、NEXTへジャンプ
+        AND     GR4,GR2         ; ↓
+        POP     GR4             ; ↓
+        JZE     NEXT1           ; ↓
+        ADDL    GR3,GR5         ; GR3 <- GR3 + GR5
+        ADDL    GR0,GR1         ; GR0 <- GR0 + GR1
+        JOV     AHB1            ; GR0がオーバーフローした場合、AHB1へジャンプ
+        JUMP    NEXT1           ; ↓
+AHB1    LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+NEXT1   SLL     GR4,1           ; GR4を1回左シフト
+        JOV     CHKOV           ; ↓
+        SLL     GR5,1           ; GR5を1回左シフト
+        CPL     GR4,GR2         ; (GR4 > GR2)の場合、CHKOVへジャンプ
+        JPL     CHKOV           ; ↓
+        SLL     GR1,1           ; GR1を1回左シフト
+        JOV     AHB2            ; GR1がオーバーフローした場合、AHBへジャンプ
+        JUMP    NEXT2           ; ↓
+AHB2    LAD     GR5,1,GR5       ; GR5 <- GR5 + 1
+NEXT2   JUMP    LOOP            ; ループ終端
+CHKOV   AND     GR3,GR3         ; GR3 = 0の場合、終了
+        JZE     FIN             ; ↓
+        LAD     GR4,#FFFF       ; GR3 <> 0の場合、オーバーフロー
+        SLL     GR4,1           ; ↓
+FIN     POP     GR5
+        POP     GR4
+        RET
+        END
index 6f8f84d..baf71c9 100644 (file)
@@ -42,3 +42,67 @@ STR     DS      17
 LEN     DS      1
 NCHAR   DC      '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
         END
+;;; GR1を符号付き整数とみなし、絶対値に変換
+;;; 入力 GR1: -32768から32767の整数
+;;; 出力 GR1: 入力された整数の絶対値
+;;;       OF: 入力されたGR1が-32768の場合、1
+;;;       SF: 入力されたGR1が負数(-32767〜-1)の場合、1
+ABS     START
+        AND     GR1,GR1         ; GR1が0以上の場合は、FINへジャンプ
+        JPL     FIN             ; ↓
+        JZE     FIN             ; ↓
+        XOR     GR1,ALLON       ; GR1のビットを反転
+        ADDA    GR1,ONE         ; GR1に1を追加
+        JOV     FIN             ; 足し算でオーバーフローの場合は、OF:1を保持してFINへジャンプ
+        CPL     GR1,ALLON       ; SF:1を設定
+FIN     RET
+ONE     DC      1
+ALLON   DC      #FFFF
+        END
+;;; 0〜65535の範囲にある正数の割算(筆算方式)を行う
+;;; 入力 GR1:被除数 GR2:除数
+;;; 出力 GR0:商 GR3:剰余
+;;; (GR2 = 0)の場合、GR0 GR3とも0になり、オーバーフロー
+DIVL    START
+        PUSH    0,GR1
+        PUSH    0,GR2
+        PUSH    0,GR4
+        XOR     GR0,GR0         ; GR0:商 初期化
+        XOR     GR3,GR3         ; GR3:剰余 初期化
+        AND     GR2,GR2         ; (GR2 = 0)の場合、DIVZEROへジャンプ
+        JZE     DIVZERO         ; ↓
+        AND     GR1,GR1         ; (GR1 = 0)の場合、FINへジャンプ
+        JZE     FIN             ; ↓
+        ST      GR2,Y           ; YにGR2の初期値を保存
+        LAD     GR4,1           ; GR4:対象ビットのインデックス 初期化
+SL      CPL     GR2,GR1         ; ループ先頭。(GR2 > GR1)の場合、LOOPへループ脱出
+        JPL     LOOP            ; ↓
+        SLL     GR4,1           ; GR4を1回左シフト
+        ST      GR2,TMP         ; GR2の値をTMPに退避
+        SLL     GR2,1           ; GR2を1回左シフト
+        JOV     YOV             ; オーバーフローの場合は、YOVへジャンプ
+        JUMP    SL              ; ループ終端
+YOV     LD      GR2,TMP         ; GR2の値をTMPから復元
+        SRL     GR4,1           ; GR4を1回右シフト
+        JUMP    LPIN            ; LPINへジャンプ
+LOOP    SRL     GR4,1           ; ループ先頭。GR4を1回右シフト
+        JZE     SETMOD          ; (GR4 = 0)の場合、SETMODへループ脱出
+        SRL     GR2,1           ; GR2を1回右シフト
+        CPL     GR1,Y           ; (GR1 < Y)の場合、SETMODへループ脱出
+        JMI     SETMOD          ; ↓
+        CPL     GR1,GR2         ; (GR1 < GR2)の場合、ループ先頭へジャンプ
+        JMI     LOOP            ; ↓
+LPIN    SUBL    GR1,GR2         ; GR1 <- GR1 - GR2
+        ADDL    GR0,GR4         ; GR0 <- GR0 + GR4
+        JUMP    LOOP            ; ループ終端
+DIVZERO LAD     GR3,#8000       ; 強制的にオーバーフローを発生させ、GR3 <- 0
+        SLL     GR3,1           ; ↓
+        JUMP    FIN             ; FIN へジャンプ
+SETMOD  LD      GR3,GR1         ; GR3 <- GR1。剰余の設定
+FIN     POP     GR4
+        POP     GR2
+        POP     GR1
+        RET
+Y       DS      1
+TMP     DS      1
+        END
index 7c0e01c..74b1e2d 100644 (file)
@@ -44,3 +44,62 @@ STR     DS      20
 LEN     DS      1
         END
 
+;;; GR1を符号付き整数とみなし、絶対値に変換
+;;; 入力 GR1: -32768から32767の整数
+;;; 出力 GR1: 入力された整数の絶対値
+;;;       OF: 入力されたGR1が-32768の場合、1
+;;;       SF: 入力されたGR1が負数(-32767〜-1)の場合、1
+ABS     START
+        AND     GR1,GR1         ; GR1が0以上の場合は、FINへジャンプ
+        JPL     FIN             ; ↓
+        JZE     FIN             ; ↓
+        XOR     GR1,ALLON       ; GR1のビットを反転
+        ADDA    GR1,ONE         ; GR1に1を追加
+        JOV     FIN             ; 足し算でオーバーフローの場合は、OF:1を保持してFINへジャンプ
+        CPL     GR1,ALLON       ; SF:1を設定
+FIN     RET
+ONE     DC      1
+ALLON   DC      #FFFF
+        END
+;;; 0〜65535の範囲にある正数のかけ算(筆算方式)を行う
+;;; 入力 GR1:被乗数 GR2:乗数
+;;; 出力 GR0:積の下位WORD GR3:積の上位WORD
+;;; 積が65535より大きい場合は、オーバーフロー
+MULL    START
+        PUSH    0,GR4
+        PUSH    0,GR5
+        XOR     GR0,GR0         ; 積
+        XOR     GR3,GR3         ; 上位word
+        XOR     GR5,GR5         ; 上位wordの一時値
+        AND     GR1,GR1         ; (GR1 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        AND     GR2,GR2         ; (GR2 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        LAD     GR4,1           ; 対象ビット
+LOOP    PUSH    0,GR4           ; ループ先頭。GR2のビット中でGR4が示すビットが0の場合、NEXTへジャンプ
+        AND     GR4,GR2         ; ↓
+        POP     GR4             ; ↓
+        JZE     NEXT1           ; ↓
+        ADDL    GR3,GR5         ; GR3 <- GR3 + GR5
+        ADDL    GR0,GR1         ; GR0 <- GR0 + GR1
+        JOV     AHB1            ; GR0がオーバーフローした場合、AHB1へジャンプ
+        JUMP    NEXT1           ; ↓
+AHB1    LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+NEXT1   SLL     GR4,1           ; GR4を1回左シフト
+        JOV     CHKOV           ; ↓
+        SLL     GR5,1           ; GR5を1回左シフト
+        CPL     GR4,GR2         ; (GR4 > GR2)の場合、CHKOVへジャンプ
+        JPL     CHKOV           ; ↓
+        SLL     GR1,1           ; GR1を1回左シフト
+        JOV     AHB2            ; GR1がオーバーフローした場合、AHBへジャンプ
+        JUMP    NEXT2           ; ↓
+AHB2    LAD     GR5,1,GR5       ; GR5 <- GR5 + 1
+NEXT2   JUMP    LOOP            ; ループ終端
+CHKOV   AND     GR3,GR3         ; GR3 = 0の場合、終了
+        JZE     FIN             ; ↓
+        LAD     GR4,#FFFF       ; GR3 <> 0の場合、オーバーフロー
+        SLL     GR4,1           ; ↓
+FIN     POP     GR5
+        POP     GR4
+        RET
+        END
index 7ecb73e..dd1ebaa 100644 (file)
@@ -35,3 +35,77 @@ NCHAR   DC      '01'
 SPC     DC      ' '
 DIG     DC      16
         END
+;;; 0〜65535の範囲にある正数の割算(筆算方式)を行う
+;;; 入力 GR1:被除数 GR2:除数
+;;; 出力 GR0:商 GR3:剰余
+;;; (GR2 = 0)の場合、GR0 GR3とも0になり、オーバーフロー
+DIVL    START
+        PUSH    0,GR1
+        PUSH    0,GR2
+        PUSH    0,GR4
+        XOR     GR0,GR0         ; GR0:商 初期化
+        XOR     GR3,GR3         ; GR3:剰余 初期化
+        AND     GR2,GR2         ; (GR2 = 0)の場合、DIVZEROへジャンプ
+        JZE     DIVZERO         ; ↓
+        AND     GR1,GR1         ; (GR1 = 0)の場合、FINへジャンプ
+        JZE     FIN             ; ↓
+        ST      GR2,Y           ; YにGR2の初期値を保存
+        LAD     GR4,1           ; GR4:対象ビットのインデックス 初期化
+SL      CPL     GR2,GR1         ; ループ先頭。(GR2 > GR1)の場合、LOOPへループ脱出
+        JPL     LOOP            ; ↓
+        SLL     GR4,1           ; GR4を1回左シフト
+        ST      GR2,TMP         ; GR2の値をTMPに退避
+        SLL     GR2,1           ; GR2を1回左シフト
+        JOV     YOV             ; オーバーフローの場合は、YOVへジャンプ
+        JUMP    SL              ; ループ終端
+YOV     LD      GR2,TMP         ; GR2の値をTMPから復元
+        SRL     GR4,1           ; GR4を1回右シフト
+        JUMP    LPIN            ; LPINへジャンプ
+LOOP    SRL     GR4,1           ; ループ先頭。GR4を1回右シフト
+        JZE     SETMOD          ; (GR4 = 0)の場合、SETMODへループ脱出
+        SRL     GR2,1           ; GR2を1回右シフト
+        CPL     GR1,Y           ; (GR1 < Y)の場合、SETMODへループ脱出
+        JMI     SETMOD          ; ↓
+        CPL     GR1,GR2         ; (GR1 < GR2)の場合、ループ先頭へジャンプ
+        JMI     LOOP            ; ↓
+LPIN    SUBL    GR1,GR2         ; GR1 <- GR1 - GR2
+        ADDL    GR0,GR4         ; GR0 <- GR0 + GR4
+        JUMP    LOOP            ; ループ終端
+DIVZERO LAD     GR3,#8000       ; 強制的にオーバーフローを発生させ、GR3 <- 0
+        SLL     GR3,1           ; ↓
+        JUMP    FIN             ; FIN へジャンプ
+SETMOD  LD      GR3,GR1         ; GR3 <- GR1。剰余の設定
+FIN     POP     GR4
+        POP     GR2
+        POP     GR1
+        RET
+Y       DS      1
+TMP     DS      1
+        END
+;;; メモリー上にある指定されたアドレス、長さの文字列を逆順に並べ替える
+;;;     例: 12345 -> 54321、54321- -> -12345
+;;; 入力 GR1:文字列のアドレス GR2:文字列の長さ
+;;; 出力 (同上)
+REV     START
+        RPUSH
+        LAD     GR3,0           ; GR3の初期化
+PU      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
+        JZE     NEXT            ; ↓
+        LD      GR4,GR1         ; GR4 <- GR1
+        ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
+        LD      GR5,0,GR4       ; GR5 <- GR4アドレスの値
+        PUSH    0,GR5           ; GR5をプッシュ
+        LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+        JUMP    PU              ; ループ終端
+NEXT    LAD     GR3,0           ; GR3の初期化
+PO      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
+        JZE     FIN             ; ↓
+        POP     GR5             ; GR5にポップ
+        LD      GR4,GR1         ; GR4にGR1の値をコピー
+        ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
+        ST      GR5,0,GR4       ; GR4のアドレス <- GR5の値
+        LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+        JUMP    PO              ; ループ終端
+FIN     RPOP
+        RET
+        END
index d64bff6..cf709d6 100644 (file)
@@ -41,3 +41,77 @@ NCHAR   DC      '01'
 SPC     DC      ' '
 DIG     DC      31
         END
+;;; 0〜65535の範囲にある正数の割算(筆算方式)を行う
+;;; 入力 GR1:被除数 GR2:除数
+;;; 出力 GR0:商 GR3:剰余
+;;; (GR2 = 0)の場合、GR0 GR3とも0になり、オーバーフロー
+DIVL    START
+        PUSH    0,GR1
+        PUSH    0,GR2
+        PUSH    0,GR4
+        XOR     GR0,GR0         ; GR0:商 初期化
+        XOR     GR3,GR3         ; GR3:剰余 初期化
+        AND     GR2,GR2         ; (GR2 = 0)の場合、DIVZEROへジャンプ
+        JZE     DIVZERO         ; ↓
+        AND     GR1,GR1         ; (GR1 = 0)の場合、FINへジャンプ
+        JZE     FIN             ; ↓
+        ST      GR2,Y           ; YにGR2の初期値を保存
+        LAD     GR4,1           ; GR4:対象ビットのインデックス 初期化
+SL      CPL     GR2,GR1         ; ループ先頭。(GR2 > GR1)の場合、LOOPへループ脱出
+        JPL     LOOP            ; ↓
+        SLL     GR4,1           ; GR4を1回左シフト
+        ST      GR2,TMP         ; GR2の値をTMPに退避
+        SLL     GR2,1           ; GR2を1回左シフト
+        JOV     YOV             ; オーバーフローの場合は、YOVへジャンプ
+        JUMP    SL              ; ループ終端
+YOV     LD      GR2,TMP         ; GR2の値をTMPから復元
+        SRL     GR4,1           ; GR4を1回右シフト
+        JUMP    LPIN            ; LPINへジャンプ
+LOOP    SRL     GR4,1           ; ループ先頭。GR4を1回右シフト
+        JZE     SETMOD          ; (GR4 = 0)の場合、SETMODへループ脱出
+        SRL     GR2,1           ; GR2を1回右シフト
+        CPL     GR1,Y           ; (GR1 < Y)の場合、SETMODへループ脱出
+        JMI     SETMOD          ; ↓
+        CPL     GR1,GR2         ; (GR1 < GR2)の場合、ループ先頭へジャンプ
+        JMI     LOOP            ; ↓
+LPIN    SUBL    GR1,GR2         ; GR1 <- GR1 - GR2
+        ADDL    GR0,GR4         ; GR0 <- GR0 + GR4
+        JUMP    LOOP            ; ループ終端
+DIVZERO LAD     GR3,#8000       ; 強制的にオーバーフローを発生させ、GR3 <- 0
+        SLL     GR3,1           ; ↓
+        JUMP    FIN             ; FIN へジャンプ
+SETMOD  LD      GR3,GR1         ; GR3 <- GR1。剰余の設定
+FIN     POP     GR4
+        POP     GR2
+        POP     GR1
+        RET
+Y       DS      1
+TMP     DS      1
+        END
+;;; メモリー上にある指定されたアドレス、長さの文字列を逆順に並べ替える
+;;;     例: 12345 -> 54321、54321- -> -12345
+;;; 入力 GR1:文字列のアドレス GR2:文字列の長さ
+;;; 出力 (同上)
+REV     START
+        RPUSH
+        LAD     GR3,0           ; GR3の初期化
+PU      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
+        JZE     NEXT            ; ↓
+        LD      GR4,GR1         ; GR4 <- GR1
+        ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
+        LD      GR5,0,GR4       ; GR5 <- GR4アドレスの値
+        PUSH    0,GR5           ; GR5をプッシュ
+        LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+        JUMP    PU              ; ループ終端
+NEXT    LAD     GR3,0           ; GR3の初期化
+PO      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
+        JZE     FIN             ; ↓
+        POP     GR5             ; GR5にポップ
+        LD      GR4,GR1         ; GR4にGR1の値をコピー
+        ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
+        ST      GR5,0,GR4       ; GR4のアドレス <- GR5の値
+        LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+        JUMP    PO              ; ループ終端
+FIN     RPOP
+        RET
+        END
index a2967d8..bf16e79 100644 (file)
@@ -34,3 +34,77 @@ STR     DS      17              ; 符号付き2進数で表記した場合を想
 LEN     DS      1
 NCHAR   DC      '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
         END
+;;; 0〜65535の範囲にある正数の割算(筆算方式)を行う
+;;; 入力 GR1:被除数 GR2:除数
+;;; 出力 GR0:商 GR3:剰余
+;;; (GR2 = 0)の場合、GR0 GR3とも0になり、オーバーフロー
+DIVL    START
+        PUSH    0,GR1
+        PUSH    0,GR2
+        PUSH    0,GR4
+        XOR     GR0,GR0         ; GR0:商 初期化
+        XOR     GR3,GR3         ; GR3:剰余 初期化
+        AND     GR2,GR2         ; (GR2 = 0)の場合、DIVZEROへジャンプ
+        JZE     DIVZERO         ; ↓
+        AND     GR1,GR1         ; (GR1 = 0)の場合、FINへジャンプ
+        JZE     FIN             ; ↓
+        ST      GR2,Y           ; YにGR2の初期値を保存
+        LAD     GR4,1           ; GR4:対象ビットのインデックス 初期化
+SL      CPL     GR2,GR1         ; ループ先頭。(GR2 > GR1)の場合、LOOPへループ脱出
+        JPL     LOOP            ; ↓
+        SLL     GR4,1           ; GR4を1回左シフト
+        ST      GR2,TMP         ; GR2の値をTMPに退避
+        SLL     GR2,1           ; GR2を1回左シフト
+        JOV     YOV             ; オーバーフローの場合は、YOVへジャンプ
+        JUMP    SL              ; ループ終端
+YOV     LD      GR2,TMP         ; GR2の値をTMPから復元
+        SRL     GR4,1           ; GR4を1回右シフト
+        JUMP    LPIN            ; LPINへジャンプ
+LOOP    SRL     GR4,1           ; ループ先頭。GR4を1回右シフト
+        JZE     SETMOD          ; (GR4 = 0)の場合、SETMODへループ脱出
+        SRL     GR2,1           ; GR2を1回右シフト
+        CPL     GR1,Y           ; (GR1 < Y)の場合、SETMODへループ脱出
+        JMI     SETMOD          ; ↓
+        CPL     GR1,GR2         ; (GR1 < GR2)の場合、ループ先頭へジャンプ
+        JMI     LOOP            ; ↓
+LPIN    SUBL    GR1,GR2         ; GR1 <- GR1 - GR2
+        ADDL    GR0,GR4         ; GR0 <- GR0 + GR4
+        JUMP    LOOP            ; ループ終端
+DIVZERO LAD     GR3,#8000       ; 強制的にオーバーフローを発生させ、GR3 <- 0
+        SLL     GR3,1           ; ↓
+        JUMP    FIN             ; FIN へジャンプ
+SETMOD  LD      GR3,GR1         ; GR3 <- GR1。剰余の設定
+FIN     POP     GR4
+        POP     GR2
+        POP     GR1
+        RET
+Y       DS      1
+TMP     DS      1
+        END
+;;; メモリー上にある指定されたアドレス、長さの文字列を逆順に並べ替える
+;;;     例: 12345 -> 54321、54321- -> -12345
+;;; 入力 GR1:文字列のアドレス GR2:文字列の長さ
+;;; 出力 (同上)
+REV     START
+        RPUSH
+        LAD     GR3,0           ; GR3の初期化
+PU      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
+        JZE     NEXT            ; ↓
+        LD      GR4,GR1         ; GR4 <- GR1
+        ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
+        LD      GR5,0,GR4       ; GR5 <- GR4アドレスの値
+        PUSH    0,GR5           ; GR5をプッシュ
+        LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+        JUMP    PU              ; ループ終端
+NEXT    LAD     GR3,0           ; GR3の初期化
+PO      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
+        JZE     FIN             ; ↓
+        POP     GR5             ; GR5にポップ
+        LD      GR4,GR1         ; GR4にGR1の値をコピー
+        ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
+        ST      GR5,0,GR4       ; GR4のアドレス <- GR5の値
+        LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+        JUMP    PO              ; ループ終端
+FIN     RPOP
+        RET
+        END
index 2ae4b25..0355a6f 100644 (file)
@@ -27,3 +27,45 @@ PRT     ST      GR4,LEN         ; LEN <- GR4
 STR     DS      20
 LEN     DS      1
         END
+;;; 0〜65535の範囲にある正数のかけ算(筆算方式)を行う
+;;; 入力 GR1:被乗数 GR2:乗数
+;;; 出力 GR0:積の下位WORD GR3:積の上位WORD
+;;; 積が65535より大きい場合は、オーバーフロー
+MULL    START
+        PUSH    0,GR4
+        PUSH    0,GR5
+        XOR     GR0,GR0         ; 積
+        XOR     GR3,GR3         ; 上位word
+        XOR     GR5,GR5         ; 上位wordの一時値
+        AND     GR1,GR1         ; (GR1 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        AND     GR2,GR2         ; (GR2 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        LAD     GR4,1           ; 対象ビット
+LOOP    PUSH    0,GR4           ; ループ先頭。GR2のビット中でGR4が示すビットが0の場合、NEXTへジャンプ
+        AND     GR4,GR2         ; ↓
+        POP     GR4             ; ↓
+        JZE     NEXT1           ; ↓
+        ADDL    GR3,GR5         ; GR3 <- GR3 + GR5
+        ADDL    GR0,GR1         ; GR0 <- GR0 + GR1
+        JOV     AHB1            ; GR0がオーバーフローした場合、AHB1へジャンプ
+        JUMP    NEXT1           ; ↓
+AHB1    LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+NEXT1   SLL     GR4,1           ; GR4を1回左シフト
+        JOV     CHKOV           ; ↓
+        SLL     GR5,1           ; GR5を1回左シフト
+        CPL     GR4,GR2         ; (GR4 > GR2)の場合、CHKOVへジャンプ
+        JPL     CHKOV           ; ↓
+        SLL     GR1,1           ; GR1を1回左シフト
+        JOV     AHB2            ; GR1がオーバーフローした場合、AHBへジャンプ
+        JUMP    NEXT2           ; ↓
+AHB2    LAD     GR5,1,GR5       ; GR5 <- GR5 + 1
+NEXT2   JUMP    LOOP            ; ループ終端
+CHKOV   AND     GR3,GR3         ; GR3 = 0の場合、終了
+        JZE     FIN             ; ↓
+        LAD     GR4,#FFFF       ; GR3 <> 0の場合、オーバーフロー
+        SLL     GR4,1           ; ↓
+FIN     POP     GR5
+        POP     GR4
+        RET
+        END
index 70803c3..146e89a 100644 (file)
@@ -34,3 +34,118 @@ WIDTH   DS      32
 SPC     DC      ' '
 HEIGHT  DS      1
 WHLEN   DS      1
+;;; GR1に格納された符号なし整数を文字列に変換する
+;;; GR2に文字列の先頭アドレス、GR3に文字列の長さを返す
+;;; 依存プログラム: DIVL, REV
+L2STR   START
+        PUSH    0,GR1
+        PUSH    0,GR4
+        XOR     GR0,GR0         ; GR0 <- 0
+        LD      GR4,GR2         ; GR4 <- GR2
+        AND     GR1,GR1         ; GR1をテスト
+        JZE     ZERO            ; GR1が0の場合、ZEROにジャンプ
+        PUSH    0,GR2
+STI     CPL     GR1,GR2         ; ループ先頭。(GR1 < GR2)の場合は、ループ脱出
+        JMI     STLST           ; ↓
+        LAD     GR2,10          ; GR2に10進数の「10」を格納。
+        CALL    DIVL            ; GR1とGR2の、商をGR0、剰余をGR3に格納
+        LD      GR1,GR3         ; GR1にGR3をコピー
+        LD      GR1,NCHAR,GR1   ; GR1を文字に変換
+        ST      GR1,0,GR4       ; (GR4) <- GR1
+        LAD     GR4,1,GR4       ; GR4 <- GR4 + 1
+        LD      GR1,GR0         ; GR0をGR1にコピー
+        JUMP    STI             ; ループ終端
+STLST   POP     GR2
+        LD      GR1,NCHAR,GR1   ; GR1を文字に変換
+        ST      GR1,0,GR4       ; (GR4) <- GR1
+        LAD     GR4,1,GR4       ; GR4 <- GR4 + 1
+        JUMP    PRT             ; PRTにジャンプ
+ZERO    LD      GR1,NCHAR       ; 「0」をSTR領域に格納
+        ST      GR1,0,GR4       ; ↓ (GR4) <- GR1
+        LAD     GR4,1,GR4       ; ↓ GR4 <- GR4 + 1
+PRT     LD      GR1,GR2         ; GR1に文字列のアドレスを格納
+        SUBL    GR4,GR2         ; GR2 <- GR4 - GR2
+        LD      GR2,GR4         ; ↓
+        CALL    REV             ; 文字列を逆順に並べ替え
+        LD      GR3,GR2         ; GR3に文字列の長さを格納
+        LD      GR2,GR4         ; GR2に文字列のアドレスを格納
+        POP     GR4
+        POP     GR1
+        RET
+LEN     DS      1
+NCHAR   DC      '0123456789'
+        END
+;;; 0〜65535の範囲にある正数の割算(筆算方式)を行う
+;;; 入力 GR1:被除数 GR2:除数
+;;; 出力 GR0:商 GR3:剰余
+;;; (GR2 = 0)の場合、GR0 GR3とも0になり、オーバーフロー
+DIVL    START
+        PUSH    0,GR1
+        PUSH    0,GR2
+        PUSH    0,GR4
+        XOR     GR0,GR0         ; GR0:商 初期化
+        XOR     GR3,GR3         ; GR3:剰余 初期化
+        AND     GR2,GR2         ; (GR2 = 0)の場合、DIVZEROへジャンプ
+        JZE     DIVZERO         ; ↓
+        AND     GR1,GR1         ; (GR1 = 0)の場合、FINへジャンプ
+        JZE     FIN             ; ↓
+        ST      GR2,Y           ; YにGR2の初期値を保存
+        LAD     GR4,1           ; GR4:対象ビットのインデックス 初期化
+SL      CPL     GR2,GR1         ; ループ先頭。(GR2 > GR1)の場合、LOOPへループ脱出
+        JPL     LOOP            ; ↓
+        SLL     GR4,1           ; GR4を1回左シフト
+        ST      GR2,TMP         ; GR2の値をTMPに退避
+        SLL     GR2,1           ; GR2を1回左シフト
+        JOV     YOV             ; オーバーフローの場合は、YOVへジャンプ
+        JUMP    SL              ; ループ終端
+YOV     LD      GR2,TMP         ; GR2の値をTMPから復元
+        SRL     GR4,1           ; GR4を1回右シフト
+        JUMP    LPIN            ; LPINへジャンプ
+LOOP    SRL     GR4,1           ; ループ先頭。GR4を1回右シフト
+        JZE     SETMOD          ; (GR4 = 0)の場合、SETMODへループ脱出
+        SRL     GR2,1           ; GR2を1回右シフト
+        CPL     GR1,Y           ; (GR1 < Y)の場合、SETMODへループ脱出
+        JMI     SETMOD          ; ↓
+        CPL     GR1,GR2         ; (GR1 < GR2)の場合、ループ先頭へジャンプ
+        JMI     LOOP            ; ↓
+LPIN    SUBL    GR1,GR2         ; GR1 <- GR1 - GR2
+        ADDL    GR0,GR4         ; GR0 <- GR0 + GR4
+        JUMP    LOOP            ; ループ終端
+DIVZERO LAD     GR3,#8000       ; 強制的にオーバーフローを発生させ、GR3 <- 0
+        SLL     GR3,1           ; ↓
+        JUMP    FIN             ; FIN へジャンプ
+SETMOD  LD      GR3,GR1         ; GR3 <- GR1。剰余の設定
+FIN     POP     GR4
+        POP     GR2
+        POP     GR1
+        RET
+Y       DS      1
+TMP     DS      1
+        END
+;;; メモリー上にある指定されたアドレス、長さの文字列を逆順に並べ替える
+;;;     例: 12345 -> 54321、54321- -> -12345
+;;; 入力 GR1:文字列のアドレス GR2:文字列の長さ
+;;; 出力 (同上)
+REV     START
+        RPUSH
+        LAD     GR3,0           ; GR3の初期化
+PU      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
+        JZE     NEXT            ; ↓
+        LD      GR4,GR1         ; GR4 <- GR1
+        ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
+        LD      GR5,0,GR4       ; GR5 <- GR4アドレスの値
+        PUSH    0,GR5           ; GR5をプッシュ
+        LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+        JUMP    PU              ; ループ終端
+NEXT    LAD     GR3,0           ; GR3の初期化
+PO      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
+        JZE     FIN             ; ↓
+        POP     GR5             ; GR5にポップ
+        LD      GR4,GR1         ; GR4にGR1の値をコピー
+        ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
+        ST      GR5,0,GR4       ; GR4のアドレス <- GR5の値
+        LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+        JUMP    PO              ; ループ終端
+FIN     RPOP
+        RET
+        END
index 39671ca..e615f35 100644 (file)
@@ -29,3 +29,114 @@ L2LEN   DC      5
 HEIGHT  DC      16
 BEG     DS      1
         END
+;;; GR1に格納された値を、2進数値として表示
+OUTB    START
+        RPUSH
+        LD      GR2,BIN         ; GR2に2進数の「2」を格納。
+        XOR     GR4,GR4         ; GR4: 2進数値の長さ
+STI     CPL     GR1,GR2         ; ループ先頭。(GR1 < GR2)の場合は、ループ脱出
+        JMI     STLST           ; ↓
+        CALL    DIVL            ; GR1とGR2の、商をGR0、剰余をGR3に格納
+        LD      GR1,GR3         ; GR1にGR3をコピー
+        LD      GR1,NCHAR,GR1   ; GR1を文字に変換
+        ST      GR1,STR,GR4     ; (STR + GR4) <- GR1
+        LAD     GR4,1,GR4       ; GR4 <- GR4 + 1
+        LD      GR1,GR0         ; GR0をGR1にコピー
+        JUMP    STI             ; ループ終端
+STLST   LD      GR1,NCHAR,GR1   ; GR1を文字に変換
+        ST      GR1,STR,GR4     ; (STR + GR4) <- GR1
+        LAD     GR4,1,GR4       ; GR4 <- GR4 + 1
+EMLOOP  CPL     GR4,DIG         ; ループ先頭。(GR4 = DIG)の場合は、ループ脱出
+        JZE     PRT             ; ↓
+        LD      GR1,NCHAR       ; GR1 <- NCHAR:'0'
+        ST      GR1,STR,GR4     ; (STR + GR4) <- GR1
+        LAD     GR4,1,GR4       ; GR4 <- GR4 + 1
+        JUMP    EMLOOP          ; ループ終端
+PRT     ST      GR4,LEN         ; LEN <- GR4
+        LD      GR2,LEN         ; GR2にLENの値を格納
+        LAD     GR1,STR         ; GR1に文字列のアドレスを格納
+        CALL    REV             ; 文字列を逆順に並べ替え
+        OUT     STR,LEN         ; 文字列を出力
+        RPOP
+        RET
+STR     DS      17
+LEN     DS      1
+BIN     DC      2
+NCHAR   DC      '01'
+SPC     DC      ' '
+DIG     DC      16
+        END
+;;; 0〜65535の範囲にある正数の割算(筆算方式)を行う
+;;; 入力 GR1:被除数 GR2:除数
+;;; 出力 GR0:商 GR3:剰余
+;;; (GR2 = 0)の場合、GR0 GR3とも0になり、オーバーフロー
+DIVL    START
+        PUSH    0,GR1
+        PUSH    0,GR2
+        PUSH    0,GR4
+        XOR     GR0,GR0         ; GR0:商 初期化
+        XOR     GR3,GR3         ; GR3:剰余 初期化
+        AND     GR2,GR2         ; (GR2 = 0)の場合、DIVZEROへジャンプ
+        JZE     DIVZERO         ; ↓
+        AND     GR1,GR1         ; (GR1 = 0)の場合、FINへジャンプ
+        JZE     FIN             ; ↓
+        ST      GR2,Y           ; YにGR2の初期値を保存
+        LAD     GR4,1           ; GR4:対象ビットのインデックス 初期化
+SL      CPL     GR2,GR1         ; ループ先頭。(GR2 > GR1)の場合、LOOPへループ脱出
+        JPL     LOOP            ; ↓
+        SLL     GR4,1           ; GR4を1回左シフト
+        ST      GR2,TMP         ; GR2の値をTMPに退避
+        SLL     GR2,1           ; GR2を1回左シフト
+        JOV     YOV             ; オーバーフローの場合は、YOVへジャンプ
+        JUMP    SL              ; ループ終端
+YOV     LD      GR2,TMP         ; GR2の値をTMPから復元
+        SRL     GR4,1           ; GR4を1回右シフト
+        JUMP    LPIN            ; LPINへジャンプ
+LOOP    SRL     GR4,1           ; ループ先頭。GR4を1回右シフト
+        JZE     SETMOD          ; (GR4 = 0)の場合、SETMODへループ脱出
+        SRL     GR2,1           ; GR2を1回右シフト
+        CPL     GR1,Y           ; (GR1 < Y)の場合、SETMODへループ脱出
+        JMI     SETMOD          ; ↓
+        CPL     GR1,GR2         ; (GR1 < GR2)の場合、ループ先頭へジャンプ
+        JMI     LOOP            ; ↓
+LPIN    SUBL    GR1,GR2         ; GR1 <- GR1 - GR2
+        ADDL    GR0,GR4         ; GR0 <- GR0 + GR4
+        JUMP    LOOP            ; ループ終端
+DIVZERO LAD     GR3,#8000       ; 強制的にオーバーフローを発生させ、GR3 <- 0
+        SLL     GR3,1           ; ↓
+        JUMP    FIN             ; FIN へジャンプ
+SETMOD  LD      GR3,GR1         ; GR3 <- GR1。剰余の設定
+FIN     POP     GR4
+        POP     GR2
+        POP     GR1
+        RET
+Y       DS      1
+TMP     DS      1
+        END
+;;; メモリー上にある指定されたアドレス、長さの文字列を逆順に並べ替える
+;;;     例: 12345 -> 54321、54321- -> -12345
+;;; 入力 GR1:文字列のアドレス GR2:文字列の長さ
+;;; 出力 (同上)
+REV     START
+        RPUSH
+        LAD     GR3,0           ; GR3の初期化
+PU      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
+        JZE     NEXT            ; ↓
+        LD      GR4,GR1         ; GR4 <- GR1
+        ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
+        LD      GR5,0,GR4       ; GR5 <- GR4アドレスの値
+        PUSH    0,GR5           ; GR5をプッシュ
+        LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+        JUMP    PU              ; ループ終端
+NEXT    LAD     GR3,0           ; GR3の初期化
+PO      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
+        JZE     FIN             ; ↓
+        POP     GR5             ; GR5にポップ
+        LD      GR4,GR1         ; GR4にGR1の値をコピー
+        ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
+        ST      GR5,0,GR4       ; GR4のアドレス <- GR5の値
+        LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+        JUMP    PO              ; ループ終端
+FIN     RPOP
+        RET
+        END
index 1394131..591ef66 100644 (file)
@@ -1,63 +1,84 @@
-;;; 10進数の整数を表す文字列を数値に変換
-;;; 数値の範囲は、0から65535
-;;; 入力 GR1: 文字列を格納するアドレス
-;;;      GR2: 文字列の長さ。最大5けた
-;;; 出力 GR0: 数値
-;;;           文字列が最大長より大きい場合や数値以外の場合は、GR0は#FFFF、OFは1
-;;; 依存プログラム: MULL
-STR2L   START
+;;; 0〜65535の範囲にある正数のかけ算(筆算方式)を行う
+;;; 入力 GR1:被乗数 GR2:乗数
+;;; 出力 GR0:積の下位WORD GR3:積の上位WORD
+;;; 積が65535より大きい場合は、オーバーフロー
+MULL    START
         PUSH    0,GR4
         PUSH    0,GR5
-        XOR     GR0,GR0         ; GR0:初期化
-        AND     GR2,GR2         ; (GR2 = 0)の場合、FINへジャンプ
+        XOR     GR0,GR0         ; 積
+        XOR     GR3,GR3         ; 上位word
+        XOR     GR5,GR5         ; 上位wordの一時値
+        AND     GR1,GR1         ; (GR1 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        AND     GR2,GR2         ; (GR2 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        LAD     GR4,1           ; 対象ビット
+LOOP    PUSH    0,GR4           ; ループ先頭。GR2のビット中でGR4が示すビットが0の場合、NEXTへジャンプ
+        AND     GR4,GR2         ; ↓
+        POP     GR4             ; ↓
+        JZE     NEXT1           ; ↓
+        ADDL    GR3,GR5         ; GR3 <- GR3 + GR5
+        ADDL    GR0,GR1         ; GR0 <- GR0 + GR1
+        JOV     AHB1            ; GR0がオーバーフローした場合、AHB1へジャンプ
+        JUMP    NEXT1           ; ↓
+AHB1    LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+NEXT1   SLL     GR4,1           ; GR4を1回左シフト
+        JOV     CHKOV           ; ↓
+        SLL     GR5,1           ; GR5を1回左シフト
+        CPL     GR4,GR2         ; (GR4 > GR2)の場合、CHKOVへジャンプ
+        JPL     CHKOV           ; ↓
+        SLL     GR1,1           ; GR1を1回左シフト
+        JOV     AHB2            ; GR1がオーバーフローした場合、AHBへジャンプ
+        JUMP    NEXT2           ; ↓
+AHB2    LAD     GR5,1,GR5       ; GR5 <- GR5 + 1
+NEXT2   JUMP    LOOP            ; ループ終端
+CHKOV   AND     GR3,GR3         ; GR3 = 0の場合、終了
         JZE     FIN             ; ↓
-        CPL     GR2,MAXLEN      ; (GR2 > MAXLEN)の場合、LENOVへジャンプ
-        JPL     LENOV           ; ↓
-        ST      GR1,STR         ; STR <- GR1 文字列の開始アドレス
-        ST      GR2,LEN         ; LEN <- GR2
-        LAD     GR2,10          ; GR2:10進数の「10」
-        XOR     GR4,GR4         ; GR4:値の一時格納
-        XOR     GR5,GR5         ; GR5:インデックス
-STOL    CPL     GR5,LEN         ; ループ先頭。(GR5 = LEN)の場合、ループ脱出
-        JZE     CP              ; ↓
-        LD      GR1,STR         ; GR1に、入力文字列中の次の桁を格納
-        ADDL    GR1,GR5         ; ↓
-        LD      GR1,0,GR1       ; ↓
-        CPL     GR1,ZERO        ; (GR1 < '0')の場合、NANへジャンプ
-        JMI     NAN             ; ↓
-        CPL     GR1,NINE        ; (GR1 > '9')の場合、NANへジャンプ
-        JPL     NAN             ; ↓
-        SUBL    GR1,ZERO        ; GR1の文字を、対応する数値に変換
-        ST      GR5,NLEN        ; GR5 <- LEN - NLEN - 1
-        LD      GR5,LEN         ; ↓
-        SUBA    GR5,NLEN        ; ↓
-MUL10   CPA     GR5,=1          ; ループ先頭。GR1 <- 10 ** GR5
-        JZE     NEXT            ; (GR5 = 1)の場合、ループ脱出
-        JMI     NEXT            ; ↓
-        CALL    MULL            ; MULLを呼び出し、GR0 <- GR1 * GR2
-        JOV     FIN             ; ↓ オーバーフロー時は、プログラム終端へジャンプ
-        LD      GR1,GR0         ; GR1 <- GR0
-        LAD     GR5,-1,GR5      ; GR5 <- GR5 -1
-        JUMP    MUL10           ; ループ終端へジャンプ
-NEXT    LD      GR5,NLEN        ; GR5 <- NLEN。復元
-        ADDL    GR4,GR1         ; GR4 <- GR4 + GR1
-        JOV     FIN             ; ↓
-        LAD     GR5,1,GR5       ; GR5 <- GR5 + 1
-        JUMP    STOL            ; ループ終端
-NAN     LAD     GR2,#FFFF       ; GR2 <- #FFFF
-        JUMP    FIN             ; FINへジャンプ
-CP      LD      GR1,GR4         ; GR0 <- GR4
-        LD      GR0,LEN         ; GR0 <- LEN
-        JUMP    FIN             ; プログラム終端へジャンプ
-LENOV   LAD     GR0,#FFFF       ; 文字列が最大長より大きい場合、GR0 <- #FFFF
-        SRA     GR0,1           ; ↓ オーバーフロー発生
+        LAD     GR4,#FFFF       ; GR3 <> 0の場合、オーバーフロー
+        SLL     GR4,1           ; ↓
+FIN     POP     GR5
+        POP     GR4
+        RET
+        END
+;;; 0〜65535の範囲にある正数のかけ算(筆算方式)を行う
+;;; 入力 GR1:被乗数 GR2:乗数
+;;; 出力 GR0:積の下位WORD GR3:積の上位WORD
+;;; 積が65535より大きい場合は、オーバーフロー
+MULL    START
+        PUSH    0,GR4
+        PUSH    0,GR5
+        XOR     GR0,GR0         ; 積
+        XOR     GR3,GR3         ; 上位word
+        XOR     GR5,GR5         ; 上位wordの一時値
+        AND     GR1,GR1         ; (GR1 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        AND     GR2,GR2         ; (GR2 = 0)の場合、終了
+        JZE     CHKOV           ; ↓
+        LAD     GR4,1           ; 対象ビット
+LOOP    PUSH    0,GR4           ; ループ先頭。GR2のビット中でGR4が示すビットが0の場合、NEXTへジャンプ
+        AND     GR4,GR2         ; ↓
+        POP     GR4             ; ↓
+        JZE     NEXT1           ; ↓
+        ADDL    GR3,GR5         ; GR3 <- GR3 + GR5
+        ADDL    GR0,GR1         ; GR0 <- GR0 + GR1
+        JOV     AHB1            ; GR0がオーバーフローした場合、AHB1へジャンプ
+        JUMP    NEXT1           ; ↓
+AHB1    LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
+NEXT1   SLL     GR4,1           ; GR4を1回左シフト
+        JOV     CHKOV           ; ↓
+        SLL     GR5,1           ; GR5を1回左シフト
+        CPL     GR4,GR2         ; (GR4 > GR2)の場合、CHKOVへジャンプ
+        JPL     CHKOV           ; ↓
+        SLL     GR1,1           ; GR1を1回左シフト
+        JOV     AHB2            ; GR1がオーバーフローした場合、AHBへジャンプ
+        JUMP    NEXT2           ; ↓
+AHB2    LAD     GR5,1,GR5       ; GR5 <- GR5 + 1
+NEXT2   JUMP    LOOP            ; ループ終端
+CHKOV   AND     GR3,GR3         ; GR3 = 0の場合、終了
+        JZE     FIN             ; ↓
+        LAD     GR4,#FFFF       ; GR3 <> 0の場合、オーバーフロー
+        SLL     GR4,1           ; ↓
 FIN     POP     GR5
         POP     GR4
         RET
-ZERO    DC      '0'
-NINE    DC      '9'
-MAXLEN  DC      5               ; 文字列の最大長
-STR     DS      1
-LEN     DS      1
-NLEN    DS      1
         END