;;; 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 ;;; 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 ;;; 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 ;;; メモリー上にある指定されたアドレス、長さの文字列を逆順に並べ替える ;;; 例: 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