--- /dev/null
+/*.casl
+doc/call.svg
+sample/*.pbm
--- /dev/null
+.PHONY: all libfiles install-casl2lib uninstall-casl2lib
+
+CAT := cat
+CASL2OUT := casl2 -M4096 -O
+RMF := rm -f
+RMDIR := rmdir
+ECHO := echo
+INSTALL := install
+CHMOD := chmod
+
+prefix ?= ~
+casl2libdir ?= $(prefix)/share/casl2lib
+
+all: stdlib.casl libfiles
+
+%.casl: src/%.casl
+ $(CHMOD) +w $@
+ $(CAT) $^ >$@
+ $(CHMOD) -w $@
+
+%.o: %.casl
+ $(CASL2OUT)$< $@
+
+include casl2lib.dep
+
+clean:
+
+distclean:
+ $(RM) *.casl
+
+install-casl2lib: *.casl
+ $(INSTALL) -d $(casl2libdir)
+ $(INSTALL) $^ $(casl2libdir)/
+
+uninstall-casl2lib:
+ @$(RMF) $(casl2libdir)/*.casl
+ @$(RMDIR) $(casl2libdir) || if test -e $(casl2libdir); then $(ECHO) "$(casl2libdir): files may be added by others."; fi
--- /dev/null
+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/outaq15.casl src/outb.casl src/outbw.casl src/outl.casl src/outlq15.casl src/outpbm.casl src/pbm16.casl src/rev.casl src/str2l.casl
+
+libfiles: abs.casl addl32.casl diva.casl divl.casl inl.casl l2str.casl max.casl minim.casl mula.casl mull.casl outa.casl outaq15.casl outb.casl outbw.casl outl.casl outlq15.casl outpbm.casl pbm16.casl 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 rev.casl
+
+outaq15.casl: src/outaq15.casl abs.casl mull.casl
+
+outb.casl: src/outb.casl divl.casl rev.casl
+
+outbw.casl: src/outbw.casl divl.casl rev.casl
+
+outl.casl: src/outl.casl divl.casl rev.casl
+
+outlq15.casl: src/outlq15.casl mull.casl
+
+outpbm.casl: src/outpbm.casl l2str.casl
+
+pbm16.casl: src/pbm16.casl outb.casl
+
+rev.casl: src/rev.casl
+
+str2l.casl: src/str2l.casl mull.casl
--- /dev/null
+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;
+}
+
--- /dev/null
+;;; ABSを呼び出す
+;;; casl2 call_abs.casl ../stdlib.casl
+MAIN START
+ LAD GR2,0
+MLOOP CPA GR2,MLEN
+ JZE MFIN
+ LD GR1,MVAL,GR2
+ CALL OUTA
+ CALL ABS
+ JOV PUTOV
+ JMI PUTM
+ OUT PLUS,=1
+ JUMP PUTD
+PUTM OUT MINUS,=1
+ JUMP PUTD
+PUTOV OUT OV,=2
+PUTD CALL OUTA
+ OUT SEP,MLEN
+ LAD GR2,1,GR2
+ JUMP MLOOP
+MFIN RET
+MVAL DC 12,-12,1,-1,32767,-32767,0,-32768
+MLEN DC 8
+SEP DC '--------'
+PLUS DC '+'
+MINUS DC '-'
+OV DC 'OV'
+ END
--- /dev/null
+MAIN START
+ LAD GR1,A
+ LAD GR2,B
+ CALL ADDL32
+ LD GR2,GR0
+ LD GR1,1,GR2
+ CALL OUTL
+ LD GR1,0,GR2
+ CALL OUTL
+ RET
+A DC 6,10
+B DC 2,65530
+ END
--- /dev/null
+MAIN START
+ LD GR1,XMAX
+LOOPX CPA GR1,XMIN
+ JMI FIN
+ OUT SEP,SLEN
+ LD GR2,YMIN
+LOOPY CPL GR2,YMAX
+ JPL XNEXT
+ CALL OUTL
+ PUSH 0,GR1
+ LD GR1,GR2
+ CALL OUTL
+ POP GR1
+ CALL DIVL
+ JOV WOV
+ PUSH 0,GR1
+ LD GR1,GR0
+ CALL OUTL
+ LD GR1,GR3
+ CALL OUTL
+ POP GR1
+YNEXT OUT SEP,SLEN
+ LAD GR2,1,GR2
+ JUMP LOOPY
+WOV OUT Y0MSG,YLEN
+ JUMP YNEXT
+XNEXT LAD GR1,-1,GR1
+ JUMP LOOPX
+FIN RET
+XMAX DC 100
+XMIN DC 0
+YMAX DC 10
+YMIN DC 0
+SEP DC '--------------------'
+SLEN DC 20
+Y0MSG DC 'Error: div by 0'
+YLEN DC 15
+ END
--- /dev/null
+;;; casl2 inl.casl ../casl2lib/inl.casl ../casl2lib/outl.casl
+MAIN START
+LOOP CALL INL ; GR1に数値、GR2に文字列の長さ
+ JOV NAN
+ JMI BIG
+ LD GR2,GR2
+ JZE FIN
+ CALL OUTL
+ JUMP LOOP
+NAN OUT NANMSG,NANLEN
+ JUMP LOOP
+BIG OUT BIGMSG,BIGLEN
+ JUMP LOOP
+FIN RET
+NANMSG DC 'Not a number'
+NANLEN DC 12
+BIGMSG DC 'Over 65535'
+BIGLEN DC 10
+ END
--- /dev/null
+MAIN START
+ LD GR1,L
+ LAD GR2,STR
+ CALL L2STR
+ ST GR0,LEN
+ OUT STR,LEN
+ RET
+L DC 6543
+STR DS 5
+LEN DS 1
+ END
--- /dev/null
+;;; casl2 minim.casl $(LIBDIR)/minim.casl $(LIBDIR)/outa.casl
+MAIN START
+ LAD GR1,DATA
+ LD GR2,CNT
+ CALL MINIM
+ LD GR1,GR0
+ CALL OUTA
+ RET
+DATA DC 23,78,2,45,67,-39,86
+CNT DC 7
+ END
--- /dev/null
+MAIN START
+ LAD GR3,0 ; Xのインデックス
+LOOPX CPA GR3,XCNT
+ JZE FIN
+ LD GR1,X,GR3
+ LAD GR4,0 ; Yのインデックス
+LOOPY CPA GR4,YCNT
+ JZE XNEXT
+ LD GR2,Y,GR4
+ CALL OUTA
+ PUSH 0,GR1
+ LD GR1,GR2
+ CALL OUTA
+ POP GR1
+ CALL MULA
+ JOV WOV
+ PUSH 0,GR1
+ LD GR1,GR0
+ CALL OUTA
+ POP GR1
+YNEXT OUT SEP,SLEN
+ LAD GR4,1,GR4
+ JUMP LOOPY
+WOV OUT YOMSG,YLEN
+ JUMP YNEXT
+XNEXT LAD GR3,1,GR3
+ JUMP LOOPX
+FIN RET
+X DC 0,1,2,127,128,151,217,255,256,257,32767,-32768,-32767,-257,-256,-255,-217,-151,-128,-127,-2,-1
+Y DC 0,1,2,127,128,151,217,255,256,257,32767,-32768,-32767,-257,-256,-255,-217,-151,-128,-127,-2,-1
+XCNT DC 22
+YCNT DC 22
+SEP DC '--------------------'
+SLEN DC 20
+YOMSG DC 'Warning: overflow'
+YLEN DC 17
+ END
--- /dev/null
+MAIN START
+ LAD GR4,0 ; Xのインデックス
+LOOPX CPA GR4,XCNT ; (GR4 = XCNT)の場合、ループ脱出
+ JZE FIN ; ↓
+ LD GR1,X,GR4 ; GR1に、(X+GR4)番地の値を転送
+ LAD GR5,0 ; Yのインデックス
+LOOPY CPA GR5,YCNT ; (GR5 = YCNT)の場合、ループ脱出
+ JZE XNEXT ; ↓
+ LD GR2,Y,GR5 ; GR2に、(X+GR5)番地の値を転送
+ CALL OUTL ; GR1の数値を出力
+ PUSH 0,GR1 ; GR2の数値を出力
+ LD GR1,GR2 ; ↓
+ CALL OUTL ; ↓
+ POP GR1 ; ↓
+ CALL MULL ; GR3 <- GR1 * GR2
+ JOV WOV ; オーバーフローの場合は、WOVへジャンプ
+ PUSH 0,GR1 ; GR3の数値を出力
+ LD GR1,GR3 ; ↓
+ CALL OUTL ; ↓
+ POP GR1 ; ↓
+YNEXT OUT SEP,SLEN ; 区切り線を出力
+ LAD GR5,1,GR5 ; GR5 <- GR5 + 1
+ JUMP LOOPY ; LOOPYへジャンプ
+WOV OUT YOMSG,YLEN ; オーバーフローした場合のメッセージを表示
+ OUT SEP,SLEN ; 区切り線を出力
+XNEXT LAD GR4,1,GR4 ; GR4 <- GR4 + 1
+ JUMP LOOPX ; LOOPXへジャンプ
+FIN RET
+X DC 0,1,2,127,128,255,256,257,32767,#8000,#FFFF
+Y DC 0,1,2,127,128,255,256,257,32767,#8000,#FFFF
+XCNT DC 11
+YCNT DC 11
+SEP DC '--------------------'
+SLEN DC 20
+YOMSG DC 'overflow'
+YLEN DC 8
+ END
--- /dev/null
+;; casl2 outi_call.casl outi.casl
+MAIN START
+ LAD GR1,VAL
+ LAD GR2,0
+LOOP CPA GR2,CNT
+ JZE FIN
+ LD GR1,VAL,GR2
+ CALL OUTA
+ LAD GR2,1,GR2
+ JUMP LOOP
+FIN RET
+VAL DC 0
+ DC #0001,#0002,#0004,#0008
+ DC #0010,#0020,#0040,#0080
+ DC #0100,#0200,#0400,#0800
+ DC #1000,#2000,#4000,#7FFF
+ DC #8000
+ DC #8001,#C000,#E000,#F000
+ DC #F800,#FC00,#FE00,#FF00
+ DC #FF80,#FFC0,#FFE0,#FFF0
+ DC #FFF8,#FFFC,#FFFE,#FFFF
+CNT DC 34
+ END
--- /dev/null
+;; outd_q15.caslを呼び出し、33個の数値を表示する
+MAIN START
+ LAD GR2,0
+LOOP LD GR1,VAL,GR2
+ CALL OUTAQ15
+ LAD GR2,1,GR2
+ CPA GR2,CNT
+ JZE FIN
+ JUMP LOOP
+FIN RET
+VAL DC #7FFF,#4000,#2000,#1000
+ DC #0800,#0400,#0200,#0100
+ DC #0080,#0040,#0020,#0010
+ DC #0008,#0004,#0002,#0001
+ DC #8000
+ DC #8001,#C000,#E000,#F000
+ DC #F800,#FC00,#FE00,#FF00
+ DC #FF80,#FFC0,#FFE0,#FFF0
+ DC #FFF8,#FFFC,#FFFE,#FFFF
+CNT DC 33
+ END
--- /dev/null
+;;; casl2 outb_call.casl outb.casl
+MAIN START
+ LAD GR2,0
+LOOP LD GR1,VAL,GR2
+ CALL OUTB
+ LAD GR2,1,GR2
+ CPA GR2,CNT
+ JZE FIN
+ JUMP LOOP
+FIN RET
+VAL DC 0
+ DC #0001,#0002,#0004,#0008
+ DC #0010,#0020,#0040,#0080
+ DC #0100,#0200,#0400,#0800
+ DC #1000,#2000,#4000,#7FFF
+ DC #8000
+ DC #8001,#C000,#E000,#F000
+ DC #F800,#FC00,#FE00,#FF00
+ DC #FF80,#FFC0,#FFE0,#FFF0
+ DC #FFF8,#FFFC,#FFFE,#FFFF
+CNT DC 34
+ END
--- /dev/null
+;;; casl2 outb_call.casl outb.casl
+MAIN START
+ LAD GR2,0
+LOOP LD GR1,VAL,GR2
+ CALL OUTBW
+ LAD GR2,1,GR2
+ CPA GR2,CNT
+ JZE FIN
+ JUMP LOOP
+FIN RET
+VAL DC 0
+ DC #0001,#0002,#0004,#0008
+ DC #0010,#0020,#0040,#0080
+ DC #0100,#0200,#0400,#0800
+ DC #1000,#2000,#4000,#7FFF
+ DC #8000
+ DC #8001,#C000,#E000,#F000
+ DC #F800,#FC00,#FE00,#FF00
+ DC #FF80,#FFC0,#FFE0,#FFF0
+ DC #FFF8,#FFFC,#FFFE,#FFFF
+CNT DC 34
+ END
--- /dev/null
+;;; casl2 outl_call.casl outl.casl
+MAIN START
+ LAD GR2,0
+LOOP LD GR1,VAL,GR2
+ CALL OUTL
+ LAD GR2,1,GR2
+ CPA GR2,CNT
+ JZE FIN
+ JUMP LOOP
+FIN RET
+VAL DC 0
+ DC #0001,#0002,#0004,#0008
+ DC #0010,#0020,#0040,#0080
+ DC #0100,#0200,#0400,#0800
+ DC #1000,#2000,#4000,#7FFF
+ DC #8000
+ DC #8001,#C000,#E000,#F000
+ DC #F800,#FC00,#FE00,#FF00
+ DC #FF80,#FFC0,#FFE0,#FFF0
+ DC #FFF8,#FFFC,#FFFE,#FFFF
+CNT DC 34
+ END
--- /dev/null
+;; outd_q15.caslを呼び出し、33個の数値を表示する
+MAIN START
+ LAD GR2,0
+LOOP LD GR1,VAL,GR2
+ CALL OUTLQ15
+ LAD GR2,1,GR2
+ CPA GR2,CNT
+ JZE FIN
+ JUMP LOOP
+FIN RET
+VAL DC #0001,#0002,#0004,#0008
+ DC #0010,#0020,#0040,#0080
+ DC #0100,#0200,#0400,#0800
+ DC #1000,#2000,#4000,#7FFF
+ DC #8000
+ DC #8001,#C000,#E000,#F000
+ DC #F800,#FC00,#FE00,#FF00
+ DC #FF80,#FFC0,#FFE0,#FFF0
+ DC #FFF8,#FFFC,#FFFE,#FFFF
+CNT DC 33
+ END
--- /dev/null
+;;; 「五」を表す16 x 16のpbm画像を出力する
+;;; 呼び出し方:
+;;; casl2 call_pbm.casl ../pbm16.casl
+MAIN START
+ LAD GR1,GRAPH
+ CALL PBM16
+ RET
+GRAPH DC #FFFC ; 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
+ DC #FFFC ; 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
+ DC #FFFC ; 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
+ DC #0700 ; 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0
+ DC #0700 ; 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0
+ DC #0700 ; 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0
+ DC #FFFC ; 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
+ DC #FFFC ; 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
+ DC #FFFC ; 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
+ DC #071C ; 0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0
+ DC #071C ; 0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0
+ DC #071C ; 0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0
+ DC #FFFF ; 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ DC #FFFF ; 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ DC #FFFF ; 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ DC #0000 ; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ END
--- /dev/null
+MAIN START
+ OUT STR,LEN
+ LAD GR1,STR
+ LD GR2,LEN
+ CALL REV
+ OUT STR,LEN
+ RET
+STR DC '12345'
+LEN DC 5
+ END
--- /dev/null
+;;; casl2 call_str2l.casl stdlib.casl
+MAIN START
+ XOR GR4,GR4
+ LAD GR6,LEN
+BLP LAD GR1,STR,GR4
+ LD GR2,0,GR6
+ JZE FIN
+ LD GR5,GR1
+ CALL STR2L
+ JOV OV
+ JMI NAN
+ LD GR1,GR3
+ CALL OUTL
+ LD GR1,GR5
+ JUMP ELP
+OV OUT MSGOV,LENOV
+ JUMP ELP
+NAN OUT MSGNAN,LENNAN
+ELP ADDL GR4,GR2
+ LAD GR6,1,GR6
+ JUMP BLP
+FIN RET
+STR DC '0'
+ DC '1'
+ DC '123'
+ DC '1234'
+ DC '65535'
+ DC '65536'
+ DC '123456'
+ DC 'a'
+LEN DC 1
+ DC 1
+ DC 3
+ DC 4
+ DC 5
+ DC 5
+ DC 6
+ DC 1
+ DC 0
+MSGOV DC 'over 65535'
+LENOV DC 10
+MSGNAN DC 'not a logical integer'
+LENNAN DC 21
+ END
--- /dev/null
+;;; call_strlen.casl
+;;;
+MAIN START
+ PUSH 0,GR1
+ LAD GR1,STR
+ CALL STRLEN
+ LD GR1,GR2
+ CALL OUTL
+FIN POP GR1
+ RET
+STR DC 'abcdefghij',0 ; 文字列
+ END
--- /dev/null
+;;; 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
--- /dev/null
+;;; 2つの32ビット値を加算する
+;;; 32ビットの値を、連続する2語の領域に格納
+;;; 入力 GR1:数値1の先頭アドレス GR2:数値2の先頭アドレス
+;;; 出力 GR0:和の先頭アドレス
+ADDL32 START
+ RPUSH
+ ST GR1,X ; X <- GR1:数値1
+ ST GR2,Y ; Y <- GR2:数値2
+ LD GR3,LEN ; GR3:語を表すインデックス 初期化
+ XOR GR4,GR4 ; GR4:キャリー値 初期化
+ LAD GR3,-1,GR3 ; ↓
+LOOP AND GR3,GR3 ; ループ先頭。(GR3 = 0)の場合は、ループ脱出
+ JMI FIN ; ↓
+ LD GR1,X ; GR1 <- (X + GR3)の値
+ ADDL GR1,GR3 ; ↓
+ LD GR1,0,GR1 ; ↓
+ LD GR2,Y ; GR2 <- (Y + GR3)の値
+ ADDL GR2,GR3 ; ↓
+ LD GR2,0,GR2 ; ↓
+ ADDL GR1,GR2 ; GR1 <- GR1 + GR2
+ JOV CRRY ; オーバーフロー時は、CRRYへジャンプ
+ ADDL GR1,GR4 ; GR1 <- GR1 + GR4
+ JOV CRRY ; オーバーフロー時は、CRRYへジャンプ
+ ST GR1,A,GR3 ; (A + GR3) <- GR1
+ LAD GR3,-1,GR3 ; GR3 <- GR3 - 1
+ XOR GR4,GR4 ; GR4 <- 0
+ JUMP LOOP ; ループ先頭へジャンプ
+CRRY AND GR3,GR3 ; 最上位の語でオーバーフローした場合、OVへジャンプ
+ JMI OV ; ↓
+ ST GR1,A,GR3 ; (A + GR3) <- GR1
+ LAD GR3,-1,GR3 ; GR3 <- GR3 - 1
+ LAD GR4,1 ; GR4 <- 1
+ JUMP LOOP ; ループ終端
+OV LAD GR3,=#8000 ; 強制的にオーバーフロー発生
+ SLL GR3,1 ; ↓
+FIN LAD GR0,A ; GR0 <- A
+ RPOP
+ RET
+X DS 1 ; 数値1の先頭アドレス
+Y DS 1 ; 数値2の先頭アドレス
+A DS 2 ; 和
+LEN DC 2 ; 数値の語数
+ END
--- /dev/null
+;;; 符号付き整数の割算を筆算方式で行う
+;;; 入力 GR1:被除数 GR2:除数
+;;; 出力 GR0:商 GR3:剰余
+;;; 次の場合はオーバーフロー
+;;; GR1 = -32768; GR2 = -32768; GR2 = 0
+;;;
+DIVA START
+ PUSH 0,GR1
+ PUSH 0,GR2
+ PUSH 0,GR4
+ XOR GR0,GR0 ; 商を初期化
+ XOR GR4,GR4 ; マイナスフラグを初期化
+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)の場合は、DIVへジャンプ
+ JPL DIV ; ↓
+ XOR GR2,ALLON ; GR2の正負を反転
+ ADDA GR2,ONE ; ↓
+ JOV FIN ; (GR2 = -32768)の場合は終了
+ XOR GR4,ONE ; マイナスフラグを反転
+DIV CALL DIVL ; GR0 <- GR1 / GR2; GR3 <- GR1 mod GR2
+ JOV FIN ; (GR2 = 0)の場合は終了
+MIN AND GR4,GR4 ; マイナスフラグがオフの場合、終了
+ JZE FIN ; ↓
+ XOR GR0,ALLON ; GR1の正負を反転
+ ADDA GR0,ONE ; ↓
+ XOR GR3,ALLON ; GR3の正負を反転
+ ADDA GR3,ONE ; ↓
+ JUMP FIN
+OV ADDL GR0,=#8000
+FIN POP GR4
+ POP GR2
+ POP GR1
+ RET
+ONE DC 1
+ALLON DC #FFFF
+ END
--- /dev/null
+;;; 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
--- /dev/null
+;;; 0から65535の範囲にある整数の入力を受け付ける
+;;; 入力 (SVC)
+;;; 出力 GR1: 入力された数値
+;;; GR2: 文字列の長さ。
+;;; 入力が数字以外の場合は、SFフラグを設定
+;;; 65535を超える数値の場合は、OFフラグを設定
+INL START
+ PUSH 0,GR3
+ IN IBUF,ILEN ; 入力文字列を格納
+ LAD GR1,IBUF
+ LD GR2,ILEN
+ CALL STR2L
+ JOV FIN
+ JMI FIN
+ LD GR1,GR3
+FIN POP GR3
+ RET
+IBUF DS 5
+ILEN DS 1
+MAXLEN DC 5
+ END
--- /dev/null
+;;; 符号なし整数を文字列に変換する。
+;;; 符号なし整数を文字列に変換する。
+;;; 入力 GR1:符号なし整数 G2:変換した文字列を格納するメモリーの先頭アドレス
+;;; 出力 GR0:文字列の長さ (同上)
+;;; 依存プログラム: DIVL, REV
+L2STR START
+ PUSH 0,GR1
+ PUSH 0,GR4
+ XOR GR0,GR0 ; GR0 <- 0
+ LD GR4,GR2 ; GR4 <- GR2
+ PUSH 0,GR2 ; GR2の保存
+ LAD GR2,10 ; GR2 <- 10。10進数の 10
+LOOP LD GR1,GR1 ; ループ先頭。GR1をテスト
+ JZE SRT ; GR1が0の場合、ループ終了
+ CALL DIVL ; GR1とGR2の、商をGR0、剰余をGR3に格納
+ ADDL GR3,='0' ; GR3を文字に変換
+ ST GR3,0,GR4 ; GR4のアドレスに、GR3を格納
+ LAD GR4,1,GR4 ; GR4 <- GR4 + 1
+ LD GR1,GR0 ; GR0の商をGR1にコピー
+ JUMP LOOP ; ループ終端
+SRT POP GR2 ; GR2の復元
+ LD GR1,GR2 ; GR1に文字列のアドレスを格納
+ SUBL GR4,GR2 ; GR4 <- GR4 - GR2
+ LD GR2,GR4 ; GR2 <- GR4
+ CALL REV ; 文字列を逆順に並べ替え
+ LD GR0,GR2 ; GR0 <- GR4 文字列の長さを格納
+ POP GR4
+ POP GR1
+ RET
+ END
--- /dev/null
+;;; 連続した複数のWORDを符号付き整数とみなして最大値を返す
+;;; 入力: GR1: WORD値を格納したアドレス GR2: 値の個数
+;;; 出力: GR0: 最大値
+MAX START
+ RPUSH
+ LD GR0,0,GR1 ; MAX <- GR1アドレスの値
+ ST GR0,MAX ; ↓
+ LAD GR3,0 ; GR3:インデックス 初期化
+S1 CPA GR3,GR2 ; ループ先頭。(GR2 = GR3)の場合、終了
+ JZE RET ; ↓
+ LAD GR1,1,GR1 ; GR1 <- GR1 + 1
+ LD GR0,0,GR1 ;
+ CPA GR0,MAX ;
+ JMI S2 ;
+ JZE S2 ;
+ ST GR0,MAX ;
+S2 LAD GR3,1,GR3 ;
+ JUMP S1 ;
+RET LD GR0,MAX ;
+ RPOP
+ RET
+MAX DS 1 ; 最小値を格納
+ END
--- /dev/null
+;;; 複数のWORD値の中から、最小値を返す
+;;; 入力: GR1: WORD値を格納したアドレス GR2: 値の個数
+;;; 出力: GR0: 最小値
+MINIM START
+ RPUSH
+ LD GR0,0,GR1 ; MIN <- GR1アドレスの値
+ ST GR0,MIN ; ↓
+ LAD GR3,0 ; GR3:インデックス 初期化
+S1 CPA GR3,GR2 ; ループ先頭。(GR2 = GR3)の場合、終了
+ JZE RET ; ↓
+ LAD GR1,1,GR1 ; GR1 <- GR1 + 1
+ LD GR0,0,GR1 ;
+ CPA GR0,MIN ;
+ JPL S2 ;
+ JZE S2 ;
+ ST GR0,MIN ;
+S2 LAD GR3,1,GR3 ;
+ JUMP S1 ;
+RET LD GR0,MIN ;
+ RPOP
+ RET
+MIN DS 1 ; 最小値を格納
+ END
--- /dev/null
+;;; -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 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 MUL ; ↓
+ XOR GR2,ALLON ; GR2の正負を反転
+ ADDA GR2,ONE ; ↓
+ JOV FIN ; (GR2 = -32768)の場合は終了
+ XOR GR4,ONE ; マイナスフラグを反転
+MUL CALL MULL ; GR0 <- GR1 * GR2
+ JOV FIN
+ AND GR0,GR0
+ JMI OV
+MIN AND GR4,GR4 ; マイナスフラグがオフの場合、終了
+ JZE FIN ; ↓
+ XOR GR0,ALLON ; GR1の正負を反転
+ ADDA GR0,ONE ; ↓
+ JUMP FIN
+OV ADDL GR0,=#8000
+FIN RPOP
+ RET
+ONE DC 1
+ALLON DC #FFFF
+ END
--- /dev/null
+;;; 0〜65535の範囲にある正数のかけ算(筆算方式)を行う
+;;; 入力 GR1:被乗数 GR2:乗数
+;;; 出力 GR3:積
+;;; 積が65535より大きい場合は、オーバーフロー
+MULL START
+ XOR GR3,GR3 ; GR3の初期化
+ AND GR1,GR1 ; GR1 = 0 の場合、FINへジャンプ
+ JZE FIN ; ↓
+ AND GR2,GR2 ; GR2 = 0 の場合、FINへジャンプ
+ JZE FIN ; ↓
+ PUSH 0,GR1 ; GR1の退避
+ PUSH 0,GR2 ; GR2の退避
+LOOP SRL GR2,1 ; ループ開始。SRLを1つ右シフト
+ JOV ON ; 乗数の最下位ビットが1の場合、ONへジャンプ
+ JUMP NEXT ; NEXTへジャンプ
+ON ADDL GR3,GR1 ; GR3 <- GR3 + GR1
+ JOV POST ; GR3がオーバーフローした場合、POSTへジャンプ
+NEXT AND GR2,GR2 ; GR2 = 0 の場合、POSTへジャンプ
+ JZE POST ; ↓
+ SLL GR1,1 ; GR1を1つ左シフト
+ JOV POST ; GR1がオーバーフローした場合、POSTへジャンプ
+ JUMP LOOP ; ループ終端
+POST POP GR2 ; GR2の復元
+ POP GR1 ; GR1の復元
+FIN RET
+ END
--- /dev/null
+; 符号なし乗算
+; 入力
+; GR0 = 被乗数
+; GR1 = 乗数
+; 出力
+; GR3 = 結果
+MULL START
+; レジスタを退避
+ PUSH 0,GR1
+ PUSH 0,GR2
+; 初期化
+ XOR GR3,GR3 ; GR3 = 積
+; 被乗数をシフトしながら加算していく
+LOOP SRL GR2,1 ; 最下位ビットが
+ JOV ONE ; 1なら加算
+ JUMP ZERO ; 0なら加算しない
+ONE ADDL GR3,GR1 ;
+ZERO SLL GR1,1 ; 被乗数をシフト
+ AND GR2,GR2 ; 乗数に1のビットが
+ JNZ LOOP ; あれば続行
+; レジスタを復元
+ POP GR2
+ POP GR1
+ RET
+ END
--- /dev/null
+;;; GR1に格納された値を、10進数の整数値(-32768〜32767)として表示
+OUTA START
+ RPUSH
+ LAD GR2,10 ; GR2に10進数の「10」を格納。
+ LAD GR0,0 ; GR0 <- 0
+ LAD GR4,0 ; 負数フラグ。GR1が負数の場合、GR4は1
+ LAD GR5,0 ; 整数値の長さ
+ AND GR1,GR1 ; GR1をテスト
+ JZE ZPRT ; GR1が0の場合、ZPRTにジャンプ
+ JPL STI ; GR1が正数の場合、STIにジャンプ
+ LAD GR4,1 ; GR1が負数の場合、GR4をオン
+ CALL ABS ; GR1を正数に変換
+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,GR5 ; (STR + GR5) <- GR1
+ LAD GR5,1,GR5 ; GR5 <- GR5 + 1
+ LD GR1,GR0 ; GR0をGR1にコピー
+ JUMP STI ; ループ終端
+STLST LD GR1,NCHAR,GR1 ; GR1を文字に変換
+ ST GR1,STR,GR5 ; (STR + GR5) <- GR1
+ LAD GR5,1,GR5 ; GR5 <- GR5 + 1
+ AND GR4,GR4 ; 正数の場合
+ JZE PRT ; ↓
+ LD GR1,='-' ; 負数の場合、「-」をSTR領域に格納
+ ST GR1,STR,GR5 ; (STR + GR5) <- GR1
+ LAD GR5,1,GR5 ; GR5 <- GR5 + 1
+ JUMP PRT ; PRTにジャンプ
+ZPRT LD GR1,NCHAR ; 「0」をSTR領域に格納
+ ST GR1,STR,GR5 ; (STR + GR5) <- GR1
+ LAD GR5,1,GR5 ; GR5 <- GR5 + 1
+PRT ST GR5,LEN ; LEN <- GR5
+ LD GR2,LEN ; GR2にLENの値を格納
+ LAD GR1,STR ; GR1に文字列のアドレスを格納
+ CALL REV ; 文字列を逆順に並べ替え
+ OUT STR,LEN ; 文字列を出力
+ RPOP
+ RET
+STR DS 17
+LEN DS 1
+NCHAR DC '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ END
--- /dev/null
+;; GR1に格納された値を、10進数の符号付き小数値として表示
+OUTAQ15 START
+ RPUSH
+ LAD GR2,10 ; GR2に10進数の「10」を格納
+ XOR GR4,GR4 ; 整数値の長さ
+ XOR GR3,GR3 ; 出力する文字を一時的に格納
+ AND GR1,GR1 ; GR1の符号をチェック
+ JPL STDN ; ↓ GR1が正数の場合、STDNにジャンプ
+ LD GR3,='-' ; ↓ GR1が負数の場合、「-」をSTR領域に格納
+ ST GR3,STR ; ↓ ↓
+ LAD GR4,1,GR4 ; ↓ ↓ GR4 <- GR4 + 1
+ CPA GR1,=#8000 ; (GR1 = #8000)の場合、MINONEへジャンプ
+ JZE MINONE ; ↓
+ CALL ABS ; GR1を正数に変換
+STDN LD GR3,='0' ; 「0」をSTR領域に格納
+ ST GR3,STR,GR4 ; ↓
+ AND GR1,GR1 ; GR1が0の場合、PRTへジャンプ
+ JZE PRT ; ↓
+ LAD GR4,1,GR4 ; ↓ GR4 <- GR4 + 1
+ LD GR3,='.' ; 「.」をSTR領域に格納
+ ST GR3,STR,GR4 ; ↓
+ LAD GR4,1,GR4 ; ↓ GR4 <- GR4 + 1
+ SLL GR1,1 ; GR1を1回左シフト
+;; GR1の内容を小数値と見なし、10進数の文字列に変換してSTRに格納
+TODIG AND GR1,GR1 ; GR1が0の場合は、ループを脱出
+ JZE PRT ; ↓
+ CALL MULL ; GR1とGR2の、積をGR1、オーバーフロー値をGR3に格納
+ LD GR1,GR0 ; GR0をGR1にコピー
+ ADDA GR3,='0' ; GR1を文字に変換
+ ST GR3,STR,GR4 ; (STR + GR4) <- GR1
+ LAD GR4,1,GR4 ; GR4 <- GR4 + 1
+ JUMP TODIG ; ループ
+;; GR1 = -1の場合
+MINONE LD GR1,='1' ; GR1が#8000の場合、-1を出力
+ ST GR1,STR,GR4 ; (STR + GR4) <- GR1
+ LAD GR4,1,GR4 ; GR4 <- GR4 + 1
+ JUMP PRT ; ↓
+;; 値を出力
+PRT ST GR4,LEN ; LEN <- GR4
+ OUT STR,LEN ; ↓
+ RPOP
+ RET
+STR DS 20
+LEN DS 1
+ END
+
--- /dev/null
+;;; 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
--- /dev/null
+;;; GR1に格納された値を、空白付きの2進数値として表示
+OUTBW 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,SPC ; GR1 <- SPC
+ 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,SPC ; GR1 <- SPC
+ ST GR1,STR,GR4 ; (STR + GR4) <- GR1
+ LAD GR4,1,GR4 ; GR4 <- GR4 + 1
+ 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 32
+LEN DS 1
+BIN DC 2
+NCHAR DC '01'
+SPC DC ' '
+DIG DC 31
+ END
--- /dev/null
+;;; GR1に格納された値を、10進数の整数値(0〜65535)として表示
+;;; 依存プログラム: DIVL, REV
+OUTL START
+ RPUSH
+ LAD GR2,10 ; GR2に10進数の「10」を格納。
+ XOR GR0,GR0 ; GR0 <- 0
+ XOR GR4,GR4 ; 整数値の長さ
+ AND GR1,GR1 ; GR1をテスト
+ JZE ZERO ; GR1が0の場合、ZEROにジャンプ
+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
+ JUMP PRT ; PRTにジャンプ
+ZERO LD GR1,NCHAR ; 「0」をSTR領域に格納
+ ST GR1,STR,GR4 ; ↓ (STR + GR4) <- GR1
+ LAD GR4,1,GR4 ; ↓ GR4 <- GR4 + 1
+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 ; 符号付き2進数で表記した場合を想定
+LEN DS 1
+NCHAR DC '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ END
--- /dev/null
+;; GR1に格納された値を、10進数の符号なし小数値として表示
+OUTLQ15 START
+ RPUSH
+ LAD GR2,10 ; GR2に10進数の「10」を格納
+ XOR GR4,GR4 ; 整数値の長さ
+STDN LD GR3,='0' ; 「0」をSTR領域に格納
+ ST GR3,STR,GR4 ; ↓
+ AND GR1,GR1 ; GR1が0の場合、PRTへジャンプ
+ JZE PRT ; ↓
+ LAD GR4,1,GR4 ; ↓ GR4 <- GR4 + 1
+ LD GR3,='.' ; 「.」をSTR領域に格納
+ ST GR3,STR,GR4 ; ↓
+ LAD GR4,1,GR4 ; ↓ GR4 <- GR4 + 1
+;; GR1の内容を小数値と見なし、10進数の文字列に変換してSTRに格納
+TODIG AND GR1,GR1 ; GR1が0の場合は、ループを脱出
+ JZE PRT ; ↓
+ CALL MULL ; GR1とGR2の、積をGR0、オーバーフロー値をGR3に格納
+ LD GR1,GR0 ; GR0をGR1にコピー
+ ADDA GR3,='0' ; GR3を文字に変換
+ ST GR3,STR,GR4 ; (STR + GR3) <- GR1
+ LAD GR4,1,GR4 ; GR4 <- GR4 + 1
+ JUMP TODIG ; ループ
+PRT ST GR4,LEN ; LEN <- GR4
+ OUT STR,LEN ; 文字列を出力
+ RPOP
+ RET
+STR DS 20
+LEN DS 1
+ END
--- /dev/null
+;;; PBM画像ファイルを出力
+;;; GR1: 画像ビット列の先頭アドレス
+;;; GR2: 画像の幅
+;;; GR3: 画像の高さ
+OUTPBM START
+ OUT HEADER,HLEN
+ PUSH 0,GR1
+ PUSH 0,GR2
+ PUSH 0,GR3
+ PUSH 0,GR4
+ XOR GR4,GR4
+ LD GR1,GR2
+ LAD GR2,WIDTH
+ CALL L2STR
+ LD GR4,GR0
+ LAD GR4,1,GR4
+ LD GR1,SPC
+ ST GR1,WIDTH,GR4
+ LAD GR4,1,GR4
+ LD GR1,GR3
+ LAD GR2,WIDTH,GR4
+ CALL L2STR
+ ADDL GR4,GR0
+ ST GR4,WHLEN
+ OUT WIDTH,WHLEN
+ POP GR4
+ POP GR3
+ POP GR2
+ POP GR1
+ RET
+HEADER DC 'P1'
+HLEN DC 2
+WIDTH DS 32
+SPC DC ' '
+HEIGHT DS 1
+WHLEN DS 1
--- /dev/null
+;;; PBM16
+;;; GR1で指定されたアドレス以降のメモリを 16×16 の
+;;; 白黒ビットマップ画像データ(白:0 黒:1)とみなし、
+;;; PBM画像ファイルとして出力
+;;; 入力: GR1 画像データの先頭アドレス
+;;; 依存副プログラム: outb_w.casl divl.casl rotate.casl
+PBM16 START
+ PUSH 0,GR1
+ PUSH 0,GR2
+ ST GR1,BEG
+ OUT L1,L1LEN
+ OUT L2,L2LEN
+ XOR GR2,GR2
+LOOP CPL GR2,HEIGHT
+ JZE FIN
+ LD GR1,BEG
+ ADDL GR1,GR2
+ LD GR1,0,GR1
+ CALL OUTB
+ LAD GR2,1,GR2
+ JUMP LOOP
+FIN POP GR2
+ POP GR1
+ RET
+L1 DC 'P1'
+L1LEN DC 2
+L2 DC '16 16'
+L2LEN DC 5
+HEIGHT DC 16
+BEG DS 1
+ END
--- /dev/null
+;;; メモリー上にある指定されたアドレス、長さの文字列を逆順に並べ替える
+;;; 例: 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
--- /dev/null
+;; CASL IIライブラリー
--- /dev/null
+;;; 10進数の整数を表す文字列を数値に変換
+;;; 数値の範囲は、0から65535
+;;; 入力 GR1: 文字列を格納するメモリーの先頭アドレス
+;;; GR2: 文字列の長さ。最大5けた
+;;; 出力 GR3: 数値
+;;; 文字列が最大長より大きい場合と数値以外の場合は、GR3は#FFFF、OFは1
+;;; 数値以外の場合、OFは1
+;;; 依存プログラム: MULL
+STR2L START
+ PUSH 0,GR1
+ PUSH 0,GR2
+ PUSH 0,GR4
+ PUSH 0,GR5
+ PUSH 0,GR6
+ PUSH 0,GR7
+ XOR GR3,GR3 ; GR3の初期化
+ AND GR2,GR2 ; GR2 = 0の場合、OVへジャンプ
+ JZE OV ; ↓
+ CPL GR2,=5 ; GR2 > 5の場合、OVへジャンプ
+ JPL OV ; ↓
+ XOR GR4,GR4 ; GR4: インデックスの初期化
+ LD GR5,GR1 ; GR5 <- GR1
+ LD GR6,GR2 ; GR6 <- GR2
+ XOR GR1,GR1 ; GR1の初期化
+STOL LD GR1,GR5 ; GR1に、入力文字列中の次の桁を格納
+ ADDL GR1,GR4 ; ↓
+ LD GR1,0,GR1 ; ↓
+ LD GR7,ZERO ; GR1 < '0'の場合、FINへジャンプ
+ CPL GR1,GR7 ; ↓
+ JMI FIN ; ↓
+ LD GR7,NINE ; GR1 > '9'の場合、FINへジャンプ
+ CPL GR7,GR1 ; ↓
+ JMI FIN ; ↓
+ SUBL GR1,ZERO ; GR1の文字を、対応する数値に変換
+ ADDL GR3,GR1
+ JOV FIN
+ LAD GR4,1,GR4 ; GR4 <- GR4 + 1
+ CPL GR4,GR6 ; GR4 = GR6の場合、ループ脱出
+ JZE FIN ; ↓
+MUL10 LAD GR2,10 ; GR2:10進数の 10
+ LD GR1,GR3 ; GR1 <- GR3
+ CALL MULL ; MULLを呼び出し、GR3 <- GR1 * GR2
+ JUMP STOL ; ループ終端
+OV LAD GR7,1 ; オーバーフロー発生
+ SRL GR7,1 ; ↓
+FIN POP GR7
+ POP GR6
+ POP GR5
+ POP GR4
+ POP GR2
+ POP GR1
+ RET
+ZERO DC '0'
+NINE DC '9'
+ END