dullyのアイコン画像

スロットゲーム作り~初心者による初心者のためのアセンブリ入門~

dully 2021年02月28日に作成
スロットゲーム作り~初心者による初心者のためのアセンブリ入門~

はじめに

皆さんが普段ものづくりをするとき,何のプログラミング言語を使っていますか?
C言語やPythonあたりがメジャーでしょうか.
これらの言語で作成したプログラムは,マイコン上でどのように実行されるのでしょうか?
ソースコードはコンパイルされて機械語となり,メモリから読み出されて実行されます.
C言語では関数を呼び出せば良いですが,機械語に限りなく近いアセンブリ言語では,レジスタの動きや実行順などコンピュータの仕組みを考慮しつつコードを書く必要があります.
スロットゲーム作りを通じて,コンピュータの気持ちになってアセンブリを書いてみませんか!(なれたか私はわからない…

つくるもの

PICマイコンを使った三桁のスロットゲーム
↓こんなやつ
スロットゲーム
ちなみに表の配置だけ見て作ったら裏はスパゲッティになりました()

必要なもの

必要な道具

  • PC
  • PICKit(書き込み機)
  • はんだごて
  • ニッパー etc.

部品

  • ユニバーサル基板
  • PICマイコン(今回は16F84A)
  • シフトレジスタ(74HC164)
  • 7セグLED x3
  • 適当な抵抗たくさん
  • RC発振用のコンデンサ
  • 適当なnpnトランジスタ(2SC1815) x3
  • タクトスイッチ
  • 電源ボックス
  • 電源スイッチ
  • その他(書き込み用のピンヘッダやチャタリング防止用コンデンサなど)

回路構成

今回はマイコンに16F84Aを用いたので,シフトレジスタを用いて以下のようにダイナミック点灯で3桁表示させます.
マイコンの出力電流が少ないのでトランジスタでスイッチします.
回路構成

ソースコード

以下が実際のアセンブリのソースコードとなります.
7セグの上位桁からPOH,POT,POOとレジスタを用意してループしたときの値を保存しています.

Lチカの例

LIST P=16F84A,R=DEC ; INCLUDE "P16F84A.INC" ; __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC ; ;********************************************* COUNT1 EQU 1CH ; COUNT2 EQU 1DH ; ADRSP EQU 1EH ;LOOPC EQU 1FH PATDAT EQU 20H LPCNT EQU 21H TMP EQU 22H ;ADRSP一時保存用 POO EQU 23H ;P POT EQU 24H POH EQU 25H SCOUNT1 EQU 26H SCOUNT2 EQU 27H TMP2 EQU 28H HOGE EQU 29H ;********************************************* ORG 00H ; GOTO START ; DGET ADDWF PCL,F RETLW B'11111100' ;0 RETLW B'01100000' ;1 RETLW B'11011010' ;2 RETLW B'11110010' ;3 RETLW B'01100110' ;4 RETLW B'10110110' ;5 RETLW B'10111110' ;6 RETLW B'11100100' ;7 RETLW B'11111110' ;8 RETLW B'11110110' ;9 RETLW B'11101110' ;A RETLW B'00111110' ;B RETLW B'00011010' ;C RETLW B'01111010' ;D RETLW B'10011110' ;E RETLW B'10001110' ;F START BSF STATUS,RP0 MOVLW B'00000000' ;0:164CK, 1:164DATA, 2:ONEGND, 3:TENGND, 4:HUNDREDGND, 5:SPEAKER MOVWF TRISB MOVLW B'00001111' ;0;ENTER, 1:ONESW, 2:TENSW, 3:HUNDREDSW MOVWF TRISA BCF STATUS,RP0 CLRF PORTB CLRF POO CLRF POT CLRF POH ; LOOP CALL DISP CALL WAIT CALL WAIT CALL WAIT CALL WAIT BTFSC PORTA,1 GOTO LOOP2 INCF POO INCF POT INCF POH MOVF POO,W MOVWF TMP MOVLW D'10' SUBWF TMP,F BTFSC STATUS,Z CALL INIT GOTO LOOP ; LOOP21 CALL INIT2 LOOP2 CALL DISP BTFSC PORTA,2 GOTO LOOP3 INCF POT INCF POH MOVF POT,W MOVWF TMP MOVLW D'10' SUBWF TMP,F BTFSC STATUS,Z CALL INIT2 GOTO LOOP2 ; LOOP3 CALL DISP BTFSC PORTA,3 GOTO LOOP4 INCF POH MOVF POH,W MOVWF TMP MOVLW 10 SUBWF TMP,F BTFSC STATUS,Z CALL INIT3 GOTO LOOP3 ; LOOP4 MOVLW D'3' MOVWF HOGE LOOP40 CALL SND CALL SND CALL SND CALL SND CALL SND CALL SND CALL WAIT CALL WAIT CALL WAIT CALL WAIT CALL WAIT CALL WAIT DECFSZ HOGE,F GOTO LOOP40 GOTO JUDGE ; JUDGE MOVF POO,W MOVWF TMP MOVF POT,W SUBWF TMP,W BTFSS STATUS,Z GOTO FALSE MOVF POH,W SUBWF TMP,W BTFSS STATUS,Z GOTO FALSE GOTO SUCCESS ; FALSE CALL DISP CALL SND BTFSS PORTA,0 GOTO FALSE GOTO LOOP ; SUCCESS CALL DISP CALL SND BTFSS PORTA,0 GOTO SUCCESS GOTO LOOP ; DISP ;百の位 LOOP10 MOVF POH,W CALL DGET MOVWF PATDAT CALL DATSEND BSF PORTB,4 CALL WAIT_ON BCF PORTB,4 CALL WAIT_OFF ;十の位 LOOP20 MOVF POT,W CALL DGET MOVWF PATDAT CALL DATSEND BSF PORTB,3 CALL WAIT_ON BCF PORTB,3 CALL WAIT_OFF ;一の位 LOOP30 MOVF POO,W CALL DGET MOVWF PATDAT CALL DATSEND BSF PORTB,2 CALL WAIT_ON BCF PORTB,2 CALL WAIT_OFF RETURN ; WAIT00 MOVLW 160 MOVWF COUNT1 WT001 CLRF COUNT2 WT002 DECFSZ COUNT2,F GOTO WT002 DECFSZ COUNT1,F GOTO WT001 RETURN ; WAIT_ON MOVLW 1 MOVWF COUNT1 WT011 CLRF COUNT2 WT012 DECFSZ COUNT2,F GOTO WT012 DECFSZ COUNT1,F GOTO WT011 RETURN ; WAIT_OFF MOVLW 1 MOVWF COUNT1 WT021 CLRF COUNT2 WT022 DECFSZ COUNT1,F GOTO WT021 RETURN ; DATSEND MOVLW 8 MOVWF LPCNT ; DATSE10 RRF PATDAT,F BCF PORTB,1 BTFSC STATUS,C BSF PORTB,1 BSF PORTB,0 BCF PORTB,0 DECFSZ LPCNT,F GOTO DATSE10 RETURN ; INIT CLRF POO CLRF POT CLRF POH RETURN ; INIT2 CLRF POT CLRF POH RETURN ; INIT3 CLRF POH RETURN ; WAIT MOVLW 03H ; MOVWF COUNT1 WT1 MOVLW 17H MOVWF COUNT2 ; WT2 DECFSZ COUNT2,F ; GOTO WT2 ; DECFSZ COUNT1,F ; GOTO WT1 ; RETURN ; SND BSF PORTB,5 CALL WAIT BCF PORTB,5 CALL WAIT RETURN ; END
dully さんが 2021/02/28 に 編集 をしました。 (メッセージ: 初版)
ログインしてコメントを投稿する