Wednesday, April 23, 2014

最近ザイログのZ80のアセンブラに興味がある。

弟はITの勉強を手伝ってくれと言うから、特に関心を持たず弄ってみたけど、流石にそれだけ有名のあるプロセッサーだね。Z80のアセンブラはちょうど現在によく使われているMCU(マイクロコントローラーユニット)と今のコンピューターの間のアセンブラを利用しているので、教育に良いと言われる理由が良く解った。


プロラッミングしてみたら、やはり面白いと思ってしまった。結構基本的なアセンブラなんだけど、とりあえず常識としてしっかり学んでおくようにしたい。その価値があると判断した。そういう訳なんだけど、もしかしたらもう一つのブログでいくつか練習のために書いてみた例のようなプログラムをポストするかもしれない。
ちなみに、知りたい人がいらっしゃると、とても便利な開発ソフトを見つけたよ。ジェノヴァ大学の先生が作って下さったらしい。エディタはエミュレータ丸ごとと一緒になっていて、もの凄く楽。ホームページもソフトも英語だし、実際にアイコンがとても解りやすくて、英語をあまり馴染まなくても大丈夫というぐらいの使い勝手。良かったら試してみたい人はここからダウンロードしてみてね: http://www.esng.dibe.unige.it/deeds/Index.htm

誰も怖がらせたくないけど、一応今日書いたパラレルで入力した6ビットのデータをシリアルで出力するプログラムをここに添付する。勿論最初の例としてかなり難しいけど、既に他のアセンブラをお使いになった方には具体的にZ80のアセンブラがどんな感じかを解ってもらえるには最適と思う。まだ経験のない人には、これぐらいのレベルに着くまで多分1週間から1ヶ月まで掛かれるとかもしれない。では、早速だけど:

;Parallel-Serial 6 bit
;This program gets a parallel INPUT on port 12h
;Bit 0 is the TRIGGER, if it changes from 0 to 1

;data is sent serially on bit 0 of the OUTPUT port 14h.
;Data is composed of 6 bits from bit 1 to 6 of INPUT.
;Bit 7 is supposed to be always in low state.
;Once a sequence is sent, program waits for next one.

       INPUT EQU 12H   ;Input port address
       OUTPUT EQU 14H    ;Output port address

       ORG 0000H       ;Z80 starts here on reset

         JP START        ;skips memory reserved to interrupts
       ORG 0100H       ;our program will start from address 100h

START:   LD SP, 0FFFFH     ;inizializes the stack pointer
         LD B, 00H         ;I will use register B to fast clear register A

WAIT_0:  IN A, (INPUT)     ;get INPUT
         BIT 0, A          ;when bit 0 goes from low to high we are ready
         JP NZ, WAIT_0     ;to send data serially on bit 0 of the OUTPUT port
WAIT_1:  IN A, (INPUT)
         BIT 0, A
         JP Z, WAIT_1
   
         LD C, A           ;saves the INPUT in register C
   
     LD D, 08H         ;register D will count the number of sent bits

NEXT:    RR C         ;rotates C right. Bit 0 will be moved to the Carry flag
   
     LD A, B      ;resets A
   
     RLA          ;RLA gets the Carry flag an pushes it in bit 0 of A register
   
     OUT (OUTPUT), A    ;updates OUTPUT
   
     CALL WAIT_1MS      ;waits 1ms (WAIT_1MS is a function)
   
     DEC D              ;count the sent bit
   
     JP NZ, NEXT        ;if there are still bits to be sent, keeps sending
   
     JP WAIT_0          ;otherwise jumps to start waiting for next sequence.

WAIT_1MS:LD A, 238D   ;we will do 238 cycles to pause 1ms
LOOP:    DEC A        ;that is because the system is supposed to work with a 10MHz clock
   
     NOP          ;and instructions inside the loop use 42 clock cycles.
   
     NOP          ;respectively DEC = 4, NOP = 4, JP = 10
   
     NOP          ;thus for a total of about 10,000 cycles.
   
     NOP
   
     NOP
   
     NOP
   
     NOP
   
     JP NZ, LOOP
   
     RET          ;goes back to main program

最後に忘れて欲しくないこと:今SDCCはZ80のアセンブラも書けるので、アセンブラの使いたくない人はCを使ってこのオープンソースコンパイラを使用してプログラミンング出来るよ。質問があれば、どうぞコメントはいつも大歓迎。それでは、また今度!