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