易码技术论坛

 找回密码
 加入易码
搜索
查看: 331926|回复: 12

[原创]文曲星pc1000a/pc1000/cc800添加游戏手柄

[复制链接]
发表于 2004-11-21 09:53:00 | 显示全部楼层
期待ING。。。。。。。。。。。。
发表于 2004-10-31 18:53:00 | 显示全部楼层
好帖
不过两个键能干什么,楼主再开发开发,弄个方向键什么的。
发表于 2004-10-31 21:52:00 | 显示全部楼层
PC1000a这一级别的做手柄没什么实用价值...
NC3000倒是有个线控...不知可不可以做手柄用...
 楼主| 发表于 2004-11-2 21:20:00 | 显示全部楼层
以下是引用tian7在2004-10-31 18:53:40的发言:

好帖

不过两个键能干什么,楼主再开发开发,弄个方向键什么的。


可以用数字电路来控制占空比,这样可以增加按键,但是我没有相关的资料,也就没有研究!
 楼主| 发表于 2004-11-2 21:28:00 | 显示全部楼层
以下是引用xdata在2004-10-31 21:52:50的发言:

PC1000a这一级别的做手柄没什么实用价值
为什么?pc1000a正因为按键不灵才需要做手柄
发表于 2004-11-2 22:23:00 | 显示全部楼层
用什么手柄呢
发表于 2004-11-22 14:04:00 | 显示全部楼层
NC3000偶尝试做一个红外互相控制程序,结果越做越乱,差点把机子弄坏,偶不敢了55555555555555555555
发表于 2004-11-23 20:46:00 | 显示全部楼层
NC2600C
发表于 2004-11-24 20:52:00 | 显示全部楼层
我找文曲星的通信原理很久了,楼主能提供下吗,非常感谢!
 楼主| 发表于 2004-12-3 12:20:00 | 显示全部楼层
[转帖]原在WQXNET
[转帖]一级棒!CC800/PC1000串行通讯原理详解(WQXNET)
CC800/PC1000串行通讯原理详解
                                     by sel.mocker
    在CC800/PC1000机子的旁侧,可以看到的一个插孔,就是CC800/PC1000的串行通讯口,CC800/PC1000用这个口与电脑或其他机子连线进行数据的传输,所以一般称之为串口。长期以来,网上的文曲星论坛里一直没有介绍关于CC800/PC1000的这个串口的通讯原理和编程的文章,使得广大星迷们对CC800/PC1000的通讯原理一知半解,更谈不上对串口进行编程了,本人sel.mocker通过一段时间的研究,最终得出一些结论,现在贴出来与广大CC800/PC1000星迷们共享。
    以下都是本人对CC800/PC1000通讯原理的个人理解,其中肯定有不足不正之处,还请高手们不吝赐教。
    其实CC800并没有真正意义上的串口。真正的串口有波特率这样一个概念,是指串行通信中每秒传送的数据位。一般单片机中都有SBUF这样一个寄存器,只要事先设定好波特率,再将要发送的字节写入SBUF,串行通信装置就能以设定好的波特率将数据通过一根串行线将数据发送出去,接收亦是同理,只需读取SBUF即可。所以两台单片机只要在波特率相同的情况下就能正确收发数据,进行正常的串行通信。
    但是CC800/PC1000并没有真正的串口(这是它的硬件设计师决定的,NC1020,NC2000等就有真正的串口),这样的情况下,要进行串行通信只能用普通的I/O口来模拟串口,就是以固定的时间间隔控制这条I/O口高电平或低电平,就能模拟出一个固定的波特率来。注意这波特率必须是“固定”的,这在有可编程中断和定时器的单片机中是容易实现的,但关键是,CC800/PC1000的中断是固定好了的,没法编程,定时器似乎也没法编程。所以,考虑到CPU的速度并不稳定,CC800/PC1000根本无法做到精确地以“固定的时间间隔来控制那条I/O口”,也就是说,在一条I/O线的情况下,CC800/PC1000根本无法做到波特率固定。波特率不稳定的情况下进行串口通信是很冒险的,因为数据错误率会高到你无法接受的地步。
    幸运的是,CC800/PC1000在设计之初就绕过了波特率不稳定这一难题,因为CC800/PC1000使用两条I/O线,而不是一条!
    那么多出来的那条I/O线是作什么用的呢?你可能想到了:用于同步信号!我们可以称之为同步线,那么另一条I/O线就成了数据线。两条I/O线可以比作正跟你对话的两个人A和B,A先对你说:“B要和你说话。”(相当于发出一个同步信号),你就会知道B要跟你说什么话,才放下手中的工作准备仔细聆听B对你说的话(相当于准备接受一个数据位),这样,只有当同步线有信号时,接收方才会接收数据线上的一个数据位。这样的设计使得通信非常地自由,只要你发送数据的时间间隔没有超过接收方的超时时间限制,什么时候传都可以,根本不用考虑去固定波特率。
    CC800/PC1000中真正用于通信的代码原理就是这样,发送一个数据位时先将数据位传到数据线,然后让同步线有一个负跳变,当作一个同步信号,接收方检测到同步线有负跳变时,就读取数据线上的电平信号,这样就完成了一个数据位的传输,传输一个字节就需要八次上述的操作。
    上面已经讲了CC800/PC1000传输一个数据位的基本通信原理,下面让我们上升到整套的完整的通信协议。
    任何串行通信的开始都需要一个握手程序,以确保双方做好通信准备。这相当于有个人想和你聊天,他会先打个招呼:“Hi,可以和你聊聊吗?”这时若你拒绝了,那么那个人与你的谈话无法开始,若你不理睬他,谈话也同样无法进行,只有当你接受了,回答他说:“可以啊。”表示你已经准备好与他开始谈话,握手程序才顺利通过。
    CC800/PC1000的握手程序基本上也就是让一条I/O线一直跳变,发出请求,另一条接收对方的响应,接收方若同意了就会做出响应,握手程序顺利通过,通信就可以开始了。若连线有问题或对方未准备好,请求方的那条接受线上一直无对方响应,那么超过一定时间后(也就是超时),握手失败。
    握手程序通过后,真正的数据传输就可以开始了,总之每个字节都是通过我前面所说的一个数据位一个数据位地传输,具体先传什么数据,还有如何校验,都是编程者自己设定的,这都属于通信协议的高层部分,本文仅是介绍CC800/PC1000底层的通信原理而已。
    原理解释完了,但大家还不知道具体编程中怎么控制I/O线呢。
    大家知道,文曲星中各外部接口都是映射到内存中的,如LCD液显的显存映射在内存中的$09C0--$0FFF,而存储器页码寄存器的映射地址就是$00,等等。这两条I/O线也有映射地址,那就是$18中的第5,第6位。
(不知道第5位和第6位?比如一个字节:bit bit bit bit bit bit bit bit
                   对应的位数就是  7   6   5   4   3   2   1   0        )
    要知道CC800/PC1000串口里有三条线,若插上连接线,你握着连线的另一头,就会看到这个插头很像随身听耳机插头,共有三片金属片。最外的那个金属片对应着$18中的第六位,中间那个金属片对应$18中的第五位。最里的那个金属片是GND(地线),作为电平零基准。$18中第5,6位的电平会放映到插头上的两块金属片上来。同样若金属片接着高低电平也会放映到$18中的第5,6位上来。这样就能实现像读写内存的方式来控制两条I/O线的电平,很方便吧?
    还要告诉你,这两条I/O线并不是同时双向的,在某一时刻一条I/O线只能是收或发,需要通过设定来规定某条I/O线是接收还是发送。某条I/O线设为发送时,才能往$18中的对应位上写数据位,而设为接收时仅能从$18中对应的位上读数据位并不能改写。怎么设定呢?同样是映射内存,$07的第5,6位分别设定$18中的第5,6位是发送还是接收,1表示发送,0表示接收。如设定$07的第5,6位为01,表示$18中的第5位是接收,第6位是发送。CC800/PC1000中的串行通信代码中,作为发送端的机子将$07设为11,接收的机子将$07设为00,这样发送端才能控制同步线的电平并往数据线里写数据位。而接收端两条I/O线都是接收。具体哪条作为同步线哪条为数据线都是看编程者自己设定的。在握手程序中,一台机将$07设为01,那么另一台机就得设为10。
但是设定完$07还不能通过$18中的第5,6位直接控制两条I/O线,为方便大家应用,一般是使用如下的初始化代码:
     LDA #$9F
     AND #04C0
     STA $19
     LDA $04BA
     AND #$9F
     STA $07
     LDA #$00
     STA $BC
     LDA $04BA
     ORA #$40 *
     AND #$DF *
     STA $07
     STA $04BA
(带*的语句中的数据仅用于举例)
本例中$07的第6,5位被分别设为10,即$18中第6位用于发送,第5位用于接收。
初始化$07之后,就可以直接对$18读写了:
写(发送):
     LDA $04BD
     ORA #$40 *
     AND #$DF *
     STA $O4BD
     STA $18
(带*的语句中的数据仅用于举例)
这样$18中的第六位对应的I/O线就升为高电平了。

读(接收):
     LDA $18
     AND #$20 *
(带*的语句中的数据仅用于举例)
这样$18中的第五位即对应那个I/O线上的电平就被过滤出来到A寄存器中了
接下来加一个BNE语句就可以依照读到的I/O线电平进行跳转了。

    特别要注意的是:若你要改变两条I/O线的收发设定,比如说握手程序之前和之后,都要记得运行一下前面的初始化$07的代码,当然,怎么设定,看你自己的了。

    至此,CC800/PC1000的通讯原理讲得也差不多了,希望这篇文章能给你一点帮助。我想我已经讲得很详细了,有什么不清楚的地方可以问我sel.mocker,其他的具体编程的细节就请你自己研究吧。若这篇文章对你没多大用处,也还是请你支持一下,至少我打了这么多字,也有苦劳吧。呵呵。
还是很谢谢你把它看完了!
手酸死了。。。
sel.mocker 2004 ALL RIGHTS RESERVED 2004/2/18
  

发表于 2004-12-26 17:21:00 | 显示全部楼层
NC2600C需要啊,玩游戏太多好伤键盘的,2600游戏多啊,又忍不住啊,想玩心疼键盘
发表于 2006-8-29 20:45:20 | 显示全部楼层
yun
 楼主| 发表于 2004-10-31 16:26:55 | 显示全部楼层 |阅读模式





为文曲星pc1000a/pc1000/cc800添加游戏手柄
  注意:如果你的文曲星按下述文章测试而出现问题,本人概不负责。请三思后动手!有什么问题请发E-mail:gggyg@163.com
  从文曲星的通信原理可以知道$18接受两条io线,这可以为文曲星做一个手柄。接线图如图(图在压缩包里)。其中电池可用文曲星用过的电池。是否按下按键K1,K2可以通过$18上的第5,第6位可以检测出来。
  检测程序如下:
1.汇编
LDA $00
STA $07  ;把$18的5,6位设为接受
LDA $18
AND #$20 ;检测$18的第5位是否为1,如是则K1按下
BEQ    ;跳转
LDA $18
AND #$40 ;检测$18的第6位是否为1,如是则K2按下
BEQ    ;跳转

我编了一个测试软件,汇编代码如下:
2010: 20 38 E1   JSR $E138   
2013: A9 00    LDA #$00   
2015: 85 07    STA $07   ;把$18的5,6位设为接受  
2017: 20 A8 E0   JSR $E0A8  ;防止循环死机 
201A: A5 18    LDA $18    
201C: 29 40    AND #$40  ;检测$18的第6位是否为1,如是则K2按下   
201E: F0 05    BEQ $2025  
2020: A9 01    LDA #$01   
2022: 20 37 20   JSR $2037  
2025: A5 18    LDA $18   
2027: 29 20    AND #$20  ;检测$18的第5位是否为1,如是则K1按下   
2029: F0 05    BEQ $2030   
202B: A9 50    LDA #$50   
202D: 20 37 20   JSR $2037   
2030: A5 CD    LDA $CD   
2032: C9 F7    CMP #$F7   
2034: D0 E1    BNE $2017  
2036: 60      RTS      
2037: 8D A6 03   STA $03A6  ;画矩形子程序  
203A: 18      CLC      
203B: 69 4F    ADC #$4F   
203D: 8D A8 03   STA $03A8  
2040: A9 01    LDA #$01  
2042: 8D A7 03   STA $03A7  
2045: 18      CLC      
2046: 69 4F    ADC #$4F   
2048: 8D A9 03   STA $03A9  
204B: A9 01    LDA #$01   
204D: 8D AC 03   STA $03AC   
2050: 20 A1 E1   JSR $E1A1  
2053: EA      NOP     
2054: EA      NOP     
2055: EA      NOP      
2056: A9 00    LDA #$00   
2058: 8D AC 03   STA $03AC  
205B: 20 A1 E1   JSR $E1A1  
205E: 60      RTS      

2.bas中的运用
例1.初试化,在文件开始加入:
0 POKE 7,0
1 DATA 165,24,41,32,141,255,63,165,24,41,64,141,254,63,96
2 FOR I=0 TO 14 :READ AOKE 16360+I,A:NEXT
调用:
100 CALL 16360
103 IF PEEK (16383)<>0 THEN    ;如果按下k1就跳转
105 IF PEEK (16382)<>0 THEN    ;如果按下k2就跳转
以上是我把打砖块修改成可用手柄的加入代码。
例2.初试化,在文件开始加入:
1 POKE 16373,165OKE 16374,24OKE 16375,41:POKE 16376,96:POKE 16377,133:POKE 16378,250
2 POKE 16379,96:POKE 7,0
调用:
1010 CALL 16373
1011 IF PEEK (250)<>32 THEN 1020 ;如果按下k1就跳转
……
1020 IF PEEK (250)<>64 THEN 1028 ;如果按下k2就跳转
以上是我把暴走蛇修改成可用手柄的加入代码。

压缩包里有所要的软件,暴走蛇&打砖块的版权属于原作者!

您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

Archiver|手机版|小黑屋|EMAX Studio

GMT+8, 2025-8-24 19:27 , Processed in 0.013128 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表