役にたたない技術情報。
タコプログラマが経験したあがきの記録でもあります。
たまにはBASICも悪くない。
と言っても、正確にはべ−しっ君
の話なんだが。
べ−しっ君
には、MSX2対応の初代
、MSX2+対応のぷらす
、MSXturboR対応のたーぼ
といったバージョンがあって、人によってはこれを判別したくなるらしい。たぶん、MSXturboR専用ソフトをべーしっ君
で動かすのに、バージョンが初代
だったりすると困るからだろう。正確なところは知らないが。
で、本体とべーしっ君
、両方のバージョンチェックをやれば、あまり困らずにすむ。問題はバージョンチェックの方法で、マシン語が分かる人間だと全てのスロットに対して文字列"BASIC'n ver"を検索して云々となるのだろうが、べーしっ君
を使うのにマシン語を必要とするのはもう一つしっくりこない。
で、なんとかBASIC(+べーしっ君
)のみで検索してみたのが次のプログラム。
10 CALL TURBO ON 20 DEFINT A-Z 30 N$="BASIC'n ver " 40 N=ASC(MID$(N$,1,1)) 50 HL=&H4000:DE=0:I=2:V=0 60 FOR HL=&H4000 TO HL+&H400 70 IF PEEK(HL)<>N GOTO 120 80 FOR I=2 TO LEN(N$)-1 90 IF PEEK(HL+I-1)<>ASC(MID$(N$,I,1)) THEN I=LEN(N$)+1 100 NEXT I 110 IF I=LEN(N$) THEN DE=HL+I:HL=&H5000 120 NEXT HL 130 IF DE>0 THEN V=VAL(CHR$(PEEK(DE))) 140 IF V<>1 AND V<>2 THEN V=1 150 IF V=2 THEN V=V+VAL(CHR$(PEEK(DE+2))) 160 PRINT "BASIC'n version=";V 170 CALL TURBO OFF 180 END
やっている事は、べーしっ君
を起動し、4000H〜4400Hに文字列"BASIC'n ver "が存在すれば"ver "の後の数値からバージョンを決定するというものである。もちろん、10行のCALL TURBO ONでエラーが出ればべ−しっ君
は存在しないので、バージョンチェックその物が無意味である。
ここでポイントとなるのは、初代
, ぷらす
, たーぼ
のバージョンがそれぞれ"1.0"、"2.0"、"2.1"である事で、130〜150行では"1.0" → 1、"2.0" → 2、"2.1" → 3といった変換を行っている。ただし、初代
には"BASIC'n ver "文字列が存在しない物があるので、140行でこれを1とする処理をしている。
なお、べーしっ君
使用中はPage1(4000H〜7FFFH)がMAIN ROMではなく、べーしっ君
に切り変わっている。だからこそ、自前でスロット切り替えして....といった作業が省け、BASICのみで間に合うわけだ。
この、べーしっ君
が自分を表に出し放しで動く事を利用して、オールBASICでROM(RAMかも知らんけど)の吸い出しが可能になる。例えば、こんな感じ。
10 CALL TURBO ON 20 SCREEN 5 30 FOR I=&H4000 TO &H7FFF 40 VPOKE I,PEEK(I) 50 NEXT I 60 CALL TURBO OFF 70 BSAVE "BASICN.ROM",&H4000,&H7FFF,S
名古屋の収穫の一つだなんて、口が避けても言えません。
ExpFさんのツッコミ。
をここに書くのは止めときます。わずか2行に収められた逸品を、御題の前に読まれると勿体無いから。とゆ〜わけで、2/3のは既に読んだという方のみ、追記を読んで下さいな。
(NOB)さんに先を越されたネタ。
13:05頃、思いついたのにぃぃぃ。
RES 7,A RES 6,A RES 5,A RES 4,A RES 3,A RES 2,A
bit操作命令なんてあまり使わないから、さっきまで忘れてた。
オチとして十分なネタだったのになぁ。
例によって例の如く。
Z80 Quizをまた一つ。
本日の御題は、
A reg.の、上位6bitのみをクリアする。
ただし、AND命令は使わない。
にございます。とりあえず、先を読まずにお考えを。
いくつ思い付くかで、あなたのZ80への愛情が分かりません。
以下、回答例。
LD L,LOW TABLE ADD A,L LD L,A LD A,HIGH TABLE ADC A,0 LD H,A LD A,(HL)
テーブルを使って、一切計算しない方法。
他の方法を使わなければテーブルを作れない辺り、ほとんど反則である。
LD BC,804H LD H,0 LD L,A LOOP: ADD HL,HL LD A,H SUB C JR C,NEXT LD H,A NEXT: DJNZ LOOP LD A,H
いきなり、汎用割り算ルーチンを使うとゆ〜、無駄の多い方法。
高級言語に染まった人間の末路である。
もちろん、私も染まっている。
LD BC,680H LOOP: CP C JR C,NEXT SUB C NEXT: SRL C DJNZ LOOP
1bitずつ見ていって、1なら引き算でクリアする方法。
アタマワルイ。
RRCA RRCA LD L,A LD H,0 ADD HL,HL ADD HL,HL LD A,H
これはあれだ。
RRCA RR L RRCA RR L XOR A RL L RLA RL L RLA
をちょっとひねった奴。
下位2bitを他に移した隙にA reg.をクリアして、移した分だけを戻す方法。
LD L,A RRCA RRCA ADD A,A ADD A,A XOR L
かなりマスクの考え方に近い方法。
下位2bitには何もしない辺りが特に。
4番目の奴の裏返しとゆ〜見方も可。
ADD A,A ADD A,A ADD A,A ADD A,A ADD A,A ADD A,A RLCA RLCA
8bit分の左シフトを、bitのクリア・保存を選びながらやればいいわけだ。
ANDのマスク値に、命令の並びが対応している辺りは、かなり美しい。美しいんだったら。
CPL OR 11111100B CPL
下位2bitは、2回反転で元に戻るだけ。
上位6bitは1で埋められた挙句に、反転食らって0クリア。
ちなみに、ド・モルガンの法則から導くのは、なんか悔しいので反則。反則なんだったら。
例によって例の如く、何の役にも立ちません。
素直にANDするよろし。
それでも他の方法を知りたくて仕方がない、今日この頃でございます。
2行でまとめてます。
OR 11111100B SUB 11111100B
もう一つ。
OR 11111100B ADD A,00000100B
'ANDにOR'にかなり近い感じです。
さすがはExpFさん。気休めでない高速化講座
の分を、しっかりツッコミ返してくれました。