l2strを中心に、casl2libの更新
[YACASL2.git] / as / casl2lib / outpbm.casl
1 ;;; PBM画像ファイルを出力
2 ;;;   GR1: 画像ビット列の先頭アドレス
3 ;;;   GR2: 画像の幅
4 ;;;   GR3: 画像の高さ
5 OUTPBM  START
6         OUT     HEADER,HLEN
7         PUSH    0,GR1
8         PUSH    0,GR2
9         PUSH    0,GR3
10         PUSH    0,GR4
11         XOR     GR4,GR4
12         LD      GR1,GR2
13         LAD     GR2,WIDTH
14         CALL    L2STR
15         LD      GR4,GR0
16         LAD     GR4,1,GR4
17         LD      GR1,SPC
18         ST      GR1,WIDTH,GR4
19         LAD     GR4,1,GR4
20         LD      GR1,GR3
21         LAD     GR2,WIDTH,GR4
22         CALL    L2STR
23         ADDL    GR4,GR0
24         ST      GR4,WHLEN
25         OUT     WIDTH,WHLEN
26         POP     GR4
27         POP     GR3
28         POP     GR2
29         POP     GR1
30         RET
31 HEADER  DC      'P1'
32 HLEN    DC      2
33 WIDTH   DS      32
34 SPC     DC      ' '
35 HEIGHT  DS      1
36 WHLEN   DS      1
37 ;;; 符号なし整数を文字列に変換する。
38 ;;; 符号なし整数を文字列に変換する。
39 ;;; 入力 GR1:符号なし整数 G2:変換した文字列を格納するメモリーの先頭アドレス
40 ;;; 出力 GR0:文字列の長さ (同上)
41 ;;; 依存プログラム: DIVL, REV
42 L2STR   START
43         PUSH    0,GR1
44         PUSH    0,GR4
45         XOR     GR0,GR0         ; GR0 <- 0
46         LD      GR4,GR2         ; GR4 <- GR2
47         PUSH    0,GR2           ; GR2の保存
48         LAD     GR2,10          ; GR2 <- 10。10進数の 10
49 LOOP    LD      GR1,GR1         ; ループ先頭。GR1をテスト
50         JZE     SRT             ; GR1が0の場合、ループ終了
51         CALL    DIVL            ; GR1とGR2の、商をGR0、剰余をGR3に格納
52         ADDL    GR3,='0'        ; GR3を文字に変換
53         ST      GR3,0,GR4       ; GR4のアドレスに、GR3を格納
54         LAD     GR4,1,GR4       ; GR4 <- GR4 + 1
55         LD      GR1,GR0         ; GR0の商をGR1にコピー
56         JUMP    LOOP            ; ループ終端
57 SRT     POP     GR2             ; GR2の復元
58         LD      GR1,GR2         ; GR1に文字列のアドレスを格納
59         SUBL    GR4,GR2         ; GR4 <- GR4 - GR2
60         LD      GR2,GR4         ; GR2 <- GR4
61         CALL    REV             ; 文字列を逆順に並べ替え
62         LD      GR0,GR2         ; GR0 <- GR4 文字列の長さを格納
63         POP     GR4
64         POP     GR1
65         RET
66         END
67 ;;; 0〜65535の範囲にある正数の割算(筆算方式)を行う
68 ;;; 入力 GR1:被除数 GR2:除数
69 ;;; 出力 GR0:商 GR3:剰余
70 ;;; (GR2 = 0)の場合、GR0 GR3とも0になり、オーバーフロー
71 DIVL    START
72         PUSH    0,GR1
73         PUSH    0,GR2
74         PUSH    0,GR4
75         XOR     GR0,GR0         ; GR0:商 初期化
76         XOR     GR3,GR3         ; GR3:剰余 初期化
77         AND     GR2,GR2         ; (GR2 = 0)の場合、DIVZEROへジャンプ
78         JZE     DIVZERO         ; ↓
79         AND     GR1,GR1         ; (GR1 = 0)の場合、FINへジャンプ
80         JZE     FIN             ; ↓
81         ST      GR2,Y           ; YにGR2の初期値を保存
82         LAD     GR4,1           ; GR4:対象ビットのインデックス 初期化
83 SL      CPL     GR2,GR1         ; ループ先頭。(GR2 > GR1)の場合、LOOPへループ脱出
84         JPL     LOOP            ; ↓
85         SLL     GR4,1           ; GR4を1回左シフト
86         ST      GR2,TMP         ; GR2の値をTMPに退避
87         SLL     GR2,1           ; GR2を1回左シフト
88         JOV     YOV             ; オーバーフローの場合は、YOVへジャンプ
89         JUMP    SL              ; ループ終端
90 YOV     LD      GR2,TMP         ; GR2の値をTMPから復元
91         SRL     GR4,1           ; GR4を1回右シフト
92         JUMP    LPIN            ; LPINへジャンプ
93 LOOP    SRL     GR4,1           ; ループ先頭。GR4を1回右シフト
94         JZE     SETMOD          ; (GR4 = 0)の場合、SETMODへループ脱出
95         SRL     GR2,1           ; GR2を1回右シフト
96         CPL     GR1,Y           ; (GR1 < Y)の場合、SETMODへループ脱出
97         JMI     SETMOD          ; ↓
98         CPL     GR1,GR2         ; (GR1 < GR2)の場合、ループ先頭へジャンプ
99         JMI     LOOP            ; ↓
100 LPIN    SUBL    GR1,GR2         ; GR1 <- GR1 - GR2
101         ADDL    GR0,GR4         ; GR0 <- GR0 + GR4
102         JUMP    LOOP            ; ループ終端
103 DIVZERO LAD     GR3,#8000       ; 強制的にオーバーフローを発生させ、GR3 <- 0
104         SLL     GR3,1           ; ↓
105         JUMP    FIN             ; FIN へジャンプ
106 SETMOD  LD      GR3,GR1         ; GR3 <- GR1。剰余の設定
107 FIN     POP     GR4
108         POP     GR2
109         POP     GR1
110         RET
111 Y       DS      1
112 TMP     DS      1
113         END
114 ;;; メモリー上にある指定されたアドレス、長さの文字列を逆順に並べ替える
115 ;;;     例: 12345 -> 54321、54321- -> -12345
116 ;;; 入力 GR1:文字列のアドレス GR2:文字列の長さ
117 ;;; 出力 (同上)
118 REV     START
119         RPUSH
120         LAD     GR3,0           ; GR3の初期化
121 PU      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
122         JZE     NEXT            ; ↓
123         LD      GR4,GR1         ; GR4 <- GR1
124         ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
125         LD      GR5,0,GR4       ; GR5 <- GR4アドレスの値
126         PUSH    0,GR5           ; GR5をプッシュ
127         LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
128         JUMP    PU              ; ループ終端
129 NEXT    LAD     GR3,0           ; GR3の初期化
130 PO      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
131         JZE     FIN             ; ↓
132         POP     GR5             ; GR5にポップ
133         LD      GR4,GR1         ; GR4にGR1の値をコピー
134         ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
135         ST      GR5,0,GR4       ; GR4のアドレス <- GR5の値
136         LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
137         JUMP    PO              ; ループ終端
138 FIN     RPOP
139         RET
140         END