PIC N64 Controller

Includes but not limited to: SNES, Genesis, Sega CD, PlayStation 1, Nintendo 64, Dreamcast, Game Gear and I guess the Virtual Boy.

Moderator:Moderators

User avatar
evilteddy
Portablizer
Posts:423
Joined:Tue Mar 25, 2008 2:11 am
360 GamerTag:Kirren of Smeg
Steam ID:kizzinator
Location:Newcastle, Australia
PIC N64 Controller

Post by evilteddy » Mon May 24, 2010 8:39 pm



Pretty self explanatory. Shortly after this video was made I managed to destroy my crystal so it'll be a while until my next update but I thought I'd share what I've done so far.

The aim is to get a fully fuctioning controller with support for pot joysticks (optional support for C stick) and rumble and memory. It will be very small compared to a normal controller using a cut up 64 controller board with a mem-pack and a rumble pack.

Evilteddy

User avatar
blaze3927
Portablizer
Posts:1114
Joined:Mon Dec 08, 2008 6:14 am
360 GamerTag:notjames
Location:Australia
Contact:

Re: PIC N64 Controller

Post by blaze3927 » Tue May 25, 2010 12:02 am

Very
very well done, and your also in Australia xD

How much experience with microchips have you had before?
and do you plan to draw/etch up a custom PCB for the final product?
Australian Kaillera server
[url]hhttp://i56.tinypic.com/ncb0wi.gif[/url]

User avatar
stuntpenguin007
Posts:667
Joined:Sun Apr 27, 2008 12:21 pm

Re: PIC N64 Controller

Post by stuntpenguin007 » Tue May 25, 2010 2:37 pm

I was thinking of the exact same project :shock:

Are you going to be open sourcing this as you go? Or are you just going to release it as a hex file when it's finished?
SNESP WIP
Case - 50%
acquired parts - 90%
assembly - 0%

User avatar
evilteddy
Portablizer
Posts:423
Joined:Tue Mar 25, 2008 2:11 am
360 GamerTag:Kirren of Smeg
Steam ID:kizzinator
Location:Newcastle, Australia

Re: PIC N64 Controller

Post by evilteddy » Tue May 25, 2010 3:50 pm

Of course it'll be open source. In fact here's the code I have come up with so far. Beware, it's messy and ugly and badly commented:
Spoiler:

Code: Select all

;N64 controller reciever with LCD on PORTB

	LIST p = 16f628a
	include "p16f628a.inc"
	__config	0x3d0A
	ERRORLEVEL	0,	-302

	cblock 0x20
		Wstore
		temp
		tempout
		button1
	endc

	org 0x0000
	goto	start

	org 0x0004				;interrupt is here and most likely took 3 

cycles to arrive
	movwf	Wstore			;stores the W value in case its used for something 

in the main program

	nop
	nop
	nop
	nop
	nop
	nop
	nop

	call	record8bits
	
	call	delay
	call	delay

	movlw	0x00
	subwf	temp,	w

	btfsc	STATUS,	Z
	call	contstatus

	movlw	0x01
	subwf	temp,	w

	btfsc	STATUS,	Z
	call	contbuttons

	bcf		STATUS,	0
	
	bsf		PORTA,	4

	movf	Wstore	,w		;restores the W value
	bcf		INTCON, 1		;Reset the int flag
	RETFIE					;end of interrupt



start
	movlw	0x07
	movwf	CMCON			;Turn off comparators

	bsf		STATUS,	RP0		;To Bank 1

	movlw	0xFF
	movwf	TRISB			;All Port B are inputs
	movlw	0x00
	movwf	TRISA			;All Port A are outputs

	bcf		81h,	7		;Turns on weak internal Pull ups on Port B 

for the switches
	bcf		81h,	6		;Interrupt triggers on a falling edge of 

data line	

	bcf		STATUS,	RP0		;To bank 0

	movlw	0xFF
	movwf	temp	

delaying	nop	
	nop
	decfsz	temp,	f
	goto	delaying	

	bsf		INTCON,	7		;Turn on Interrupts
	bsf		INTCON,	4		;Turn on RB0 interrupt
	bcf		INTCON, 1		;Clearing the INT flagasdf

	bsf		PORTA,	4

	movlw	0x00
	movwf	button1

looping	btfss	PORTB,	4
	movlw	0xFF
	btfsc	PORTB,	4
	movlw	0x00
	movwf	button1
	goto	looping	


;/////////////////////////////////////////////////////////////////////////////////////////
;Start of the rest of the routines.

record8bits	btfss	PORTB,	1	;Assumes you start the function 2us in.
	goto	$+3
	bsf		temp	,7
	goto	$+3					;All this stupid stuff is needed 

for timing. Without
	bcf		temp	,7			;this the btfss command would throw 

it out because
	nop							;it can take 1 or 2 cycles. 

BTW, like all my commenting?
	call	delay
		
	btfss	PORTB,	1	
	goto	$+3
	bsf		temp	,6
	goto	$+3		
	bcf		temp	,6		
	nop						
	call 	delay

	btfss	PORTB,	1
	goto	$+3
	bsf		temp	,5
	goto	$+3		
	bcf		temp	,5		
	nop						
	call 	delay

	btfss	PORTB,	1
	goto	$+3
	bsf		temp	,4
	goto	$+3		
	bcf		temp	,4		
	nop						
	call 	delay

	btfss	PORTB,	1
	goto	$+3
	bsf		temp	,3
	goto	$+3		
	bcf		temp	,3		
	nop						
	call 	delay

	btfss	PORTB,	1
	goto	$+3
	bsf		temp	,2
	goto	$+3		
	bcf		temp	,2		
	nop						
	call 	delay

	btfss	PORTB,	1
	goto	$+3
	bsf		temp	,1
	goto	$+3		
	bcf		temp	,1		
	nop						
	call 	delay

	btfss	PORTB,	1
	goto	$+3
	bsf		temp	,0
	goto	finish		
	bcf		temp	,0		;The end, Removed a Delay so theres time to 

do stuff

	movlw	0x01
	movwf	temp

finish		return

contstatus	movlw	0x05
	movwf	tempout
	call	Send8bits
	movlw	0x00
	movwf	tempout
	call	Send8bits
	movlw	0x02
	movwf	tempout
	call	Send8bits

	bcf	PORTA,	4
	nop
	nop
	nop
	nop
	call	delay2
	bsf		PORTA,	4
	call	fourus	

	return

contbuttons	movfw	button1
	movwf	tempout
	call	Send8bits
	movfw	button1
	movwf	tempout
	call	Send8bits
	movfw	button1
	movwf	tempout
	call	Send8bits
	movfw	button1
	movwf	tempout
	call	Send8bits

	bcf	PORTA,	4
	nop
	nop
	nop
	nop
	call	delay2
	bsf		PORTA,	4
	call	fourus	

	return	

Send8bits	bcf	PORTA,	4
	nop
	nop
	btfsc	tempout,	7
	bsf		PORTA,	4
	call	delay2
	bsf		PORTA,	4
	call	fourus

	bcf		PORTA,	4
	nop
	nop
	nop
	btfsc	tempout,	6
	bsf		PORTA,	4
	call	delay2
	bsf		PORTA,	4
	call	fourus

	bcf		PORTA,	4
	nop
	nop
	nop
	btfsc	tempout,	5
	bsf		PORTA,	4
	call	delay2
	bsf		PORTA,	4
	call	fourus

	bcf		PORTA,	4
	nop
	nop
	nop
	btfsc	tempout,	4
	bsf		PORTA,	4
	call	delay2
	bsf		PORTA,	4
	call	fourus

	bcf		PORTA,	4
	nop
	nop
	nop
	btfsc	tempout,	3
	bsf		PORTA,	4
	call	delay2
	bsf		PORTA,	4
	call	fourus

	bcf		PORTA,	4
	nop
	nop
	nop
	btfsc	tempout,	2
	bsf		PORTA,	4
	call	delay2
	bsf		PORTA,	4
	call	fourus

	bcf		PORTA,	4
	nop
	nop
	nop
	btfsc	tempout,	1
	bsf		PORTA,	4
	call	delay2
	bsf		PORTA,	4
	call	fourus

	bcf		PORTA,	4
	nop
	nop
	nop
	btfsc	tempout,	0
	bsf		PORTA,	4
	call	delay2
	bsf		PORTA,	4
	
	return		;remember you have 1 us to play with
		
fourus	return
		
delay2
	nop
	nop
	nop
	nop
	nop
	return


delay	
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	return

	end
In answer to Blaze, I haven't had a huge amount of experience with PICs but unlike what Marshall is doing this isn't rocket surgery and there is some great documentation out there but only from the perspective of people talking to the controller not the other way around.

Stuntpenguin, if you do the same project that would be excellent. I'd be interested in seeing some different ways of doing this.

Evilteddy

User avatar
marshallh
Moderator
Posts:2986
Joined:Sat Sep 10, 2005 2:17 pm
360 GamerTag:marshallh
Location:here and there
Contact:

Re: PIC N64 Controller

Post by marshallh » Tue May 25, 2010 3:57 pm

Nice work so far. Before you get too far I would rewrite most of that code, though. For your own sanity later, trust me ;)

I'm crossing my fingers for you with the controller pak stuff. Your PIC should hopefully be fast enough for it, but you can always migrate to a faster one if that happens.
Image

User avatar
stuntpenguin007
Posts:667
Joined:Sun Apr 27, 2008 12:21 pm

Re: PIC N64 Controller

Post by stuntpenguin007 » Tue May 25, 2010 6:34 pm

I haven't gotten too far in my pic programming adventures. Lately I've just been doing blinking leds and doing potentiometer stuff in C. I started off with assembly, so I understand what most of the code is actually doing (except for that "goto $+3" thing), but I'm not entirely sure what the purpose is for some of the code.

correct me if I'm wrong on any of this:

From what I understand, the first step to building something like this would be to answer the n64's polling request to see if a controller is present, and the timing has to be perfect... and that's why you used all the "no operations".

from http://www.mixdown.ca/n64dev/" onclick="window.open(this.href);return false; I've gathered that the n64 will send a 0x00 to the controller to see if it's there. Then the controller, or pic in this case would respond with ??? fill in the blank ???

After this week I should finally get some time to work on this. Good luck with yours :wink:


useful links:
http://www.mixdown.ca/n64dev/" onclick="window.open(this.href);return false;
http://svn.navi.cx/misc/trunk/wasabi/de ... /firmware/" onclick="window.open(this.href);return false;
http://svn.navi.cx/misc/trunk/wasabi/de ... c_comm.inc" onclick="window.open(this.href);return false;
SNESP WIP
Case - 50%
acquired parts - 90%
assembly - 0%

User avatar
evilteddy
Portablizer
Posts:423
Joined:Tue Mar 25, 2008 2:11 am
360 GamerTag:Kirren of Smeg
Steam ID:kizzinator
Location:Newcastle, Australia

Re: PIC N64 Controller

Post by evilteddy » Tue May 25, 2010 10:17 pm

This program is going to be improved a huge amount obviously. It will look completely different in its next rewrite, at the very least I'll compress Record8bits and Send8bits to an eighth of the lines.

The goto $+3 is the same as any other goto but the address it goes to is where the PCL is pointing to at the moment + 3. In simpler language, go down 3 lines.

What the mixdown site told you is broadly correct except many games seem not to care about what you return to an 0x00 request as long as you respond. This is of course only for basic operation where you're only pushing buttons. The controller will not count as being detected unless you are responding to both 0x00 requests and 0x01 requests be it garbage or quality data.

I assume via your question marks that you missed http://svn.navi.cx/misc/trunk/wasabi/de ... servations when you were looking through those other links. It'll get you up to speed with whatever mixdown has missed, in short the nintendo 64 responds with 05 00 02 if no controller pack is inserted. I cannot recommend enough getting an oscilloscope or logic analyser. Working blind is a pain.

Oh, and timing is fairly important and will be even more important when the 64 will eventually want to do a full page eeprom write.

Good luck
Evilteddy

User avatar
stuntpenguin007
Posts:667
Joined:Sun Apr 27, 2008 12:21 pm

Re: PIC N64 Controller

Post by stuntpenguin007 » Wed May 26, 2010 4:07 pm

I made this which is largely based off of your code. In fact, it's pretty much just parts of your code copied and pasted together. I believe this code will answer the n64's request to see if a controller is attached, except I need to get a logic analyzer or something so I can get the right timing down.
Spoiler:

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;							PIC N64 CONTROLLER							 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LIST p = 16f690
include "P16F690.INC"
;Config bits here
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


cblock 0x20
	tempout		;tempout created at 0x20
endc

org	0x0000		;The start address
goto start		;skip to start -- kind of unnessacary right now


start
	movlw   0x07
	movwf   CMCON	;comparators are now off

	bsf      STATUS,   RP0	;move to bank 1 to setup I/O
	movlw   0x00			;put 0x00 in register W
	movwf   TRISA         	;PORTA is now output
	bcf      STATUS,   RP0      	;To bank 0

loop	;infinite loop
	call contstatus
goto loop

contstatus   
	movlw   0x05	;send 05 00 02 in response to n64
	movwf   tempout	;0x05 is now in temput
   	call   Send8bits	;send the 0x05 to the n64
   	movlw   0x00
   	movwf   tempout
   	call   Send8bits
   	movlw   0x02
   	movwf   tempout
   	call   Send8bits

   	bcf   PORTA,   4
   	nop
   	nop
   	nop
   	nop
   	call   delay2
   	bsf      PORTA,   4
   	call   fourus   

   	return	;go back and do it again


Send8bits   
	bcf   PORTA,   4		;set porta bit 4 to 0 (pull low)
   	nop						;waste 1us
   	nop						;waste 1us
   	btfsc   tempout,   7	;if tempout bit 7 is 0 skip the next instruction
   	bsf      PORTA,   4		;set porta bit 4 to 1 (pull high)
   	call   delay2			;delay for 5us (or maybe more?)
   	bsf      PORTA,   4		;set porta bit 4 to 1 (isn't it already pulled high?)
   	call   fourus			;probably a 4us delay?

   	bcf      PORTA,   4		;set porta bit 4 to 0 (pull low)
   	nop						;waste 1us
   	nop						;waste 1us
   	nop						;waste 1us
   	btfsc   tempout,   6	;if tempout bit 6 is 0 skip the next instruction
   	bsf      PORTA,   4		;set porta bit 4 to 1 (pull high)
   	call   delay2			;delay for 5us
   	bsf      PORTA,   4		;set porta bit 4 to 1 (pull high)
   	call   fourus			;probably a 4us delay?

   	bcf      PORTA,   4		;and on and on until 8 bits have been sent
   	nop
   	nop
   	nop
   	btfsc   tempout,   5
   	bsf      PORTA,   4
   	call   delay2
   	bsf      PORTA,   4
   	call   fourus

   	bcf      PORTA,   4
   	nop
   	nop
   	nop
   	btfsc   tempout,   4
   	bsf      PORTA,   4
   	call   delay2
   	bsf      PORTA,   4
   	call   fourus

   	bcf      PORTA,   4
   	nop
   	nop
   	nop
   	btfsc   tempout,   3
   	bsf      PORTA,   4
   	call   delay2
   	bsf      PORTA,   4
   	call   fourus

   	bcf      PORTA,   4
   	nop
   	nop
   	nop
   	btfsc   tempout,   2
   	bsf      PORTA,   4
   	call   delay2
   	bsf      PORTA,   4
   	call   fourus

   	bcf      PORTA,   4
   	nop
   	nop
   	nop
   	btfsc   tempout,   1
   	bsf      PORTA,   4
   	call   delay2
   	bsf      PORTA,   4
   	call   fourus

   	bcf      PORTA,   4
   	nop
   	nop
   	nop
   	btfsc   tempout,   0
   	bsf      PORTA,   4
   	call   delay2
   	bsf      PORTA,   4
   
   	return

;I need to figure out the proper amount of delay time with an osciloscope
;or something.  I obviously left out the delay instruction for delay1 & 2
Does it look like it would work to answer the n64's request if the timing was right and the data line for the controller is on PORTA, 4?
SNESP WIP
Case - 50%
acquired parts - 90%
assembly - 0%

User avatar
evilteddy
Portablizer
Posts:423
Joined:Tue Mar 25, 2008 2:11 am
360 GamerTag:Kirren of Smeg
Steam ID:kizzinator
Location:Newcastle, Australia

Re: PIC N64 Controller

Post by evilteddy » Wed May 26, 2010 7:55 pm

This code wouldn't work for a couple of reasons. For one if you pull the Nintendo 64 data line low while its trying to let it go high while its sending a command or any other data it will just stop and not send anything. At the moment your'e just spitting out controller status constantly and there's no garantuee that the everything would magically sync up and it will return the controller status in the couple of us after the N64 requested it. This is why I used an interrupt. You can work as normal in the main program and the interrupt helps keep timing clean. If you use an interrupt to test this make sure that you delay until after the whole byte has been transmitted and not just send the interrupt as soon as the data line goes low.

Of course if you do this you'll need to connect an interrupt pin to the data line because RA4 can't act as an interrupt trigger in the majority of PICs (and at the moment I've got a 3rd pin connected for TTL input which registers a 1 at a lower voltage than schmitt triggering but in the future I'll just turn the interrupt off RB0). Another very important thing when it comes to timing is of course what you're using as your clock. 20Mhz is the speed I made my program for.

Lastly, even if you make these alterations will still show the controller as not connected until you respond to button status requests with a full 32 bits of data. If you need a basic test then you can respond to the controller status requests with the button status 32 bits.

Evilteddy

User avatar
stuntpenguin007
Posts:667
Joined:Sun Apr 27, 2008 12:21 pm

Re: PIC N64 Controller

Post by stuntpenguin007 » Thu May 27, 2010 1:34 pm

ok, I kind of expected that. If I'm bugging you, just tell me and I'll go away :wink: .

On a side note, the reason I was thinking of a PIC n64 controller was because of another project I was thinking of in which a PIC would plug into a computer on one end, and the n64 on the other, and then there would be a program that would let you use controllers plugged into your computer on the n64.

It's not like I have enough experience / knowledge to make something like that anyways, but I can still dream.
SNESP WIP
Case - 50%
acquired parts - 90%
assembly - 0%

User avatar
Basement_Modder
Portablizer
Posts:962
Joined:Sun Aug 24, 2008 7:16 am
Location:Next door to my neighbor
Contact:

Re: PIC N64 Controller

Post by Basement_Modder » Fri May 28, 2010 11:48 am

I would use this.
Cheers,
Basement_Modder
_________________

User avatar
evilteddy
Portablizer
Posts:423
Joined:Tue Mar 25, 2008 2:11 am
360 GamerTag:Kirren of Smeg
Steam ID:kizzinator
Location:Newcastle, Australia

Re: PIC N64 Controller

Post by evilteddy » Fri May 28, 2010 4:52 pm

Well, I have managed to take the really messy code seen above and by not being an idiot I halved the length of the program. I have also been looking through the magical world of CRCs in general and with the memory and rumble pack. I'm definitely sure that I can get the rumble pack working because there is only ever two messages written to one place so I only need to use a PIC to read what CRCs are returned. On the other hand memory packs will be quite a bit harder but I'm going to give them a try in any case. Big thanks go to Michael Dowty who has a slightly working implementation already in asm.

User avatar
Basement_Modder
Portablizer
Posts:962
Joined:Sun Aug 24, 2008 7:16 am
Location:Next door to my neighbor
Contact:

Re: PIC N64 Controller

Post by Basement_Modder » Sat May 29, 2010 2:53 pm

Could you release pinouts and code for just the buttons, sans any peripherals?

Just so people building portables without that crap can do so sooner.

:P
Cheers,
Basement_Modder
_________________

User avatar
evilteddy
Portablizer
Posts:423
Joined:Tue Mar 25, 2008 2:11 am
360 GamerTag:Kirren of Smeg
Steam ID:kizzinator
Location:Newcastle, Australia

Re: PIC N64 Controller

Post by evilteddy » Sat May 29, 2010 4:56 pm

I would love to release a working version at the moment but there still are a couple of things to go with the basic stuff. Simple things like needing to migrate to a PIC with more buttons and A2D support for joysticks. I'm currently working on migrating to the 16f887 so its happening but at the same time I don't have a crystal anymore so either I make it work at 8Mhz (pretty sure that's impossible even for basic operation) or I have to wait until I get another crystal which isn't coming anytime soon.

User avatar
Basement_Modder
Portablizer
Posts:962
Joined:Sun Aug 24, 2008 7:16 am
Location:Next door to my neighbor
Contact:

Re: PIC N64 Controller

Post by Basement_Modder » Sat May 29, 2010 8:15 pm

Didn't you plan ahead on using a PIC with enough capacity to handle all the buttons? :P

Or did you just have that one on hand at the time?
Cheers,
Basement_Modder
_________________

Post Reply