From 7ac339dcd755848e9820142422752fbdc8186b5c Mon Sep 17 00:00:00 2001 From: j8takagi Date: Sat, 2 Jun 2018 16:42:30 +0900 Subject: [PATCH] =?utf8?q?casl2lib=E3=83=95=E3=82=A9=E3=83=AB=E3=83=80?= =?utf8?q?=E3=82=92=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- as/casl2lib/.gitignore | 3 + as/casl2lib/Makefile | 23 +++++-- as/casl2lib/casl2lib.dep | 39 +++++++++++ as/casl2lib/diva.casl | 47 ++++++++++++++ as/casl2lib/doc/call.gv | 24 +++++++ as/casl2lib/inl.casl | 84 ++++++++++++++++++++++++ as/casl2lib/l2str.casl | 74 +++++++++++++++++++++ as/casl2lib/mula.casl | 42 ++++++++++++ as/casl2lib/outa.casl | 64 ++++++++++++++++++ as/casl2lib/outa_q15.casl | 59 +++++++++++++++++ as/casl2lib/outb.casl | 74 +++++++++++++++++++++ as/casl2lib/outb_w.casl | 74 +++++++++++++++++++++ as/casl2lib/outl.casl | 74 +++++++++++++++++++++ as/casl2lib/outl_q15.casl | 42 ++++++++++++ as/casl2lib/outpbm.casl | 115 ++++++++++++++++++++++++++++++++ as/casl2lib/pbm16.casl | 111 +++++++++++++++++++++++++++++++ as/casl2lib/str2l.casl | 133 ++++++++++++++++++++++---------------- 17 files changed, 1021 insertions(+), 61 deletions(-) create mode 100644 as/casl2lib/.gitignore create mode 100644 as/casl2lib/casl2lib.dep create mode 100644 as/casl2lib/doc/call.gv diff --git a/as/casl2lib/.gitignore b/as/casl2lib/.gitignore new file mode 100644 index 0000000..04dbd3d --- /dev/null +++ b/as/casl2lib/.gitignore @@ -0,0 +1,3 @@ +*.casl +doc/call.svg +sample/*.pbm diff --git a/as/casl2lib/Makefile b/as/casl2lib/Makefile index 880ba6b..1392daa 100644 --- a/as/casl2lib/Makefile +++ b/as/casl2lib/Makefile @@ -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 index 0000000..9bb2032 --- /dev/null +++ b/as/casl2lib/casl2lib.dep @@ -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 diff --git a/as/casl2lib/diva.casl b/as/casl2lib/diva.casl index 6796eb9..9b34690 100644 --- a/as/casl2lib/diva.casl +++ b/as/casl2lib/diva.casl @@ -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 index 0000000..2579add --- /dev/null +++ b/as/casl2lib/doc/call.gv @@ -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; +} + diff --git a/as/casl2lib/inl.casl b/as/casl2lib/inl.casl index 3587131..ec8bd8b 100644 --- a/as/casl2lib/inl.casl +++ b/as/casl2lib/inl.casl @@ -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 diff --git a/as/casl2lib/l2str.casl b/as/casl2lib/l2str.casl index a3dba83..736c888 100644 --- a/as/casl2lib/l2str.casl +++ b/as/casl2lib/l2str.casl @@ -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 diff --git a/as/casl2lib/mula.casl b/as/casl2lib/mula.casl index 431486a..e997471 100644 --- a/as/casl2lib/mula.casl +++ b/as/casl2lib/mula.casl @@ -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 diff --git a/as/casl2lib/outa.casl b/as/casl2lib/outa.casl index 6f8f84d..baf71c9 100644 --- a/as/casl2lib/outa.casl +++ b/as/casl2lib/outa.casl @@ -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 diff --git a/as/casl2lib/outa_q15.casl b/as/casl2lib/outa_q15.casl index 7c0e01c..74b1e2d 100644 --- a/as/casl2lib/outa_q15.casl +++ b/as/casl2lib/outa_q15.casl @@ -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 diff --git a/as/casl2lib/outb.casl b/as/casl2lib/outb.casl index 7ecb73e..dd1ebaa 100644 --- a/as/casl2lib/outb.casl +++ b/as/casl2lib/outb.casl @@ -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 diff --git a/as/casl2lib/outb_w.casl b/as/casl2lib/outb_w.casl index d64bff6..cf709d6 100644 --- a/as/casl2lib/outb_w.casl +++ b/as/casl2lib/outb_w.casl @@ -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 diff --git a/as/casl2lib/outl.casl b/as/casl2lib/outl.casl index a2967d8..bf16e79 100644 --- a/as/casl2lib/outl.casl +++ b/as/casl2lib/outl.casl @@ -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 diff --git a/as/casl2lib/outl_q15.casl b/as/casl2lib/outl_q15.casl index 2ae4b25..0355a6f 100644 --- a/as/casl2lib/outl_q15.casl +++ b/as/casl2lib/outl_q15.casl @@ -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 diff --git a/as/casl2lib/outpbm.casl b/as/casl2lib/outpbm.casl index 70803c3..146e89a 100644 --- a/as/casl2lib/outpbm.casl +++ b/as/casl2lib/outpbm.casl @@ -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 diff --git a/as/casl2lib/pbm16.casl b/as/casl2lib/pbm16.casl index 39671ca..e615f35 100644 --- a/as/casl2lib/pbm16.casl +++ b/as/casl2lib/pbm16.casl @@ -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 diff --git a/as/casl2lib/str2l.casl b/as/casl2lib/str2l.casl index 1394131..591ef66 100644 --- a/as/casl2lib/str2l.casl +++ b/as/casl2lib/str2l.casl @@ -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 -- 2.18.0