スロット用モードチェッカー

 友人に頼まれて作ったのですが、一昔前の4号機と呼ばれる「北斗の拳」の物です。
実際ホールなどで使用すると違法らしいのですが、今となっては家庭で持っている好きな方なら使えるんじゃないか
と思い経過はかなりはしょって公開します。
元々スロットに関して知識がなかったので友人に台を提供していただき、まずは構造などデータ取りをしてみました。

いろいろ調べてみると左図のような構造であることはだいたい
わかってきましたので赤丸の部分に注目しメイン基板からサブ
基板に出力される信号は8bitである事も判明したので、それを
ロジアナで計り信号変化をエクセル上で表にしてみました。

結果はこちら

表にしてみると単純な物で、スタート時に役は決定されてサブ
基板に送られ、続いて停止ボタンに応じたドラムの停止信号と
全てストップ後に現在のモードなどが送信される仕組みです。

サブ基板では信号ヘッダに従い音声などの処理をして表示など
を抽選決定している様子です。

ここで設計するにあたり追加機能で画面表示にバグが出た時に
リセットできるサブ基板初期化機能(これは単純にRAMクリアと
呼ばれる台を設定状態にした時の信号を出力)と画面表示変更
機能(これは断線チェックの為にコイン投入→スタート→ドラム
停止→モード決定の信号を出力し2台以上の本機を並列接続す
れば断線や機能チェックできるように)を付けました。
まぁオマケですけどねw

さぁいよいよ設計開始です。

入力が8bitにコントロール端子が1本と表示には7セグLEDを使うのでBCDデコードICを使っても出力4本にスイッチ
入力に2本などで合計入出力端子に15本は確保したいのでPIC16F627Aを使うことにしました。

回路図はこちらに↓
回路図

パターン図はこちらに↓
パターン図

さて次はソースコードですが・・・作ったのはかなり昔で今となっては何を考えて書いたのか全く覚えていないので、
そのまま載せようと思います。(あの頃の自分はどこへやら?w)
;****************************************************
;	Filename:		mode.asm					*
;	Programname:	モードチェッカー						*
;	Version:		Ver1.0.0						*
;	Assembler:		MPLAB Ver7.50.00			*
;****************************************************
	INCLUDE"p16F627a.inc"
	list p=16F627A
	__CONFIG _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF

;******************************プログラム初期設定***************************
;ファイルレジスタの定義
COUNT	EQU		0x20			;ウェイトカウント用
COUNT1	EQU		0x21			;ウェイトカウント用
E_ADRS	EQU		0x22			;

;RAポート割り当て
CHANG	SET		4				;チェンジモード
CLERE	SET		5				;クリアモード
CTRL	SET		6				;コントロールビット

;--------EEPROM---------
		ORG	H'2100'
		DE	H'7F',H'F6',0
		DE	H'7E',H'F7',H'71',H'EF',H'6B',H'F0',H'6A',H'B1',0
		DE	0
		DE	0
		ORG	H'2130'
		DE	H'70',H'FC',0
		DE	H'7A',H'FC',H'72',H'FD',H'73',H'F6',H'7A',H'FF',0
		DE	H'79',H'FE',H'78',H'FA',H'79',H'FD',H'77',H'F7',H'79',H'FC',H'76',H'F0',0
		DE	H'74',H'FE',H'71',H'E7',H'6B',H'F0',H'6A',H'B1',0
;
		ORG	0				;リセットベクタ
;
START
;ポートの初期設定
		MOVLW	B'00000111'		;コンパレータ不使用
		MOVWF	CMCON			;コンパレータI/O設定
		CALL	PORT_IN			;ポート入力モード

INIT	MOVLW	H'0F'			;7SEG初期値
		MOVWF	PORTA			;7SEG出力

;******************************プログラム本文***************************
;入力の読み取り
L_CHANG	BTFSC	PORTA,CHANG		;RA = (L)?
		GOTO	L_CLERE			;L_CLEREへ
		CALL	WAIT100			;ノイズカットウェイト
		BTFSC	PORTA,CHANG		;RA = (L)?
		GOTO	L_CLERE			;L_CLEREへ
		CALL	PORT_OT			;ポート出力モード
		GOTO	TASK_2			;チェンジモードへ
L_CLERE	BTFSC	PORTA,CLERE		;RA = (L)?
		GOTO	L_CTRL			;L_CTRLへ
		CALL	WAIT100			;ノイズカットウェイト
		BTFSC	PORTA,CLERE		;RA = (L)?
		GOTO	L_CTRL			;L_CTRLへ
		CALL	PORT_OT			;ポート出力モード
		GOTO	TASK_1			;クリアモードへ
L_CTRL	BTFSC	PORTA,CTRL		;CTRL = (L)?
		GOTO	L_CHANG			;L_CHANGへ
		MOVF	PORTB,W			;RB<7:0>データ読み込み
		SUBLW	H'71'			;データ照合
		BTFSS	STATUS,Z		;RB = (&H71)?
		GOTO	H_CTRL			;H_CTRLへ
		GOTO	TASK1			;TASK1へ
H_CTRL	BTFSS	PORTA,CTRL		;CTRL = (H)?
		GOTO	H_CTRL			;H_CTRLへ
		GOTO	L_CHANG			;L_CHANGへ

;メインタスク
TASK1	BTFSS	PORTA,CTRL		;CTRL = (H)?
		GOTO	TASK1			;TASK1へ
TASK2	BTFSC	PORTA,CTRL		;CTRL = (L)?
		GOTO	TASK2			;TASK2へ
		MOVF	PORTB,W			;RB<7:0>データ読み込み
		SUBLW	H'FF'			;W - &HFF
		CALL	TABLE			;データテーブル読み込み
		MOVWF	PORTA			;7SEG出力
		GOTO	H_CTRL			;H_CTRLへ

;クリアモード
TASK_1	MOVLW	H'00'			;EEPROMアドレスセット
		MOVWF	E_ADRS			;データエリアのアドレス指定
		CALL	DATAOUT			;データ出力へ
H_CLERE	BTFSS	PORTA,CLERE		;RA → (H)?
		GOTO	H_CLERE			;H_CLEREへ
		CALL	PORT_IN			;ポート入力モード
		GOTO	L_CHANG			;L_CHANGへ

;チェンジモード
TASK_2	CALL	WAIT40
		MOVLW	H'30'			;EEPROMアドレスセット
		MOVWF	E_ADRS			;データエリアのアドレス指定
		CALL	DATAOUT			;データ出力へ
H_CHANG	BTFSS	PORTA,CHANG		;RA → (H)?
		GOTO	TASK_2			;
		CALL	PORT_IN			;ポート入力モード
		GOTO	L_CHANG			;L_CHANGへ

;ポートイニシャライズ
PORT_IN	BSF     STATUS,RP0      ;バンク1に切り替え
        MOVLW   B'11110000'		;RA<0-3>出力
        MOVWF   TRISA           ;ポートA方向(入出力)設定
		MOVLW	B'11111111'		;RB<0:7>入力
        MOVWF   TRISB           ;ポートB方向(入出力)設定
        MOVLW   B'10000000'		;オプションレジスタの設定
        MOVWF   OPTION_REG		;タイマ不使用
        BCF     STATUS,RP0      ;バンク0に切り替え
		RETURN

PORT_OT	BSF     STATUS,RP0      ;バンク1に切り替え
        MOVLW   B'10110000'		;RA<0-3><6>出力
        MOVWF   TRISA           ;ポートA方向(入出力)設定
		MOVLW	B'00000000'		;RB<0:7>出力
        MOVWF   TRISB           ;ポートB方向(入出力)設定
        MOVLW   B'10000000'		;オプションレジスタの設定
        MOVWF   OPTION_REG		;タイマ不使用
        BCF     STATUS,RP0      ;バンク0に切り替え
		CALL	INI_D			;
		CALL	INI_T			;
		RETURN

;データポートイニシャライズ
INI_D	MOVLW	H'FF'
		MOVWF	PORTB			;(H)→RB<7:0>
		RETURN

;コントロールビットイニシャライズ
INI_T	BSF		PORTA,CTRL		;(H)→RA
		RETURN

;ウェイトシーケンス
WAIT	CALL	WAIT_07			;ウェイト70us
		CALL	INI_T			;
		CALL	WAIT1_0			;ウェイト1ms
		CALL	WAIT1_0			;ウェイト1ms
		CALL	INI_D			;
		RETURN

;データ出力シーケンス
DATAOUT	CALL	D_LIST			;
		CALL	WAIT
		CALL	WAIT
		CALL	WAIT
		CALL	WAIT
		INCF	E_ADRS,F		;
		CALL	D_LIST			;
		CALL	WAIT
		CALL	WAIT
		CALL	WAIT
		CALL	WAIT
		INCF	E_ADRS,F		;
		CALL	D_LIST			;
		CALL	WAIT
		CALL	WAIT
		CALL	WAIT
		CALL	WAIT
		INCF	E_ADRS,F		;
		CALL	D_LIST			;
		RETURN

;データリスト出力
D_LIST	CALL	EE_READ			;
		BTFSC	STATUS,Z		;EEDATA = (00H)?
		RETURN					;
		MOVWF	PORTB			;W → PORTB
		CALL	WAIT_01			;ウェイト10us
		BCF		PORTA,CTRL		;CTRLクリア
		CALL	WAIT			;
		INCF	E_ADRS,F		;データアドレスのインクリメント
		GOTO	D_LIST			;

;EEPROM読み出し
EE_READ	MOVF	E_ADRS,W		;アドレスをWレジスタに
		BSF		STATUS,RP0		;PAGE1へ切替え 
		MOVWF	EEADR			;アドレスをEEADRへセット 
		BSF		EECON1,RD		;読み出し
		MOVF	EEDATA,W		;Wレジスタにデータ取り出し 
		BCF		STATUS,RP0		;PAGE0に戻る 
		RETURN

;100msノイズカットウェイトサブルーチン
WAIT100	MOVLW	D'50'
		MOVWF	COUNT1			;1.0ms×100=100ms
LOOP100	CALL	WAIT1_0
		DECFSZ	COUNT1, F
		GOTO	LOOP100
		RETURN

;40msウェイトサブルーチン
WAIT40	MOVLW	D'40'
		MOVWF	COUNT1			;1.0ms×40=40ms
LOOP40	CALL	WAIT1_0
		DECFSZ	COUNT1, F
		GOTO	LOOP40
		RETURN

;1msウェイトサブルーチン
WAIT1_0	MOVLW	D'249'
		MOVWF	COUNT			;1.0ms基準
LOOP1_0	NOP
		DECFSZ	COUNT, F
		GOTO	LOOP1_0
		RETURN

;70uSウェイトサブルーチン
WAIT_07	MOVLW  	D'5'
		MOVWF  	COUNT1			;
LOOP_07	CALL  	WAIT_01
		DECFSZ	COUNT1, F
		GOTO	LOOP_07
		RETURN

;10uSウェイトサブルーチン
WAIT_01	MOVLW  	D'1'
		MOVWF  	COUNT			;
LOOP_01	NOP
		NOP
		DECFSZ 	COUNT, F
		GOTO	LOOP_01
		RETURN

;データテーブル
TABLE	ADDWF	PCL,1
		RETLW	H'00'			;FF=[0]ストック無
		RETLW	H'00'			;FE=[0]ストック無
		RETLW	H'0F'			;FD=[F]
		RETLW	H'0F'			;FC=[F]
		RETLW	H'0F'			;FB=[F]
		RETLW	H'0F'			;FA=[F]
		RETLW	H'0F'			;F9=[F]
		RETLW	H'0F'			;F8=[F]
		RETLW	H'01'			;F7=[1]低確率
		RETLW	H'01'			;F6=[1]低確率
		RETLW	H'0F'			;F5=[F]
		RETLW	H'0F'			;F4=[F]
		RETLW	H'0F'			;F3=[F]
		RETLW	H'0F'			;F2=[F]
		RETLW	H'0F'			;F1=[F]
		RETLW	H'0F'			;F0=[F]
		RETLW	H'02'			;EF=[2]通常
		RETLW	H'02'			;EE=[2]通常
		RETLW	H'0F'			;ED=[F]
		RETLW	H'0F'			;EC=[F]
		RETLW	H'0F'			;CB=[F]
		RETLW	H'0F'			;EA=[F]
		RETLW	H'0F'			;E9=[F]
		RETLW	H'0F'			;E8=[F]
		RETLW	H'03'			;E7=[3]高確率
		RETLW	H'03'			;E6=[3]高確率
		RETLW	H'0F'			;E5=[F]
		RETLW	H'0F'			;E4=[F]
		RETLW	H'0F'			;E3=[F]
		RETLW	H'0F'			;E2=[F]
		RETLW	H'0F'			;E1=[F]
		RETLW	H'0F'			;E0=[F]
		RETLW	H'04'			;DF=[4]前兆
		RETLW	H'04'			;DE=[4]前兆
		RETLW	H'0F'			;DD=[F]
		RETLW	H'0F'			;DC=[F]
		RETLW	H'0F'			;DB=[F]
		RETLW	H'0F'			;DA=[F]
		RETLW	H'0F'			;D9=[F]
		RETLW	H'0F'			;D8=[F]
		RETLW	H'05'			;D7=[5]ボーナス(7)
		RETLW	H'05'			;D6=[5]ボーナス(7)
		RETLW	H'0F'			;D5=[F]
		RETLW	H'0F'			;D4=[F]
		RETLW	H'0F'			;D3=[F]
		RETLW	H'0F'			;D2=[F]
		RETLW	H'0F'			;D1=[F]
		RETLW	H'0F'			;D0=[F]
		RETLW	H'06'			;CF=[6]ボーナス(北斗)
		RETLW	H'06'			;CE=[6]ボーナス(北斗)
		RETLW	H'0F'			;CD=[F]
		RETLW	H'0F'			;CC=[F]
		RETLW	H'0F'			;CB=[F]
		RETLW	H'0F'			;CA=[F]
		RETLW	H'0F'			;C9=[F]
		RETLW	H'0F'			;C8=[F]
		RETLW	H'0F'			;C7=[F]ボーナス66%継続
		RETLW	H'0F'			;C6=[F]ボーナス66%継続
		RETLW	H'0F'			;C5=[F]
		RETLW	H'0F'			;C4=[F]
		RETLW	H'0F'			;C3=[F]
		RETLW	H'0F'			;C2=[F]
		RETLW	H'0F'			;C1=[F]
		RETLW	H'0F'			;C0=[F]
		RETLW	H'09'			;BF=[9]ボーナス79%継続
		RETLW	H'09'			;BE=[9]ボーナス79%継続
		RETLW	H'0F'			;BD=[F]
		RETLW	H'0F'			;BC=[F]
		RETLW	H'0F'			;BB=[F]
		RETLW	H'0F'			;BA=[F]
		RETLW	H'0F'			;B9=[F]
		RETLW	H'0F'			;B8=[F]
		RETLW	H'08'			;B7=[8]ボーナス84%継続
		RETLW	H'08'			;B6=[8]ボーナス84%継続
		RETLW	H'0F'			;B5=[F]
		RETLW	H'0F'			;B4=[F]
		RETLW	H'0F'			;B3=[F]
		RETLW	H'0F'			;B2=[F]
		RETLW	H'0F'			;B1=[F]
		RETLW	H'0F'			;B0=[F]
		RETLW	H'07'			;AF=[7]ボーナス88%継続
		RETLW	H'07'			;AE=[7]ボーナス88%継続
;
		END
 一応注釈が入っているのでわかるとは思いますが、原理は簡単です。
ポートBの入力が0x71になるのを待ちコントロールビットの立ち上がりを待ちます。
次のデータを読み取り0xFFで減算した結果をテーブルから読み出して7セグに出力するだけ

画面クリアや変更信号は予めEEPROMに書き込んであるものを読み出してタイミングに従い出力している
だけなので、かなり単純な作りです。


完成品画像↑(写真のハーネスは長さ50cmのストレートケーブルです。これも作らないと接続できません)

ここで紹介した物の全てはこちらから圧縮ファイルでダウンロードできて以下の物が含まれます。
回路図(CADLUS Circuit)
パターン図(CADLUS X)
ソースコード(テキスト)
バイナリデータ(MPLAB)
部品表(エクセル)
説明書(エクセル)
ケース加工図面(図脳RAPID14 Pro)

部品代をざっと計算すると制作費は3,000円ほどになると思いますが、一番高いのは基板です。
現在基板が30枚ほど余っておりますので1枚600円でお分けいたします。
自分で製作できない方には完成品の販売も考えておりますので、メールください。

おわりに:
「吉宗」用の物も作ったのですが、回路図等を紛失したので見つけたら掲載いたします。

ジャンク箱に戻る