• 締切済み

Z80 アセンブラ言語で電卓

Z80を利用してアセンブラ言語で7セグメントLEDに表示できる簡易電卓をlinuxで作成 したいのですが、全くわかりません。どなたかご教授願えますでしょうか?

みんなの回答

  • YUI_AI
  • ベストアンサー率45% (303/661)
回答No.2

Linuxに限定しているのでしょうか? Windowsベースなら下記のものが適当かと思います。 コンパイラ及びアセンブラが付属しているし、7セグも8ケタ分搭載されています。 http://www.alles.or.jp/~thisida/index.htm ※「ND80ZIII」が良いかと。 秋月通商等にもZ80のキットはありますがPIOのポートが少ないので別途8255あたりを2個ほど追加する必要があります。 ※7セグを高速に切り替える等の制御を行うならなら16ビットの出力があれば足りますが。 ↑ 上記の意味が判らない様であれば上記の基板をお勧めします。 質問者様の回路設計・プログラミングのレベルが不明なので無難な選択をしてます。 どうしてもLinux上で開発が行いたいのであれば基板はこのままでフリーのアセンブラ等を利用すればよいかと思います。

aaooiio
質問者

お礼

説明不足でわざわざきとうしてくださったのに申し訳ございません。 No1のnotnotさんのお礼の続きです SUB_XY: PUSH AF PUSH BC PUSH HL LD BC,(YL) LD HL,(XL) AND A SBC HL,BC LD (XL),HL LD A,(XH) CP 28H JP P,OVERFLOW POP AF POP BC POP HL RET MUL_XY: PUSH AF PUSH BC PUSH DE PUSH HL LD DE,(XL) LD BC,(YL) LD HL,000H LD A,00FH SLA C RL B JP C,MUL_2 MUL_1: SLA L RL H JP C,OVERFLOW DEC A JP Z,MUL_3 SLA C RL B JP C,MUL_2 JP MUL_1 MUL_2: ADD HL,DE JP MUL_1 MUL_3: SLA C RL B JP C,MUL_4 LD (XL),HL POP AF POP BC POP DE POP HL RET MUL_4: ADD HL,DE LD (XL),HL POP AF POP BC POP DE POP HL RET DIV_XY: PUSH AF PUSH BC PUSH DE PUSH HL LD A,(YL) CP 000H JP NZ,DIV_0 LD A,(YH) CP 000H JP NZ,DIV_0 JP OVERFLOW DIV_0: LD BC,0000H LD A,10H DIV_1: LD HL,(YL) SRA H RR L RR B RR C LD (YL),HL DEC H INC H JP NZ,DIV_2 DEC L INC L JP NZ,DIV_2 LD HL,(XL) AND A SBC HL,BC JP C,DIV_2 LD (XL),HL SCF RL E RL D DEC A JP Z,DIV_E JP DIV_1 DIV_2: AND A RL E RL D DEC A JP Z,DIV_E JP DIV_1 DIV_E: LD A,(XL) LD (YL),A LD A,(XH) LD (YH),A LD (XL),DE POP AF POP BC POP DE POP HL RET DEC2BIN: PUSH AF PUSH BC PUSH DE PUSH HL LD A,000H LD (ZL),A LD (ZH),A LD A,(LED_1) LD (XL),A LD A,000H LD (XH),A LD BC,03E8H LD (YL),BC CALL MUL_XY CALL ADD_Z LD A,(LED_2) LD (XL),A LD A,000H LD (XH),A LD BC,0064H LD (YL),BC CALL MUL_XY CALL ADD_Z LD A,(LED_3) LD (XL),A LD A,000H LD (XH),A LD BC,000AH LD (YL),BC CALL MUL_XY CALL ADD_Z LD A,(LED_4) LD (XL),A LD A,000H LD (XH),A CALL ADD_Z LD HL,(ZL) LD (XL),HL POP AF POP BC POP DE POP HL RET BIN2DEC: PUSH AF PUSH BC PUSH DE PUSH HL LD BC,03E8H LD (YL),BC CALL DIV_XY LD A,(XH) CP 001H JP P,OVERFLOW LD A,(XL) CP 00AH JP P,OVERFLOW LD (LED_1),A LD A,(YL) LD (XL),A LD A,(YH) LD (XH),A LD BC,0064H LD (YL),BC CALL DIV_XY LD A,(XH) CP 001H JP P,OVERFLOW LD A,(XL) CP 00AH JP P,OVERFLOW LD (LED_2),A LD A,(YL) LD (XL),A LD A,(YH) LD (XH),A LD BC,000AH LD (YL),BC CALL DIV_XY LD A,(XH) CP 001H JP P,OVERFLOW LD A,(XL) CP 00AH JP P,OVERFLOW LD (LED_3),A LD A,(YL) LD (LED_4),A POP AF POP BC POP DE POP HL RET LED_CLR: PUSH AF LD A,000H LD (LED_1),A LD (LED_2),A LD (LED_3),A LD (LED_4),A POP AF RET OVERFLOW: LD A,0FFH LD (LED_1),A LD (LED_2),A LD (LED_3),A LD (LED_4),A CALL KEY_IN CP 00AH JP Z,INIT JP OVERFLOW END という風に書いてみたものの、コンパイルが一応通りますが まったく動かないためにどこを修正すればよいか分からず、 (特にメインルーチン)今回の質問にいたったわけでございます。 なのでわざわざ答えてくださってどうもありがとうございます。

aaooiio
質問者

補足

回答NO.1のnotnotさんのおっしゃるとおりでLINUX上でプログラムを作成したいということです。 自分が説明不足で申し訳ございません。

  • notnot
  • ベストアンサー率47% (4901/10362)
回答No.1

もうすこし具体的に書かないと何をやりたいのかさっぱりです。 出てくるキーワードから予想して書いてみると、 Z80と7segLEDとキーを搭載したワンボードマイコンか何かがあって、そのプログラムをLinuxで開発したい ということであれば、質問は、「Linux上で動くZ80クロスアセンブラの入手先を教えてください」ということでしょうか?

aaooiio
質問者

お礼

RAM EQU 8000H ROM EQU 0000H PIO_AD EQU 01CH PIO_AC EQU 01DH PIO_BD EQU 01EH PIO_BC EQU 01FH ORG RAM LED_1: BLOCK 1 LED_2: BLOCK 1 LED_3: BLOCK 1 LED_4: BLOCK 1 MODE: BLOCK 1 XL: BLOCK 1 XH: BLOCK 1 YL: BLOCK 1 YH: BLOCK 1 ZL: BLOCK 1 ZH: BLOCK 1 BUF_L: BLOCK 1 BUF_H: BLOCK 1 ORG ROM DI INIT: LD SP,RAM+0FFFH CALL PIO_INIT JP MAIN ORG 0066H RETN ORG 0070H MAIN: CALL LED_OUT IN_1ST: CALL NUM_IN CP 00AH JP Z,MAIN CP 00BH JP Z,IN_1ST LD B,A CALL DEC2BIN LD HL,(XL) LD (BUF_L),HL CALL LED_CLR IN_2ND: CALL NUM_IN CP 00AH JP Z,MAIN CP 00CH JP P,IN_2ND CALL DEC2BIN LD DE,(XL) LD (YL),DE LD HL,(BUF_L) LD (XL),HL LD A,B CAL: CP 0CH JP Z,CAL_A CP 0DH JP Z,CAL_S CP 0EH JP Z,CAL_M CALL DIV_XY CALL BIN2DEC JP CAL_E CAL_A: CALL ADD_XY CALL BIN2DEC JP CAL_E CAL_S: CALL SUB_XY CALL BIN2DEC JP CAL_E CAL_M: CALL MUL_XY CALL BIN2DEC JP CAL_E CAL_E: CALL KEY_IN CP 0AH JP Z,INIT JP CAL_E PIO_INIT: PUSH AF LD A,0CFH OUT (PIO_AC),A LD A,000H OUT (PIO_AC),A LD A,007H OUT (PIO_AC),A LD A,0CFH OUT (PIO_BC),A LD A,00FH OUT (PIO_BC),A LD A,007H OUT (PIO_BC),A LD A,000H LD (LED_1),A LD (LED_2),A LD (LED_3),A LD (LED_4),A POP AF RET KEY_IN: PUSH BC LD A,000H OUT (PIO_BD),A LOOP: CALL LED_OUT IN A,(PIO_BD) BIT 4,A JP NZ,LOOP2 IN A,(PIO_BD) BIT 5,A JP NZ,PB11 JP PB01 LOOP2: IN A,(PIO_BD) BIT 5,A JP NZ,PB00 JP PB10 PB00: LD A,000H OUT (PIO_BD),A JP CHECK PB01: LD A,010H OUT (PIO_BD),A JP CHECK PB10: LD A,020H OUT (PIO_BD),A JP CHECK PB11: LD A,030H OUT (PIO_BD),A JP CHECK CHECK: IN A,(PIO_BD) BIT 0,A JP Z,PB0 JP CHECK2 CHECK2: IN A,(PIO_BD) BIT 1,A JP Z,PB1 JP CHECK3 CHECK3: IN A,(PIO_BD) BIT 2,A JP Z,PB2 JP CHECK4 CHECK4: IN A,(PIO_BD) BIT 3,A JP Z,PB3 JP LOOP PB0: IN A,(PIO_BD) BIT 4,A JP NZ,PB0B IN A,(PIO_BD) BIT 5,A JP NZ,KEY14 JP KEY12 PB0B: IN A,(PIO_BD) BIT 5,A JP NZ,KEY15 JP KEY13 PB1: IN A,(PIO_BD) BIT 4,A JP NZ,PB1B IN A,(PIO_BD) BIT 5,A JP NZ,KEY10 JP KEY8 PB1B: IN A,(PIO_BD) BIT 5,A JP NZ,KEY11 JP KEY9 PB2: IN A,(PIO_BD) BIT 4,A JP NZ,PB2B IN A,(PIO_BD) BIT 5,A JP NZ,KEY6 JP KEY4 PB2B: IN A,(PIO_BD) BIT 5,A JP NZ,KEY7 JP KEY5 PB3: IN A,(PIO_BD) BIT 4,A JP NZ,PB3B IN A,(PIO_BD) BIT 5,A JP NZ,KEY2 JP KEY0 PB3B: IN A,(PIO_BD) BIT 5,A JP NZ,KEY3 JP KEY1 KEY0: LD B,000H JP STAY3 KEY1: LD B,001H JP STAY3 KEY2: LD B,002H JP STAY3 KEY3: LD B,003H JP STAY3 KEY4: LD B,004H JP STAY2 KEY5: LD B,005H JP STAY2 KEY6: LD B,006H JP STAY2 KEY7: LD B,007H JP STAY2 KEY8: LD B,008H JP STAY1 KEY9: LD B,009H JP STAY1 KEY10: LD B,00AH JP STAY1 KEY11: LD B,00BH JP STAY1 KEY12: LD B,00CH JP STAY0 KEY13: LD B,00DH JP STAY0 KEY14: LD B,00EH JP STAY0 KEY15: LD B,00FH JP STAY0 STAY0: CALL LED_OUT IN A,(PIO_BD) BIT 0,A JP Z,STAY0 LD A,B POP BC RET STAY1: CALL LED_OUT IN A,(PIO_BD) BIT 1,A JP Z,STAY1 LD A,B POP BC RET STAY2: CALL LED_OUT IN A,(PIO_BD) BIT 2,A JP Z,STAY2 LD A,B POP BC RET STAY3: CALL LED_OUT IN A,(PIO_BD) BIT 3,A JP Z,STAY3 LD A,B POP BC RET NUM_IN: CALL KEY_IN CP 00AH JP P,BREAK CALL L_SHIFT LD (LED_4),A JP NUM_IN BREAK: RET LED_OUT: PUSH AF PUSH HL PUSH BC IN A,(PIO_AD) ADD A,010H AND 030H LD B,A RRCA RRCA RRCA RRCA LD HL,LED_1 ADD A,L LD L,A LD A,(HL) OR B OUT (PIO_AD),A POP BC POP HL POP AF RET L_SHIFT: PUSH AF PUSH BC LD A,(LED_2) LD (LED_1),A LD A,(LED_3) LD (LED_2),A LD A,(LED_4) LD (LED_3),A POP BC POP AF RET ADD_Z: PUSH AF PUSH BC PUSH HL LD A,(XL) LD B,A LD A,(ZL) ADD A,B LD (ZL),A LD A,(XH) LD B,A LD A,(ZH) ADC A,B LD (ZH),A POP AF POP BC POP HL RET ADD_XY: PUSH AF PUSH BC PUSH HL LD A,(XL) LD B,A LD A,(YL) ADD A,B LD (XL),A LD A,(XH) LD B,A LD A,(YH) ADC A,B LD (XH),A CP 28H JP P,OVERFLOW POP AF POP BC POP HL RET 全部は乗せられませんでしたが、 以上の形まで作成しましたが、メインルーチンが特にわかりません。 今回どのように修正すればよいか分からず、焦って説明不足のまま 質問をのせてしまいました。申し訳ございません。 ですので、さらに補足を載せていまいましたが、 お礼させてください。ありがとうございました。

aaooiio
質問者

補足

自分が説明不足で申し訳ございません。 notnotさんのおっしゃるとおりでLINUX上でプログラムを作成したいということです。 4個のLEDに数値を順次表示させるプログラム PIO_AD EQU 01CH PIO_ADと01CHは等しいとする PIO_AC EQU 01DH PIO_ACと01DHは等しいとする ORG 0000H 以下のプログラムを0000H番地以降に格納する LD A,0CFH 数値0CFHをAレジスタへ呼び出す OUT (PIO_AC),A Aレジスタの値をPIO_ACに出力する LD A,000H 数値000HをAレジスタへ呼び出す OUT (PIO_AC),A Aレジスタの値をPIO_ACに出力する LD A,007H 数値007HをAレジスタへ呼び出す OUT (PIO_AC),A Aレジスタの値をPIO_ACに出力する LOOP: LD A,003H 数値003HをAレジスタへ呼び出す OUT (PIO_AD),A Aレジスタの値をPIO_ADに出力する LD HL,8000H     8000HをHLレジスタへ呼び出す LD DE,8000H     8000HをHLレジスタへ呼び出す LD BC,0200H     0200HをHLレジスタへ呼び出す LDIR レジスタHL、DB、BCの内容は破壊される LD A,014H 数値014HをAレジスタへ呼び出す OUT (PIO_AD),A Aレジスタの値をPIO_ADに出力する LD HL,8000H     8000HをHLレジスタへ呼び出す LD DE,8000H     8000HをDEレジスタへ呼び出す LD BC,0200H     0200HをBCレジスタへ呼び出す LDIR レジスタHL、DB、BCの内容は破壊される LD A,025H 数値025HをAレジスタへ呼び出す OUT (PIO_AD),A Aレジスタの値をPIO_ADに出力する LD HL,8000H     8000HをHLレジスタへ呼び出す LD DE,8000H     8000HをDEレジスタへ呼び出す LD BC,0200H     0200HをBCレジスタへ呼び出す LDIR レジスタHL、DB、BCの内容は破壊される LD A,036H 数値036HをAレジスタへ呼び出す OUT (PIO_AD),A Aレジスタの値をPIO_ADに出力する LD HL,8000H     8000HをHLレジスタへ呼び出す LD DE,8000H     8000HをDEレジスタへ呼び出す LD BC,0200H 0200HをBCレジスタへ呼び出す LDIR レジスタHL、DB、BCの内容は破壊される JP LOOP LOOPに戻る HALT プログラム停止 END  キー入力プログラムの作成 16 個のキーの状態を知るには、4 回の試行が必要なことがわかる。 ・(PB5 , PB4) = (0,0)と設定して、PB0~PB3 をチェック。 ・(PB5 , PB4) = (0,1)と設定して、PB0~PB3 をチェック。 ・(PB5 , PB4) = (1,0)と設定して、PB0~PB3 をチェック。 ・(PB5 , PB4) = (1,1)と設定して、PB0~PB3 をチェック。 PB0~PB5 の情報により、どのキーが押されたのか判別できる 1.まず最初にPIOポートの初期化を行う 8行目~13行目: PIO Bポートの初期化を行なっている。 15行目~20行目: PIO Aポートの初期化を行なっている。 2.次に(PB5,PB4)のセットを行う 22行目:数値000Hが格納されたAレジスタに数値010Hを足す。これにより、(PB5,PB4)を(0,0)から(0,1)にセットされる。 23行目~24行目: Aレジスタに格納された数値010Hと030Hを論理積にかける。結果は010Hとなるので、この値をAレジスタに格納し、PIO_BDに出力する。 25行目~28行目: SRLはレジスタの値を1/2倍する命令であるが、この処理によってメモリの内容を1bit右へシフトすることができる。ここではその処理を4回行なっているため、Aレジスタに格納されていた010Hは001Hとなる。 29行目~30行目:Aレジスタに格納された数値001Hと003Hを論理積にかける。結果は001Hとなるので、この値をAレジスタに格納し、またLD命令によりBレジスタに呼び出す。この値が(PB5,PB4)の設定値となる。 3.セットを行なった後、PB3~PB0の読み込みを行う 31行目: PIO_BDの入力ポートの内容を取り出し、Aレジスタに格納する。  32行目~40行目:一番右側のビット(PB0)から順に0であるか1であるかをチェックしていく。0であるビットが見つかり次第、SET1~4のうち指定された場所へジャンプする。PB0~PB3まで全て1だった場合はLOOP(18行目)まで戻って再度(PB5,PB4)をセットし直す。 4.PB0~PB5の情報をキーNo.に変換する  42行目~43行目:ここは1順目でSET1にジャンプした場合の処理である。26行目において格納したBレジスタの値(001H)を取り出してAレジスタに格納し、数値00CHと足し合わせ、演算結果00DHをAレジスタに格納する。  44行目~45行目:この値がPIO_ADに出力され、プログラム終了となる。SET2, SET3, SET4へジャンプした場合も同様に処理をする。 1: PIO_BD EQU 01EH 2: PIO_BC EQU 01FH 3: PIO_AD EQU 01CH 4: PIO_AC EQU 01DH 5: 6: ORG 0000H 7: 8: LD A,0CFH 9: OUT (PIO_BC),A 10: LD A,00FH 11: OUT (PIO_BC),A 12: LD A,007H 13: OUT (PIO_BC),A 14: 15: LD A,0CFH 16: OUT (PIO_AC),A 17: LD A,000H 18: OUT (PIO_AC),A 19: LD A,007H 20: OUT (PIO_AC),A 21: 22: LOOP: ADD A,010H 23: AND 030H 24: OUT (PIO_BD),A 25: SRL A 26: SRL A 27: SRL A 28: SRL A 29: AND 003H 30: LD B,A 31: IN A,(PIO_BD) 32: BIT 0,A 33: JP Z,SET1 34: BIT 1,A 35: JP Z,SET2 36: BIT 2,A 37: JP Z,SET3 38: BIT 3,A 39: JP Z,SET4 40: JP LOOP 41: 42: SET1: LD A,B 43: ADD A,00CH 44: OUT (PIO_AD),A 45: HALT 46: SET2: LD A,B 47: ADD A,008H 48: OUT (PIO_AD),A 49: HALT 50: SET3: LD A,B 51: ADD A,004H 52: OUT (PIO_AD),A 53: HALT 54: SET4: LD A,B 55: ADD A,000H 56: OUT (PIO_AD),A 57:     HALT といったところまではわかっているのですが、あとをどう作成してよいかわからなくて・・。 ということで質問させていただいたということです。

関連するQ&A