-*.casl
+/*.casl
doc/call.svg
sample/*.pbm
--- /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に数値、GR0に文字列の長さ
+ JOV OV
+ AND GR0,GR0
+ JZE FIN
+ CPL GR0,=#FFFF
+ JZE NAN
+ CALL OUTL
+ JUMP LOOP
+OV CPL GR0,=#FFFF
+ JZE LENOV
+ OUT OVMSG,MLEN1
+ JUMP LOOP
+NAN OUT NANMSG,MLEN2
+ JUMP LOOP
+LENOV OUT LENOVMSG,MLEN3
+FIN RET
+OVMSG DC 'Over 65535'
+MLEN1 DC 10
+NANMSG DC 'Not A Number'
+MLEN2 DC 12
+LENOVMSG DC 'Str too long. Stop'
+MLEN3 DC 18
+ 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 ; GR0 <- GR1 * GR2
+ JOV WOV ; オーバーフローの場合は、WOVへジャンプ
+ PUSH 0,GR1 ; GR0の数値を出力
+ LD GR1,GR0 ; ↓
+ CALL OUTL ; ↓
+ POP GR1 ; ↓
+YNEXT OUT SEP,SLEN ; 区切り線を出力
+ LAD GR5,1,GR5 ; GR5 <- GR5 + 1
+ JUMP LOOPY ; LOOPYへジャンプ
+WOV OUT YOMSG,YLEN ; オーバーフローした場合のメッセージを表示
+ PUSH 0,GR1 ; GR0の数値を出力
+ LD GR1,GR0 ; ↓
+ CALL OUTL ; ↓
+ POP GR1 ; ↓
+ PUSH 0,GR1 ; GR3の数値を出力
+ LD GR1,GR3 ; ↓
+ CALL OUTL ; ↓
+ POP GR3 ; ↓
+ JUMP YNEXT ; YNEXTへジャンプ
+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 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 #0001,#8000
+CNT DC 2
+ 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
+;;; 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: 入力された数値
+;;; GR0: 文字列の長さ。入力が数字以外の場合は、#FFFF
+;;; 65536以上の正数が入力された場合はエラー
+INL START
+ IN IBUF,ILEN ; 入力文字列を格納
+ LAD GR1,IBUF
+ LD GR2,ILEN
+ CPA GR2,LENMAX
+ JPL LENOV
+ CALL STR2L
+ JOV FIN
+ LD GR0,GR2
+ JUMP FIN
+LENOV LAD GR0,#FFFF
+ SRA GR0,1
+FIN RET
+ILEN DS 1
+LENMAX DC 5
+IBUF DS 5
+ END
--- /dev/null
+;;; 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
--- /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:乗数
+;;; 出力 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
--- /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けた
+;;; 出力 GR0: 数値
+;;; 文字列が最大長より大きい場合や数値以外の場合は、GR0は#FFFF、OFは1
+;;; 依存プログラム: MULL
+STR2L START
+ PUSH 0,GR4
+ PUSH 0,GR5
+ XOR GR0,GR0 ; GR0:初期化
+ AND GR2,GR2 ; (GR2 = 0)の場合、FINへジャンプ
+ 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 ; ↓ オーバーフロー発生
+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