`
黑色杰克史密斯
  • 浏览: 15223 次
社区版块
存档分类
最新评论

NES 的$4016

    博客分类:
  • NES
 
阅读更多
$4016 是 手柄1 的选通 ...

此 IO端口 在读写时候有着不同的行为 ...

首先读手柄的状态 ... 要先向 $4016 写 1 此时内部的计数器开始工作并且会为数据流上锁... 表示已经做好准备 ... 此时在往$4016 写0 解锁 数据才能正确读取出来 ...

数据流一共有 24 bit 如图



信号用来检测是4端口的接入状态:
    %0000:没有连接设备
    %0001:只有$4016手柄
    %0010:只有$4017手柄 (此段话摘自任天堂产品文件)


对于一般的输入 ... 只要 获取0 - 7 位即可 ...

NES的输入设备流还有一个十分古怪的之处 ... 每次读取只能读取 1 Bit 也就是想要完整的获取手柄的输入必须要读取8次 $4016 ...

6502 伪代码 ...
     
      
							LDA #$1   	
 						STA $4016   ; 	写 1 复位设备	此时设备以及准备好并且上锁
							LDA #$0  
							STA $4016 	;	解锁	获取输入设备数据流 此时可以开始获取数据流
							
							LDA	$4016	;	第1次读 获取 	A键			的状态 
							LDA	$4016	;	第2次读 获取 	B键			的状态
							LDA	$4016	;	第3次读 获取 	Select键	的状态
							LDA	$4016	;	第4次读 获取 	Start键		的状态
							LDA	$4016	;	第5次读 获取 	上键		的状态
							LDA	$4016	;	第6次读 获取	下键		的状态
							LDA	$4016	;	第7次读 获取	左键		的状态
							LDA	$4016	;	第8次读	获取	右键		的状态 
                            


有心的朋友 看过 NES模拟器的源代码就知道 ... $4016内部有一个计数器 ... 复位之后此计数器被初始化为0 ... 在初始化之后每一次读取计数器都会自增 之后左移 计数器值 ...

高级语言伪代码就是 ...

bool	isLocked	=	TRUE	; 	数据流锁	
uint	Counter4016	=	0		;	移位计数器

UINT	InputData				;	输入数据 可以来自 IDirectInput8 也可以来自Win消息回调 

BYTE	ReadAddr4016 () {
		if(isLocked == TRUE)	
				return 0		;	如被锁定什么也读不到 直接返回一个无意义的值
		else	{
			return	(InputData >> Counter4016) & 1
			++Counter4016		; 	每次读取后自增 1 访问下一位数据
		}
}

VOID 	WriteAddr4016(BYTE val){
	
		if(val == 0)
			isLocked = FALSE	; 解锁
			
		else (val == 1) {
		
			Counter4016	= 0		; 初始化计数器 从 第一位开始读取数据流 
			isLocked = TRUE		; 锁定
		}
	}	
}

$4017 同理
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics