146e89a557275cbc00e77b03fff374757327618f
[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 ;;; GR1に格納された符号なし整数を文字列に変換する
38 ;;; GR2に文字列の先頭アドレス、GR3に文字列の長さを返す
39 ;;; 依存プログラム: DIVL, REV
40 L2STR   START
41         PUSH    0,GR1
42         PUSH    0,GR4
43         XOR     GR0,GR0         ; GR0 <- 0
44         LD      GR4,GR2         ; GR4 <- GR2
45         AND     GR1,GR1         ; GR1をテスト
46         JZE     ZERO            ; GR1が0の場合、ZEROにジャンプ
47         PUSH    0,GR2
48 STI     CPL     GR1,GR2         ; ループ先頭。(GR1 < GR2)の場合は、ループ脱出
49         JMI     STLST           ; ↓
50         LAD     GR2,10          ; GR2に10進数の「10」を格納。
51         CALL    DIVL            ; GR1とGR2の、商をGR0、剰余をGR3に格納
52         LD      GR1,GR3         ; GR1にGR3をコピー
53         LD      GR1,NCHAR,GR1   ; GR1を文字に変換
54         ST      GR1,0,GR4       ; (GR4) <- GR1
55         LAD     GR4,1,GR4       ; GR4 <- GR4 + 1
56         LD      GR1,GR0         ; GR0をGR1にコピー
57         JUMP    STI             ; ループ終端
58 STLST   POP     GR2
59         LD      GR1,NCHAR,GR1   ; GR1を文字に変換
60         ST      GR1,0,GR4       ; (GR4) <- GR1
61         LAD     GR4,1,GR4       ; GR4 <- GR4 + 1
62         JUMP    PRT             ; PRTにジャンプ
63 ZERO    LD      GR1,NCHAR       ; 「0」をSTR領域に格納
64         ST      GR1,0,GR4       ; ↓ (GR4) <- GR1
65         LAD     GR4,1,GR4       ; ↓ GR4 <- GR4 + 1
66 PRT     LD      GR1,GR2         ; GR1に文字列のアドレスを格納
67         SUBL    GR4,GR2         ; GR2 <- GR4 - GR2
68         LD      GR2,GR4         ; ↓
69         CALL    REV             ; 文字列を逆順に並べ替え
70         LD      GR3,GR2         ; GR3に文字列の長さを格納
71         LD      GR2,GR4         ; GR2に文字列のアドレスを格納
72         POP     GR4
73         POP     GR1
74         RET
75 LEN     DS      1
76 NCHAR   DC      '0123456789'
77         END
78 ;;; 0〜65535の範囲にある正数の割算(筆算方式)を行う
79 ;;; 入力 GR1:被除数 GR2:除数
80 ;;; 出力 GR0:商 GR3:剰余
81 ;;; (GR2 = 0)の場合、GR0 GR3とも0になり、オーバーフロー
82 DIVL    START
83         PUSH    0,GR1
84         PUSH    0,GR2
85         PUSH    0,GR4
86         XOR     GR0,GR0         ; GR0:商 初期化
87         XOR     GR3,GR3         ; GR3:剰余 初期化
88         AND     GR2,GR2         ; (GR2 = 0)の場合、DIVZEROへジャンプ
89         JZE     DIVZERO         ; ↓
90         AND     GR1,GR1         ; (GR1 = 0)の場合、FINへジャンプ
91         JZE     FIN             ; ↓
92         ST      GR2,Y           ; YにGR2の初期値を保存
93         LAD     GR4,1           ; GR4:対象ビットのインデックス 初期化
94 SL      CPL     GR2,GR1         ; ループ先頭。(GR2 > GR1)の場合、LOOPへループ脱出
95         JPL     LOOP            ; ↓
96         SLL     GR4,1           ; GR4を1回左シフト
97         ST      GR2,TMP         ; GR2の値をTMPに退避
98         SLL     GR2,1           ; GR2を1回左シフト
99         JOV     YOV             ; オーバーフローの場合は、YOVへジャンプ
100         JUMP    SL              ; ループ終端
101 YOV     LD      GR2,TMP         ; GR2の値をTMPから復元
102         SRL     GR4,1           ; GR4を1回右シフト
103         JUMP    LPIN            ; LPINへジャンプ
104 LOOP    SRL     GR4,1           ; ループ先頭。GR4を1回右シフト
105         JZE     SETMOD          ; (GR4 = 0)の場合、SETMODへループ脱出
106         SRL     GR2,1           ; GR2を1回右シフト
107         CPL     GR1,Y           ; (GR1 < Y)の場合、SETMODへループ脱出
108         JMI     SETMOD          ; ↓
109         CPL     GR1,GR2         ; (GR1 < GR2)の場合、ループ先頭へジャンプ
110         JMI     LOOP            ; ↓
111 LPIN    SUBL    GR1,GR2         ; GR1 <- GR1 - GR2
112         ADDL    GR0,GR4         ; GR0 <- GR0 + GR4
113         JUMP    LOOP            ; ループ終端
114 DIVZERO LAD     GR3,#8000       ; 強制的にオーバーフローを発生させ、GR3 <- 0
115         SLL     GR3,1           ; ↓
116         JUMP    FIN             ; FIN へジャンプ
117 SETMOD  LD      GR3,GR1         ; GR3 <- GR1。剰余の設定
118 FIN     POP     GR4
119         POP     GR2
120         POP     GR1
121         RET
122 Y       DS      1
123 TMP     DS      1
124         END
125 ;;; メモリー上にある指定されたアドレス、長さの文字列を逆順に並べ替える
126 ;;;     例: 12345 -> 54321、54321- -> -12345
127 ;;; 入力 GR1:文字列のアドレス GR2:文字列の長さ
128 ;;; 出力 (同上)
129 REV     START
130         RPUSH
131         LAD     GR3,0           ; GR3の初期化
132 PU      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
133         JZE     NEXT            ; ↓
134         LD      GR4,GR1         ; GR4 <- GR1
135         ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
136         LD      GR5,0,GR4       ; GR5 <- GR4アドレスの値
137         PUSH    0,GR5           ; GR5をプッシュ
138         LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
139         JUMP    PU              ; ループ終端
140 NEXT    LAD     GR3,0           ; GR3の初期化
141 PO      CPL     GR3,GR2         ; ループ先頭。(GR3 = GR2)の場合、ループ脱出
142         JZE     FIN             ; ↓
143         POP     GR5             ; GR5にポップ
144         LD      GR4,GR1         ; GR4にGR1の値をコピー
145         ADDL    GR4,GR3         ; GR4 <- GR4 + GR3
146         ST      GR5,0,GR4       ; GR4のアドレス <- GR5の値
147         LAD     GR3,1,GR3       ; GR3 <- GR3 + 1
148         JUMP    PO              ; ループ終端
149 FIN     RPOP
150         RET
151         END