;;; 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 ;;; 符号なし整数を文字列に変換する。 ;;; 符号なし整数を文字列に変換する。 ;;; 入力 GR1:符号なし整数 G2:変換した文字列を格納するメモリーの先頭アドレス ;;; 出力 GR0:文字列の長さ (同上) ;;; 依存プログラム: DIVL, REV L2STR START PUSH 0,GR1 PUSH 0,GR4 XOR GR0,GR0 ; GR0 <- 0 LD GR4,GR2 ; GR4 <- GR2 PUSH 0,GR2 ; GR2の保存 LAD GR2,10 ; GR2 <- 10。10進数の 10 LOOP LD GR1,GR1 ; ループ先頭。GR1をテスト JZE SRT ; GR1が0の場合、ループ終了 CALL DIVL ; GR1とGR2の、商をGR0、剰余をGR3に格納 ADDL GR3,='0' ; GR3を文字に変換 ST GR3,0,GR4 ; GR4のアドレスに、GR3を格納 LAD GR4,1,GR4 ; GR4 <- GR4 + 1 LD GR1,GR0 ; GR0の商をGR1にコピー JUMP LOOP ; ループ終端 SRT POP GR2 ; GR2の復元 LD GR1,GR2 ; GR1に文字列のアドレスを格納 SUBL GR4,GR2 ; GR4 <- GR4 - GR2 LD GR2,GR4 ; GR2 <- GR4 CALL REV ; 文字列を逆順に並べ替え LD GR0,GR2 ; GR0 <- GR4 文字列の長さを格納 POP GR4 POP GR1 RET 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