どうしてプログラマに・・・プログラムが書けないのか?に出てくるアレをFORTHで書いてみた。pForthとかで動く。
101 1 DO i . i 3 MOD 0 = IF ." Fizz" THEN i 5 MOD 0 = IF ." Buzz" THEN LOOP
せっかくなのでZ80のアセンブラでも書いてみようと思ったが、公倍数かどうか求めるための割り算や余りを求める命令が無いので、まずはD÷E=DあまりAの処理を書いてみる。翌日続きを書いてマス。
DIV: LD B,8 XOR A LOOP: CP A,E JR C,SKIP SUB A,E SKIP: CCF RL D RL A DJNZ LOOP RET
後で使いやすいように、ちょっと改変。A÷B=AあまりBにする。DEも保存。Z80ニモニック風だと DIV A,B ってな具合か。
DIV: PUSH DE LD D,A LD E,B LD B,8 XOR A LOOP: CP A,E JR C,SKIP SUB A,E SKIP: CCF RL D RL A DJNZ LOOP LD B,A LD A,D POP DE RET
Aの内容をHLが示す場所から10進文字列で格納する処理を書いてみる。8ビットの数値だと、10進数で3桁しかないのでループにはしてない。
DEC: LD B,100 CALL DIV ADD A,'0' LD (HL),A INC HL LD A,B LD B,10 CALL DIV ADD A,'0' LD (HL),A INC HL LD A,B ADD A,'0' LD (HL),A RET
上記の例だと5が005で出ちゃうんで、ゼロサプレス処理を追加する。ついでにHL以外の全レジスタ保存。HLは格納した次のアドレスを差す。Z80ニモニック風だと DEC (HL),A ってな具合か。
DEC: PUSH AX PUSH BC PUSH DE LD B,100 CALL DIV LD C,A CP 0 JR Z,SKIP1 ADD A,'0' LD (HL),A INC HL SKIP1: LD A,B LD B,10 CALL DIV CP 0 JR NZ,SKIP2 LD A,C CP 0 JR Z,SKIP3 SKIP2: ADD A,'0' LD (HL),A INC HL SKIP3: LD A,B ADD A,'0' LD (HL),A INC HL POP DE POP BC POP AF RET
やっとこさ、例のアレを書いてみる。画面出力はCP/MやMSX-DOSを意識して末尾を"$"にした文字列をBUFから始まるアドレスに書き出している。
ARE: LD A,1 LD HL,BUF LOOPA: LD (HL),' ' INC HL CALL DEC PUSH AX LD B,3 CALL DIV POP AX LD A,B CP 0 JR NZ,SKIPA LD (HL),'F' INC HL LD (HL),'i' INC HL LD (HL),'z' INC HL LD (HL),'z' INC HL SKIPA: PUSH AX LD B,5 CALL DIV POP AX LD A,B CP 0 JR NZ,SKIPB LD (HL),'B' INC HL LD (HL),'u' INC HL LD (HL),'z' INC HL LD (HL),'z' INC HL SKIPB: INC A CP 100 JR C,LOOPA LD (HL),'$' RET
定時後、いつもの下道で帰宅。昨日から始めた親のThinkPad T20の再セットアップの続き。途中、晩御飯にオムライスとスープ。ThinkPad T20はHDDからカコン、カコンと音がしたり、内蔵光学ドライブが読み込み不良起こしたり、Windows XPインストール時の再起動で動かなくなるなど調子が悪い。
内蔵光学ドライブの読み込み不良はウルトラベイ2000のある箇所の底面にネジが1本余分に付いていたのが原因。はずしたらウルトラベイ2000の取り付け、取り外しも出来るようになった。なんで、こんなネジが付いて(いつの間に付けた)んだ??
何はともあれ、HDD不良や再起動不調も収まって何とかインストール完了。明日はアプリケーションのインストールをしよう。