Famicom World

Family Computer => Technical & Repair Assistance => Topic started by: lifewithmatthew on September 14, 2021, 11:57:14 am

Title: Creating a Built in 4 Score device
Post by: lifewithmatthew on September 14, 2021, 11:57:14 am
I'm having fun messing around with the expansion slot connector on the bottom of the front loader NES and wanted to make my own 4 score adapter using the exposed pins rather than just plugging into the two front controller ports.

I have an original Four Score that uses the Hori FPA-92-S01 9109 U chip that I'm using as a reference and am working on making a circuit diagram of.  So far I've mapped out the circuit and figured out the pinout of the main FPA-92-S01 chip and the 7 pin connector that goes to the two controller ports:

                             ,---v---.                 
                    J2 CLK ->|01   22|-- +5v         
                     J2 D0 ->|02   21|-- 2 Controller Mode Selected on +5v / 4 Controller on Ground
                    J3 CLK ->|03   20|<- J1 CLK         
                     J3 D0 ->|04   19|<- J1 D0         
                    J4 CLK ->|05   18|<- Latch/Strobe All
                     J4 D0 ->|06   17|<- CN5 Pin 1 (Latch/Strobe)
 Turbo B (Selected on +5v) --|07   16|-> CN5 Pin 2 (D0 Controller 1)
 Turbo A (Selected on +5v) --|08   15|-> CN5 Pin 5 (CLK Controller 2)
     Voltage Divider to 10 --|09   14|-> CN5 Pin 4 (D0 Controller 2)
     Voltage Divider to 09 --|10   13|-> CN5 Pin 3 (CLK Controller 1)
                       GND --|11   12|-- GND  
                             +-------+             
                             FPA-92-S01
                             ,-V-.
         FPA-92-S01 Pin 17 <-|01 |<- Latch/Strobe Controller 1 Only
         FPA-92-S01 Pin 16 ->|02 |-> Controller 1 D0
         FPA-92-S01 Pin 13 ->|03 |-> CLK Controller 1
         FPA-92-S01 Pin 14 ->|04 |-> Controller 2 D0
         FPA-92-S01 Pin 15 ->|05 |-> CLK Controller 2
                       GND --|06 |-- GND Controller 1 Only
                       +5v --|07 |-- +5v Controller 1 Only
                             +---+
              CN5

So I have two questions I was hoping y'all could help me out with.

First off, if I'm understanding the schematic of the expansion port then I can use pin 43 (Latch/Strobe Controller 1) pin 35 (Controller 1 D0), pin 37 (CLK Controller 1?), pin 19 (Controller 2 D0), pin 11 (CLK Controller 2?), pin 1 and 48 for +5v, and pin 2 and 47 for ground.  Am I right about Pin 37 and 11 of the expansion port being the Clock pulse for Controller 1 and 2? The diagram I'm referencing (https://wiki.nesdev.com/w/index.php/Expansion_port)  has pin 37 and 11 listed as
/OE for joypad 1 ($4016 read strobe) and ($4017 read strobe) /OE for joypad 2 respectively

Second, I was reading on NesDev (https://wiki.nesdev.com/w/index.php?title=Four_Score#Hardware) that if I wanted to duplicate the effects of the Hori chip you just need chip that has six total shift registers acting in parallel.  Does anyone know of a good option for that?  I'm a bit lost as anytime I search for a shift register that can handle 8 elements per channel I get results for a chip that have 64 pins, so I know I'm missing a crucial concept.

Thanks for any pointers you can provide!
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on September 15, 2021, 02:21:54 pm
For those interested I mapped out the circuitry on my board, here's the wiring diagram.  Just as a note, I have no idea what diode is being used on this board.  It has no marking, but it is clearly and purposeful being used in reverse.

If anyone could help me figure out an appropriate substitute for the main chip I'd really appreciate it!

Also I currently have zero idea what's going on with the pins I've labeled as "Volt_Div".  I named it when I thought it was split between two resistors and only later realized one of them was a radial capacitor.  The rest of it I'm confident about

(https://images2.imgbox.com/00/4e/Vsi7wBe2_o.png)
Title: Re: Creating a Built in 4 Score device
Post by: P on September 16, 2021, 02:20:47 pm
Cool project there. :) I've been hoping someone would make a home-made Four Score some day. If you support the signature used by the Hori 4 Players Adapter (which is basically the Famicom version of the Four Score) as well and add $4016.D1 and 4017.D1 to the mix you could increase compatibility with games.

I'm not the right person to answer but I will answer what I know.

Quote from: lifewithmatthew on September 14, 2021, 11:57:14 amFirst off, if I'm understanding the schematic of the expansion port then I can use pin 43 (Latch/Strobe Controller 1) pin 35 (Controller 1 D0), pin 37 (CLK Controller 1?), pin 19 (Controller 2 D0), pin 11 (CLK Controller 2?), pin 1 and 48 for +5v, and pin 2 and 47 for ground.  Am I right about Pin 37 and 11 of the expansion port being the Clock pulse for Controller 1 and 2? The diagram I'm referencing (https://wiki.nesdev.com/w/index.php/Expansion_port)  has pin 37 and 11 listed as
/OE for joypad 1 ($4016 read strobe) and ($4017 read strobe) /OE for joypad 2 respectively
Yes that is my understanding of it too, and it matches the Famicom expansion port pin 9 and 14 which are also called /OE, they are indeed what clocks $4016 and $4017 respectively and are usually called CLK.

The other pins also looks right, but one thing to be aware of is that you are using duplicates of the controller port pins (the "xx" pins on Nesdev wiki). The latch (pin 43) and clock pins are not a problem but D0 of both controllers would conflict with any controllers connected to the controller ports in front at the same time. The Famicom has a similar problem with expansion port pin 8 which is controller II D0 and controller II is normally permanently plugged in on a Famicom.


Unfortunately I can't answer the question about shift registers (I would like to know too). It's too bad that Nesdev forums are still down.
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on September 17, 2021, 05:37:01 am
Quote from: P on September 16, 2021, 02:20:47 pmUnfortunately I can't answer the question about shift registers (I would like to know too). It's too bad that Nesdev forums are still down.

Thanks for the response!  As I've been looking over it the past couple of days I realized that it's probably not a shift register being used in the four score at all, but a very basic micro processor.  It has no external clock or relays or anything, and yet it can provide a turbo mode?  After sending data for ports 1/3 it can send a signature?  Where does that signature even get generated without the the physical inputs going into a shift register?

It has to be mirco processor!  I've got some controller extension cords coming in that I plan to cut up and use to test this theory with an arduino.  We'll see how close to the mark I am with my developing theories.
Title: Re: Creating a Built in 4 Score device
Post by: P on September 18, 2021, 03:22:28 pm
Yeah it might be a custom microcontroller, I think I remember someone thinking it was that on Nesdev but I can't remember for sure. I'm sure it can be reproduced just using logic chips and discrete components though.

Yes there is a signature in two parts in the bitstream coming in after the controller 3 and the controller 4 data respectively. It's %00010000 and %00100000 respectively with bits in order coming in from the most significant bit to the least one in both cases. The Famicom variant uses the same signature but swaps the two parts, but otherwise it works exactly the same as the Four-Score/Nes-Satelite, except that it connects to the expansion port and thus uses $4016.D1 and 4017.D1 for all controllers instead of $4016.D0 and 4017.D0 like the Four-Score does. All this should be explained on the wiki.

If you build a Four-Score you need to make sure the signature is wired or games won't detect it as connected.
I made a test program for both the Four-Score and Famicom expansion controllers (the "Simple" method in the wiki). I've yet to add Hori's Famicom multitap though.

Here is the program: You cannot see attachments on this board., it's in NROM and FDS so it can be played on a flashcart, FDSStick or an emulator. Rename the file extension ".txt" to ".7z" to open and extract it.

Edit: A read-only mirror of the Nesdev forum is back up. Here (https://forums.nesdev.org/viewtopic.php?f=22&t=18701) is the link to my program.
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on September 21, 2021, 02:02:24 pm
Thanks I'll have to give that a look as I work this out.  Currently I'm waiting on some NES controller expansion cords that I can cut up to wire it into my arduino and up to my NES.  The basic theory of it seems straight forward, I look forward to finding out how wrong I am in that assumption 🤣
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on September 22, 2021, 01:03:33 pm
So I'm working on understanding (electrically) how the controllers are read.

I understand that:
1) the NES sends out a latch by writing high state followed by a low state.  This enables all button inputs to be read  (on the high state) and then stored (on the low state) in the shift register
2) The NES sends eight clock pulses, with each pulse the next bit is send out of the shift register.

So that's player one, but what about player 2? 
Does the NES send all 8 pulses for player 1 followed by all 8 pulses for player 2 I.e.:

1) Set latch to high then low
2) Send all 8 pulses for controller 1
3) Send all 8 pulses for controller 2
4) wait until next cycle

Or do the pulses alternate between each controller? I.e.

1) Set latch to high then low
2) Send first pulse for controller 1
3) Send first pulse for controller 2
4) Repeat until 8 pulses are sent for both controllers
5) Wait until the next cycle.

When the 4 score is put into the mix, I'm assuming that the scan cycle is reduced to 1/3rd it's normal speed when in 4 player mode i.e.

1) Set latch to high then low
2) Send all 8 pulses for controller 1
3) Send all 8 pulses for controller 2
4) next cycle set Latch to high then low
5) Send all 8 pulses for controller 3
6) Send all 8 pulses for controller 4
7) Next cycle set Latch to high then low
8 ) Send 0,0,0,1,0,0,0,0
9) Send 0,0,1,0,0,0,0,0
10) Wait for next cycle to repeat

But by any chance do you know exactly how the reading for the 4 score works?
Title: Re: Creating a Built in 4 Score device
Post by: P on September 23, 2021, 06:57:57 am
For controller II your second theory is correct, pulses alternates. Setting the latch high then low will latch all controllers including both expansion controllers 3 and 4 and Four Score controllers 3 and 4. The latch pin in each controller port and both NES and Famicom EXP ports are all connected to one of the Famicom's three output pins (output port $4016.D0 or sometimes just called OUT0). Each controller internally connects this pin to pin 9 of the 4021 shift-register which then starts putting the button data on its output port for the Famicom/NES to read.

After latching, the game can read the data for any and all controllers. Controller I is read from input port 4016.D0 and controller II is read from input port 4017.D0, so they are read alternating pulses but from different data pins. Expansion port controller III and IV are read from two other pins in the expansion port (input port 4016.D1 and input port 4017.D1 respectively).
The Four Score's Controller III and VI however are read from the same data pin as controller I and II respectively (input port 4016.D0/4017.D0) and comes sequentially after the 8 controller I and II reads for a total of 16 pulses for each of those ports. So you can think of it like two 16-button controllers instead of four 8-button controllers. Likewise, the signature is just another 8 reads from both ports. No need to latch again there either. Actually you shouldn't latch again, if you do the controller will just send data from the beginning again.
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on September 23, 2021, 12:33:17 pm
Thank you so much for the explanation!  That clarifies thing so nicely and raises another set of questions  ;D

You mentioned that on the expansion ports controller 3 and 4 are read from 4016.D1 and 4017.D1, whereas the 4 score still used the same location as controller 1 and 2 (so it would send a latch signal followed by 24 pulses to get Controller 1/3 and signature or Controllers 2/4 and signature).

For the four score this should mean that even in 2 player mode it would send the data for any controller connected, eight "1s" for any controller not connected and the appropriate signature.  This should work with any non four player game as the latch pulse would reset the pointer back to 0 and I would just send the data for player 1 or 2.  Okay, no worries.

So how did the game know to ask for 24 bits from player 1/2 controller ports to support the four score, or 4016.D1/4017.D1 for the expansion ports?  Was it only Japanese games that used the 4017/4016 D1?
Title: Re: Creating a Built in 4 Score device
Post by: emerson on September 24, 2021, 07:26:30 pm
This page on nesdev (https://wiki.nesdev.org/w/index.php/Controller_detection) details how to detect which peripherals are connected.

As 4016.D1/4017.D1 are not present on the US NES controller ports and no official hardware used the US expansion port, it's probably safe to say that only japanese games used them.

In regards to R1 and C2 and the "Volt_Div" inputs, I suspect these are used as the clock source for the turbo function via the RC time constant. With this in mind, let's assume U1 pin 9 is an output and pin 10 is an input. Let's start by asserting pin 9 high. This will charge C2 through R1 and eventually bring pin 10 to a logic high state. Once pin 10 reaches logic high this would internally toggle the state of pin 9 causing it to go low, thus discharging the capacitor through R1, causing pin 10 to go low, and the cycle repeats itself. The state of pin 9 would be controlled by the formula "pin 9 = (pin 10) XOR (turbo A OR turbo B)".

As for the controller port diodes, these are what's known as signal or switching diodes. Two reasons to have these diodes are to assert a known logic state or to protect the internal circuitry from external ESD. A suitable part for this would be either 1N4148 or 1N914 as these are both popular and inexpensive switching diodes. For the record, the diodes used in the schematic are 7 amp power rectifier diodes you would find in an AC->DC power adapter. The 1N400x family of diodes are probably just as popular as the 1N4148 and 1N914, just for different use cases.

We can rule out that U1 is a micro processor as processors are typically controlled by an external device via address and data busses and would either have a boot rom or receive instructions from an external rom like a game cartridge. A microcontroller would be a more appropriate assumption as they have the instructing device built in and can be programmed to interact with the outside world when necessary, much like U1 is doing here. With that being said I doubt U1 is a microcontroller for a few reasons. The main reason being there is no synchronizing system clock between U1 and the console itself, nor is there an external timing device like an oscillator or resonator. Assuming it's a microcontroller, this would imply that U1 would have an internal clock fast enough to cope with the asynchronous pulses (relative to its internal clock) of the Latch, CLK1 and CLK2 signals, calculate whatever it needs to do, and return the appropriate data. I doubt the cost of such a part in the early 90s (assuming that 9109 value is a date code) is justified in this use case.

I would assume that U1 is an ASIC, or Application Specific Integrated Circuit. In simple terms, it is a microchip designed specifically for the required job and nothing else. In this case it's a bunch of glue logic rolled up into one chip. It's an inexpensive and common solution for tasks such as this. Finding a drop in replacement will be next to impossible.

Essentially what you need for each channel is a multiplexer that can switch between a total of 3 inputs every 8 clocks, and everything be reset by the latch pulse. The 8-bit signatures for each channel could be 4021 shift registers (the chip used in NES controllers) with the data lines soldered to VCC or GND to generate the binary signature. Additionally, 4021 ICs could be used for the 8 clock counters by tying D0-D7 to GND and the serial input to VCC. This would provide a logic high on the data output line only after 8 clocks, and would remain high until the next latch pulse. The 4021 data outputs from the counters would control the multiplexer channel select bits, and a bit of glue logic would use these to control when each counter/controller pair receives the clock pulses. The data outputs from the controllers would be tied to the multiplexer data inputs, and the multiplexer data output would feed the console. In total you would need six shift registers, two 3->1 multiplexers, and a small bit of glue logic. A minimum 10-12 chip solution if using basic parts. Adding turbo functionality will require more logic.

Once the logic is known it could then be programmed into a GAL, CPLD or similar logic programmable device for a one chip solution. A modern day microcontroller could probably do the task as well but my preference is to weed out the potential for error and use pure logic, but again that's just my preference.
Title: Re: Creating a Built in 4 Score device
Post by: emerson on September 25, 2021, 05:05:50 am
I opened my four score this morning to have a look and noticed that my diodes in fact have markings! Each diode is labelled "Z6.2" which suggests they are 6.2v zener diodes. I desoldered D1 for a bench test which revealed a silkscreen image of a zener diode beneath it (note the lines coming off either end of the cathode stripe). The bench test also proved that these are in fact zener diodes.

I will ask that you double check your circuit as I am noticing a small difference between your schematic and my pcb. Every D0 resistor/diode combination on my pcb has them in series between VCC and GND, with the junction tied to D0 of its respective controller port. My pcb is labelled "HORI FPA-NES-02", "NTSC", and "FPA-92-S01". The date code on my FPA is 9139, so just a few months older than yours. I guess that also raises the question, although it shouldn't make much difference, but is your adapter PAL or NTSC?

Here is some crude ascii art of what I am seeing on my pcb:

    VCC
     |
     |
    ---
   |   |
   |   | 10K
   |   |
    ---
     |
     |
     +---------<< D0
     |
     |    /
  ___|___/
 /  / \
/  /___\  Z6.2
     |
     |
     |
    GND

Title: Re: Creating a Built in 4 Score device
Post by: P on September 25, 2021, 10:08:41 am
Quote from: lifewithmatthew on September 23, 2021, 12:33:17 pmSo how did the game know to ask for 24 bits from player 1/2 controller ports to support the four score, or 4016.D1/4017.D1 for the expansion ports?  Was it only Japanese games that used the 4017/4016 D1?
The game just needs to read 24 bits of both ports and compare the last 8 bits with the Four Score signature. If the signature is wrong, only the first 8 bits contains meaningful data as the Four Score isn't connected (or is in 2-player mode).

Normal controllers can't really be detected reliably, so I don't think games try to detect the 4016/4017.D1 expansion port controllers with the "simple" method. "Simple" expansion port controllers are supported by most Japanese games, even 1- and 2-player games, as alternative controller I and II so people can use external controllers instead of the built-in ones. There are many games that doesn't support the "simple" method though (which is pretty annoying). Localized games generally don't remove "simple" expansion port support, but Super Mario USA does remove it from Yume Koujou Doki Doki Panic for reasons only Nintendo knows. Western-made games generally don't support the expansion port at all, but some Rare games actually do support it (NES Battletoads doesn't but R.C. Pro-Am II does).

The Nesdev wiki page you linked to has a nice list of games and what controller methods they support, there is also a list here on the forum somewhere.
Bomberman II for example is a 3-player game and only supports a third controller in the expansion port ("simple") but no multitaps. Player 1 and 2 has to use the built-in controllers. Downtown Nekketsu Koushinkyoku is 4-player and supports all three methods (simple, Hori multitap and Four Score) despite the game not being released on the NES and the Four Score not available on the Famicom. To connect two controllers to the expansion port the simple way you need one of those controllers with a daisy chained expansion port or build a custom adapter that splits the port appropriately (there are those using NES ports as well so that NES controllers can be used).
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on September 27, 2021, 09:35:52 am
Quote from: emerson on September 24, 2021, 07:26:30 pmIn regards to R1 and C2 and the "Volt_Div" inputs, I suspect these are used as the clock source for the turbo function via the RC time constant.

That makes sense

Quote from: emerson on September 24, 2021, 07:26:30 pmWe can rule out that U1 is a micro processor

Microprocessor/microcontroller, I was just referring to whatever an Arduino is based on the addition of the signature after the controller 1/3 or 2/4 reads and to control the turbo and 2/4 player selection.  I suppose it's possible that it has some internal circuitry to allow it to load in the signature values


Quote from: emerson on September 24, 2021, 07:26:30 pmI would assume that U1 is an ASIC, or Application Specific Integrated Circuit. In simple terms, it is a microchip designed specifically for the required job and nothing else. In this case it's a bunch of glue logic rolled up into one chip. It's an inexpensive and common solution for tasks such as this. Finding a drop in replacement will be next to impossible.

That's true, considering when this came out, hardwired logic gates would be the most likely solution.

Quote from: emerson on September 24, 2021, 07:26:30 pmA minimum 10-12 chip solution if using basic parts. Adding turbo functionality will require more logic.

I think you would be able to do it with far less parts if turbo functionality was excluded.  All that is needed is the chip to combine the data from the controllers and 2 additional sift registers (such as the SN74HC165 from TI).  The additional sift registers would have the inputs tied to voltage/ground as appropriate to create the signature.  Then all 4 controllers and 2 signature creating shift registers would feed into the single chip to combine it all. 3 ICs and you could have a very basic solutions using just ICs.


Quote from: emerson on September 24, 2021, 07:26:30 pmA modern day microcontroller could probably do the task as well

Indeed it can.  I just got it all working with an Arduino Mega (it uses an ATMega2560).  I have a Nano Every on the way that uses the ATMega4809 to see if I can make the whole thing for dirt cheap.  I'll let you know how it goes.
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on September 27, 2021, 09:59:21 am
Quote from: emerson on September 25, 2021, 05:05:50 amI opened my four score this morning to have a look and noticed that my diodes in fact have markings! Each diode is labelled "Z6.2" which suggests they are 6.2v zener diodes. I desoldered D1 for a bench test which revealed a silkscreen image of a zener diode beneath it (note the lines coming off either end of the cathode stripe). The bench test also proved that these are in fact zener diodes.

Excellent!  As I said in my initial post I had no idea what was used so I just threw a random diode as place holder in my schematic to show that a diode existed at that location, but I didn't want to desolder anything off my 4 score.

Quote from: emerson on September 25, 2021, 05:05:50 amI will ask that you double check your circuit as I am noticing a small difference between your schematic and my pcb. Every D0 resistor/diode combination on my pcb has them in series between VCC and GND, with the junction tied to D0 of its respective controller port. My pcb is labelled "HORI FPA-NES-02", "NTSC", and "FPA-92-S01". The date code on my FPA is 9139, so just a few months older than yours. I guess that also raises the question, although it shouldn't make much difference, but is your adapter PAL or NTSC?

Sure!  So for mine I have the following markings "HORI FPA-NES-002" "CMK-54x" "FPA-92-S01" and "NTSC/PAL" with PAL marked out (so mine is NTSC)

As for the way the diodes are connected... I mean your drawing isn't wrong.  For controllers 2 and 3 that is how they're wired, but for ports 1 and 4 the diode and resistor are right next to each other.  Here's a picture I just took showing the PCB and the PCB with markups.

(https://images2.imgbox.com/8e/a9/iK8ulFgc_o.png)

(https://images2.imgbox.com/de/4b/sUN3MhGE_o.png)

The blue lines are my diodes and the red lines are resistors. (The diodes are placed such that the flow would go from ground to voltage). There is also a jumper that is between 2 diodes and to the right of a diode resistor pair that I didn't mark that is being used as a jumper for the ground plane.

More than everything being in series or parallel my translation of the layout was the resistor is a pull up resistor for the data line and the diode was to assert a known data state (as you previously mentioned as well :) ) The fact that in some cases this gives the appearance of everything being in series and in some cases being in parallel is coincidental.  I believe the focus was just on saving money and making the circuit work out for only being one layer.
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on September 27, 2021, 10:03:04 am
Quote from: P on September 25, 2021, 10:08:41 amThe Nesdev wiki page you linked to has a nice list of games and what controller methods they support, there is also a list here on the forum somewhere.
Bomberman II for example is a 3-player game and only supports a third controller in the expansion port ("simple") but no multitaps. Player 1 and 2 has to use the built-in controllers. Downtown Nekketsu Koushinkyoku is 4-player and supports all three methods (simple, Hori multitap and Four Score) despite the game not being released on the NES and the Four Score not available on the Famicom. To connect two controllers to the expansion port the simple way you need one of those controllers with a daisy chained expansion port or build a custom adapter that splits the port appropriately (there are those using NES ports as well so that NES controllers can be used).

Hmmm... the reason I'm asking is I'm trying to think of ways to maximize compatibility.  Like if I could use a switching IC to change what I'm connected to and how the data is processed (Position 1 using the four score method, position 2 send data to 4016.D1/4017.D1)
Title: Re: Creating a Built in 4 Score device
Post by: P on September 27, 2021, 03:28:17 pm
Yeah, that's what I thought too. 4016.D1 and 4017.D1 are available in the NES expansion port (pin 12 and 20) so it's just a matter of switching to those pins and swap the two signature bytes (the one for 4016.D0 goes to 4017.D1 and vice versa) for the Hori multitap method to work.
For the "simple" method I guess you could just send first two controllers to the two D0s and the other two to the two D1s, and send no signature to either.

You could also add a microphone (or just a pushbutton) to 4016.D2 (pin 33) and shout on bunnies. ;D
Title: Re: Creating a Built in 4 Score device
Post by: emerson on September 27, 2021, 03:55:28 pm
Quote from: lifewithmatthew on September 27, 2021, 09:35:52 am3 ICs and you could have a very basic solutions using just ICs.

I admit my 10-12 chip solution quote is pretty generous, but I disagree with this for three reasons:
- One, if a three chip solution were possible Nintendo would not have paid to have a custom chip made.
- Two, if two of the three chips hold the signatures, that means your third chip would be a dual 3-1 multiplexer that counts clocks and automatically changes multiplexer input every 8 clocks. In other words, an FPA-92-S01 minus some 8-bit shift registers.
- Three, if it were really that easy you would likely find schematics for it throughout the internet as you do NES/Famicom controllers.

ASICs are used when you want to cram a lot of circuitry into a relatively small enclosure. Therefore, if you see an ASIC it's safe to assume that the logical equivalent is at least somewhat complex and worth the cost of manufacturing it. Now I am curious what the lowest chip count solution is for a pure logic four-score...

Quote from: lifewithmatthew on September 27, 2021, 09:59:21 amAs for the way the diodes are connected... I mean your drawing isn't wrong.

Thank you for the images. I know my drawing isn't wrong but as I suspected your schematic is. I didn't want to assume before in case there was some weird hardware recall and you happened to have one that got through. I understand that physically some parts are in parallel and some aren't but physical orientation has little to do with how they are actually connected in circuit. You detailed the solution perfectly in the image with the highlighted diodes and resistors, now compare that to your schematic.

Do you plan to use the zener diodes in your end design? I am unaware of any specific design considerations when it comes to zener diodes aside from max current capability. I would think as long as it can handle the current any 6.2v zener diode should work fine.

I am glad to hear you have a microcontroller solution working!
Title: Re: Creating a Built in 4 Score device
Post by: emerson on September 27, 2021, 06:11:33 pm
After fooling around in Kicad for a while the best solution I can get is 8 chips and two transistors. This does not include turbo.

Edit: You don't need the transistors, logic chips only can do it.
Title: Re: Creating a Built in 4 Score device
Post by: emerson on September 28, 2021, 04:23:14 am
I think I have it down to 6 chips and 2 transistors but I'm not certain without building/simulating it.

Also, after all my talk about U1 being an ASIC, it hit me this morning that "FPA" could possibly stand for "Field Programmable Array".
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on September 29, 2021, 02:24:52 pm
Quote from: P on September 18, 2021, 03:22:28 pmIf you build a Four-Score you need to make sure the signature is wired or games won't detect it as connected.

On that program you wrote, can you confirm the signature it's looking for for the four score?

I've worked out my program such that it sees all four controllers in the program, but using the FDS program you sent, only controller 1 and 2 data are being seen at the NES.  However, the FDS program does recognize my actual Four Score when I plug it in.

Right now I have a 16 bit variable that holds the values for the 2 controllers (1 and 3 or 2 and 4), and then an 8 bit variable that holds the signature.  After 15 pulses have been read it swaps out the controller data with the signature and sends that.  For controllers 1 and 3 I have the signature set to 8 (which would be binary 00001000) and for controllers 2 and 4 I have the the signature set to 4 (which would be binary 00000100).
Title: Re: Creating a Built in 4 Score device
Post by: P on September 30, 2021, 10:03:02 am
You seem to have the signature backwards. It should be 16 and 32 respectively in decimal, not 8 and 4 (this is of course assuming that bits are rolling in from right to left like in my program). Check the @nes_multitap_id routine in my source and you should see this piece of code:

@loop_nmid2:
  lda $4016
  lsr a
  rol temp+0
  lda $4017
  lsr a
  rol temp+1           ;save ID in RAM
  dex
  bne @loop_nmid2
  lda temp+0
  cmp #%00010000
  bne @nm_off
  lda temp+1
  cmp #%00100000
  bne @nm_off
The 16-byte Four Score ID is saved in RAM registers temp+0 and temp+1, which are then compared with the expected values and branches off if either is incorrect.
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on October 01, 2021, 12:31:40 am
Quote from: P on September 30, 2021, 10:03:02 amYou seem to have the signature backwards. It should be 16 and 32 respectively in decimal, not 8 and 4 (this is of course assuming that bits are rolling in from right to left like in my program).

Just to make sure, when it gets to your program do you consider a "0" to indicate the button is pressed or not pressed?

I changed the way I processed my code to improve speed and it's working REALLY well except the signature bit.  At this point I have three 8-bit variables for each controller pair.  When I get the latch I reset back to the first bit of the first controller, after 8 clock pulses I swap to the next controller, 8 pulses later I swap to the signature bits.

I've put in some debug code and can confirm it makes it all the way to the signature bits, and I've tried all kinds of signatures for the controllers but I can't get it to work :(  At this point I wish I had an oscilloscope that I could connect to a four score so I could compare it to my setup to see what it is I'm missing!
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on October 01, 2021, 12:51:43 am
YYYYYEEEEESSSSS!!!!  That was the secret!  The signature bits are reported as seen by the NES, but that's the opposite values that are ELECTRICALLY SENT!  For my needs a 1 represents an unpressed button and a zero represents a pressed button.

(https://images2.imgbox.com/e5/15/98e7P2PD_o.png)


Also, the bits are stored opposite as to how you receive them apparently.  So for controllers 1/3 the signature bits were 11110111 and for controllers 2/4 the signature bits were 11111011 (or 247 for controller 1/3 and 251 for controllers 2/4).

Thanks for helping me work this out, I am beyond thrilled with it!

I do have a couple of lingering issues:
1) I'm currently having to use 2 boards since I didn't have enough interrupts on one.  I hope to be able to replace this with a single board.
2) I'm getting some flashing on controllers 3 and 4.  I think for some reason the "multitap" (MatthewTap, lol) is occasionally getting the latch prior to finishing sending the signature.  I'll test it out with RC-PRO AM 2 and see how well it works for players 3 and 4 later.
Title: Re: Creating a Built in 4 Score device
Post by: emerson on October 01, 2021, 03:44:56 am
I have never programmed Arduino before but I do mess with PIC microcontrollers. Something like the example code below should allow you to handle all incoming signals within the interrupt routine. Is something like this possible with the Arduino?

//This example assumes that $4016.LATCH, $4016.CLK and $4017.CLK are on PORTB bits 0, 1 and 2 respectively. The interrupt is triggered by a PORTB pin state change irq.


void interrupt __FourScoreIRQ();
x = PORTB and 0x07; //isolate latch and clock lines
switch (x) {
case 0x07: //latch high pulse detected

//latch all controllers here
       
case 0x04: //$4016.CLK low pulse detected

//$4016 read routine here

case 0x02: //$4017.CLK low pulse detected

//$4017 read routine here
     }

     while 0x06 != PORTB and 0x06 //loop until default state is returned to avoid false triggers
     wend
     retfie     //return from interrupt
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on October 01, 2021, 07:10:18 am
The Arduino does have interrupts (without using them, I'm convinced it would be impossible to make this code work), but depending on which ATMega you're using there are a limited number of interrupts.  The most prolific ATMega only provides 2 interrupts.  Now that I've worked out the correct way to do things, I'm going to try some of the other boards that have more interrupts to see if I can get it working.
Title: Re: Creating a Built in 4 Score device
Post by: P on October 01, 2021, 10:16:51 am
The game always sees 1 as pressed and 0 unpressed, and my program does nothing to change that. I know that the controllers are using reverse logic for buttons so that 0 means pressed. I'm guessing the I/O hardware in the console is inverting the controller data before the game sees it.

Pretty cool that you almost got it to work though! :)
Title: Re: Creating a Built in 4 Score device
Post by: emerson on October 01, 2021, 02:54:24 pm
I think with some well structured code you could pull this off with no interrupts whatsoever, or a maximum of one if absolutely necessary. All you need is a state machine that tests the latch and two clock pulse inputs and executes only the necessary code based on the active input signal. The code would need to complete all computations and return to the input polling loop before the next signal is expected, and because your design successfully communicates with real hardware means you're already half way there.

If you want some help with a one or no interrupt solution I'd be happy to take a look at your code and give some ideas (either here or PM). With that being said, you are doing what makes sense to you and getting successful results and that's what it's all about. Good work!
Title: Re: Creating a Built in 4 Score device
Post by: P on October 02, 2021, 12:06:42 pm
I'm just worried the microcontroller is fast enough. And since Arduino is used, that means C++ instead of assembly, introducing some overhead.
Title: Re: Creating a Built in 4 Score device
Post by: emerson on October 02, 2021, 02:24:33 pm
Quote from: P on October 02, 2021, 12:06:42 pmI'm just worried the microcontroller is fast enough. And since Arduino is used, that means C++ instead of assembly, introducing some overhead.

I agree. All the more reason for well structured code. In my PS/2 keyboard + mouse to NES adapter I only used one interrupt to reset a timer. This design required the PIC being a middle-man between three separate devices that all provide their own clock signals for data transfer. Certainly more complicated then polling four shift registers. This was done at only 4 MHz and written in XC8 which is a C variant for PIC microcontrollers. If I were to write it again today I would use assembly for sure.

If I could accomplish this with basic specs then the OP should be able to accomplish reading four shift registers using similar specs.
Title: Re: Creating a Built in 4 Score device
Post by: P on October 03, 2021, 01:39:16 pm
Yeah well, no use in dismissing it before it has been tried.
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on October 04, 2021, 09:58:39 am
If all I was working with was one controller, then I could probably get away with a single interrupt.  The issue I'm hitting is that the NES pulses the latch command for about 12 microseconds.  To make sure I caught it I would need to have my code execute, ideally for all four controllers, in less than 12 microseconds so that I could load in controller data and not be writing to the variable as it's being read.

So right now toggle the latch for all four controllers in one go, then read the first bit from each controller. then pulse the clock for all four controllers in one go and read the next bit for each controller.

The entire process takes 0.025 milliseconds or 25 microseconds.  Interestingly, the biggest hold up I've faced is the response speed from the 4201 shift register.  I had my code setting the latch in one clock cycle then unsetting it the next and it was too fast for the 4201 to register.  I had to slow it down and use code that set it in 3 cycles and unset in 3 cycles.  Same with the clock pulse, doing it too fast messed things up.

Even going slower I still have to do a double read of the controller bits to get a good read.

I'm figuring my read time by throwing my code into a for loop and having it execute 3000 times and comparing the time before it started to the time after it started.  Over 3000 loops it takes 72,972 microseconds. 

Now some caveats here, there is some overhead in a for loop (around 0.25 microseconds per loop), and there is just shy of 3 microSeconds overhead associated with the command used to return current micros.  But even if I was as generous as possible I can't get the code to read all 4 controllers under 12 microseconds.

One thing I was thinking about is changing the code to read a single controller at a time and do a latch check after each controller read (One controller read takes 10.9 microseconds).  In theory I could just hold the last read values of a controller and everything *should* be okay.  Maybe a controller press comes in 12 microseconds latter than when you pressed it... but that should only really make a difference if you need to do something frame perfect and if you're doing that then I doubt you'd go through a four-score device either.

Alternatively I could just read all the controllers and then have my code wait for the latch command.  Worst case scenario I miss for cycles reading each controller and then let's say I miss the 5th latch by a moment so every 6th latch pulse I send new controller data and the rest of the time I send "stale" data.  That would mean a button press or release could be delayed by up to 75 microseconds.  And suddenly I'm questioning my quest for immediate responses....
Title: Re: Creating a Built in 4 Score device
Post by: P on October 04, 2021, 02:24:52 pm
12 μs for all controllers, sounds tight.

Yeah I don't think you need to worry about re-reading all controllers multiple times within the same frame. Humans won't notice any changes in that short span of time anyway. 2 frames of input lag is surely noticeable, but they say not even world class speedrunners can detect 1 frame of lag and less.
Title: Re: Creating a Built in 4 Score device
Post by: emerson on October 04, 2021, 05:09:29 pm
Part 1/3

Quote from: lifewithmatthew on October 04, 2021, 09:58:39 amTo make sure I caught it I would need to have my code execute, ideally for all four controllers, in less than 12 microseconds so that I could load in controller data and not be writing to the variable as it's being read.

Does this mean you are attempting to read and store the button states of all four controllers between the latch pulse and first clock pulse from the console to the arduino?

Quote from: lifewithmatthew on October 04, 2021, 09:58:39 amSo right now toggle the latch for all four controllers in one go, then read the first bit from each controller. then pulse the clock for all four controllers in one go and read the next bit for each controller.

This implies you have all four controller clock lines tied to a single output from the arduino, is that correct? I also assume you have all four latch pins of the controllers tied together. Are these tied directly to $4016.OUT0 from the console or are they controlled by an arduino pin?

If the answer to both of these is yes then I can see why you are having timing issues. As you said it's simply too much at once. I can see the logic in taking this approach, but let's break down what we know about how the four score is read and use that to form a state machine.

What we know is:
- every time a latch pulse is received the controllers reset
- $4016.CLK pulses 0-7 read cont_1, pulses 8-15 read cont_3, and pulses 16-23 read sig_1
- $4017.CLK pulses 0-7 read cont_2, pulses 8-15 read cont_4, and pulses 16-23 read sig_2
- sig_1 and sig_2 are always the same value (aka constants)
- the idle state for $4016.OUT0 is low, and idle states for $4016.CLK and $4017.CLK are high

We now have everything we need to know about the four score and we can start designing the code to meet these requirements. First let's look at the latch pulse. Because every controller requires the latch pulse simply tie $4016.OUT0 directly to every controller. We also need the latch pulse to reset our state machine variables so tie the latch signal to an input pin on the arduino as well. Because we know nothing can happen until the latch pulse is received by the four score we can use a while loop to wait for it.

Spoiler
//4016.OUT0 is an input pin
//

while (4016.OUT0 == 0);  //loop while latch_in = 0
   4016_cnt = 0;         //reset $4016.CLK counter
   4017_cnt = 0;         //reset $4017.CLK counter
[close]

That's everything the latch pulse needs to do in code. Again, there is some overhead when programming in C but I imagine a 4MHz to 8MHz system clock should certainly execute this within 12us.
Title: Re: Creating a Built in 4 Score device
Post by: emerson on October 04, 2021, 05:15:01 pm
Part 2/3

Now let's look at the clock and data signals as these work in unison. Trying to cram all 24 controller reads between the latch pulse and first clock pulse would be like trying to execute an entire game engine within vblank. Instead, let's utilize the time we are given between clock pulses to handle only one bit from only one controller. That's how the hardware handles it right?

Tie $4016.CLK and $4017.CLK to inputs on the arduino as these are required to increment their respective clock counter variables. These variables are then used to determine which controller is being queried at that instant and send only that controller a clock pulse. We also expect to receive a bit from the controller once it is clocked. Therefore, each controller has a dedicated clock output and data input. Once all this is done we need to increment the respective clock counter for the next loop iteration.

Repeat this approach for both $4016 and $4017

Spoiler
//4016.CLK, CONT1.D0, CONT3.D0 are input pins
//4016.D0, CONT1.CLK, CONT3.CLK are output pins
//

if (4016.CLK == 0){
   switch (4016_cnt){
      case <= 7:              //cont_1
         CONT1.CLK = 0;       //instead of using a loop counter for a few microseconds just repeat the instruction
CONT1.CLK = 0;       //repeat as needed
CONT1.CLK = 1;       //release clock line
CONT1.CLK = 1;       //if necessary allow time for data to stabilize
4016.D0 = CONT1.D0;  //shift current cont1 button out to console
break;
      case <= 15:             //cont_3
         CONT3.CLK = 0;
CONT3.CLK = 0;
CONT3.CLK = 1;
CONT3.CLK = 1;
4016.D0 = CONT3.D0;  //shift current cont3 button out to console
break;
      case <= 23:   //sig_1
     4016.D0 = 0x01 AND ('0b11101111' >> (23 - 4016_cnt));  //shift signature constant x number of bits by
break;                                                 //subtracting the existing count from the total count
      default:
         4016.D0 = 1;   //additional clock pulses always return 1
         break;
   }
   4016_cnt++;   //increment clock counter by 1
}
[close]

I repeated the same command when clocking to allow enough time for the 4021 to return a bit. It looks goofy but when it compiles to assembly the code will execute faster than a for next loop. If available, the best approach would be to use something like "nop();"
Title: Re: Creating a Built in 4 Score device
Post by: emerson on October 04, 2021, 05:22:00 pm
Part 3/3
Currently once the code is past the latch pulse loop it is expecting clock pulses. Because we know the idle states of all three inputs from the console we can (and should) test them all at once. Simply connect $4016.OUT0, $4016.CLK and $4017.CLK to the same input register on the arduino.

Spoiler
//assume PORTA is an arduino I/O register
//
//PORTA = 0bxxxxx110
//               ||+-- $4016.OUT0, idle low
//               |+--- $4016.CLK, idle high
//               +---- $4017.CLK, idle high
//
//all three are input pins
//

FourScoreEngine:
   while (0x06 = PORTA AND 0x07); //loop until any input is received
      switch (PORTA AND 0x07){
         case 0b00000111:  //latch pulse detected
            4016_cnt = 0;  //reset $4016.CLK counter
            4017_cnt = 0;  //reset $4017.CLK counter
        break;
       
         case 0b00000101;           //4016.CLK pulse detected
            switch (4016_cnt){
            case <= 7:              //cont_1
               CONT1.CLK = 0;       //instead of using a loop counter for a few microseconds just repeat the instruction
      CONT1.CLK = 0;       //repeat as needed
      CONT1.CLK = 1;       //release clock line
      CONT1.CLK = 1;       //if necessary allow time for data to stabilize
      4016.D0 = CONT1.D0;  //shift current cont1 button out to console
      break;
            case <= 15:             //cont_3
               CONT3.CLK = 0;
      CONT3.CLK = 0;
      CONT3.CLK = 1;
      CONT3.CLK = 1;
      4016.D0 = CONT3.D0;  //shift current cont3 button out to console
      break;
            case <= 23:   //sig_1
           4016.D0 = 0x01 AND ('0b11101111' >> (23 - 4016_cnt));  //shift signature constant x number of bits by
      break;                                                 //subtracting the existing count from the total count
            default:
               4016.D0 = 1;   //additional clock pulses always return 1
               break;
            }
            4016_cnt++;   //increment clock counter by 1
        break;
       
         case 0b00000011;           //4017.CLK pulse detected
            switch (4016_cnt){
            case <= 7:              //cont_1
               CONT2.CLK = 0;       //instead of using a loop counter for a few microseconds just repeat the instruction
      CONT2.CLK = 0;       //repeat as needed
      CONT2.CLK = 1;       //release clock line
      CONT2.CLK = 1;       //if necessary allow time for data to stabilize
      4017.D0 = CONT2.D0;  //shift current cont1 button out to console
      break;
            case <= 15:             //cont_3
               CONT4.CLK = 0;
      CONT4.CLK = 0;
      CONT4.CLK = 1;
      CONT4.CLK = 1;
      4017.D0 = CONT4.D0;  //shift current cont3 button out to console
      break;
            case <= 23:   //sig_1
           4017.D0 = 0x01 AND ('0b11110111' >> (23 - 4017_cnt));  //shift signature constant x number of bits by
      break;                                                 //subtracting the existing count from the total count
            default:
               4017.D0 = 1;   //additional clock pulses always return 1
               break;
            }
            4017_cnt++;   //increment clock counter by 1
        break;
       
         default: break;  //do nothing when idle
      }
   goto FourScoreEngine;  //loop forever
[close]

A total of 2 variables and 13 I/O pins are required for this solution (1 latch input, 2 clock inputs, 4 clock outputs, 4 data inputs, 2 data outputs).
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on October 05, 2021, 08:29:50 am
Quote from: emerson on October 04, 2021, 05:09:29 pmPart 1/3

Quote from: lifewithmatthew on October 04, 2021, 09:58:39 amTo make sure I caught it I would need to have my code execute, ideally for all four controllers, in less than 12 microseconds so that I could load in controller data and not be writing to the variable as it's being read.

Does this mean you are attempting to read and store the button states of all four controllers between the latch pulse and first clock pulse from the console to the arduino?


Oh my no, lol.  I did word that poorly, I was saying if I only used one interrupt I would be worried about needing to execute all my code for the controller reads in less than 12 ms. 
 
Quote from: emerson on October 04, 2021, 05:09:29 pm
Quote from: lifewithmatthew on October 04, 2021, 09:58:39 amSo right now toggle the latch for all four controllers in one go, then read the first bit from each controller. then pulse the clock for all four controllers in one go and read the next bit for each controller.

This implies you have all four controller clock lines tied to a single output from the arduino, is that correct? I also assume you have all four latch pins of the controllers tied together. Are these tied directly to $4016.OUT0 from the console or are they controlled by an arduino pin?

Yes, I have all four controller clock lines tied to a single output on the arduino and all four latch pins tied to a different pin.  The four score ties all the latch pins together, but has dedicated clock pins for each controller.  My current method for reading it was to send the latch, then read the PORTC, then send clock pulse and read PORTC, rinse and repeat until I had all 8 bits.  Since all my data lines are on PORTC, I can read all four controllers in one go and then write out the appropriate bits to my controller variables.

However, I think you came up with a very interesting code concept.  I have some minor concerns about getting the timing down for sending my latch and clock pulses based on my experience so far, but it's definitely worth the go!  I'll try and test it out today if possible :)
Title: Re: Creating a Built in 4 Score device
Post by: emerson on October 05, 2021, 10:17:47 am
If you think about it, the controllers already contain the data you need so there is no reason to store that data in variables. This will save lots of time. The console only expects one bit from whichever controller port it is querying so that is all you really need to provide within one clock pulse period.

The main idea is not to assume what signal is coming next but rather structure your code to handle any signal at any program loop iteration.

I forget if you said before but what clock speed are you running your microcontroller at? This is your biggest bottleneck.
Title: Re: Creating a Built in 4 Score device
Post by: P on October 05, 2021, 10:49:55 am
Quote from: lifewithmatthew on October 05, 2021, 08:29:50 amYes, I have all four controller clock lines tied to a single output on the arduino and all four latch pins tied to a different pin.  The four score ties all the latch pins together, but has dedicated clock pins for each controller.
There is only a single latch signal coming from the console so having them separate wouldn't do anything. There are two different clocks though, $4016.CLK and $4017.CLK.
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on October 06, 2021, 10:02:17 am
Quote from: P on October 05, 2021, 10:49:55 am
Quote from: lifewithmatthew on October 05, 2021, 08:29:50 amYes, I have all four controller clock lines tied to a single output on the arduino and all four latch pins tied to a different pin.  The four score ties all the latch pins together, but has dedicated clock pins for each controller.
There is only a single latch signal coming from the console so having them separate wouldn't do anything. There are two different clocks though, $4016.CLK and $4017.CLK.

I know, and I use the two different clocks to handle writing data to the NES, but in terms of me first reading that data, to store it, it doesn't necessarily matter if I split it up or use a single clock pulse and then read the bits into my variables.

So I tested out the code last night and just as I was concerned, the timing doesn't work out.  In fact, after I tried it for a bit, I tried reducing things down to the bare minimum where I used a single controller and made my latch out equal the latch input from the NES, my clock output equal the clock input from the NES and made my data output equal the data input from the controller and it still failed.


Cont1.Latch = PORTA & 0x01
Cont1.CLK = PORTA & 0x02
4016.D0 = Cont1.D0


The timing is the hold up.  By the time I pulse the clock the NES has already read the stale value being written out even though it was a mere 6ish clock cycles later at most.  (My microcontroller is running at 16 MHz). 

I think you still have a good idea here by minimizing the code I think I can find the happy medium of pre-reading the the controller data and getting the status of the latch without having to dedicate an interrupt to it.  Then I can use the rising edge of the interrupt to write the next value such that at the falling edge the NES reads the correct value and I preload the next variable to be written.

And part of that optimization will be giving each controller its own clock pulse.  I had started off that way, but condensed it down by the time I got to the code that works.  And I do have it working, I just think it should be feasible to do it with a single microcontroller if I did things more cleanly.
Title: Re: Creating a Built in 4 Score device
Post by: emerson on October 06, 2021, 03:58:06 pm
For those three lines of code, if you manually assert the latch and clock inputs does the data output work as expected? 16MHz is plenty fast enough and possibly even overkill. Assuming one clock per instruction that's 62.5ns per instruction. Assuming each of those three lines compiles into two lines of assembly code that would still only be (2 x 3) * (62.5*10-9) = 375ns

This could possibly be a setup configuration issue and not a timing issue.

When things fail this poorly (no offense) I start from the beginning. Check your configuration fuses and initialization code. Make sure the chip is configured exactly as needed. Unless you need them disable things like watchdog timers and make sure your clock source is set to internal or external and at the appropriate rate. Also make sure whatever programming software you're using is pulling the configuration fuses from your hex file and not the software defaults. The software should allow you to read the config fuses off the chip so if you can test that to make sure they are correct.

In my code I like to force all unused peripheral features to their disabled condition regardless of their default power-up state. I will scroll through the entire datasheet and disable what I don't need in the order that it appears in the datasheet. Then below that I enable the peripherals I need. You only need basic I/O function so all peripherals should be disabled. Be sure to disable all interrupts as well.

Once you believe the chip is properly configured put a small loop just after your config setup. Have this loop toggle the state of an output pin and test with an oscilloscope. If you see a square wave with the expected period then you know the chip is alive. It will not be the same as your clock speed. At this point you can test all I/O pins if you like.
while (1){
   PORTA.D0 = PORTA.D0 XOR 0x01;
}

Once you are confident the chip is properly initialized then start debugging the code. I don't have a fancy in circuit debugger so I take an unused I/O pin and set it as an output with an LED. Then I will insert a line of code that lights the LED and halts in a loop to test if the code executed that far. If the LED doesn't light up then you know the problem lies just before that loop. This simple trick has helped me debug countless projects.
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on October 07, 2021, 11:24:47 am
Quote from: emerson on October 06, 2021, 03:58:06 pmFor those three lines of code, if you manually assert the latch and clock inputs does the data output work as expected?

So I think I may have done some miscommunication at some point here.  I have a version of the code that 100% works (I've tested it against Monopoly and RC PRO AM II).  The reason I tried changing things up is I think you had a *very* cleaver idea to get is scaled down to one microcontroller instead of using 2 microcontrollers like I currently have to.  I can confirm that I can easily read the controller data into the microcontroller with zero issues.  I can also confirm that I have learned the correct way to get that data back out of it to the NES.

The issue with trying to fully implement the code you suggested is with getting the timing worked out with the NES.  The moment the controller clock goes low, the NES has already read the value and moved on in its code.  Even if I got it out 62.2 ns later, it's still too late as far as the NES is concerned.  As a result, I have to have the data the NES is wanting to see queued up and ready to go on the rising edge of the clock pulse.

Now maybe there could be a way to always be one clock pulse ahead of the NES.  Maybe if on the rising edge of the latch pulse from the NES I sent the latch pulse to the controller, and read the first bit (the "A" button status) and output that status onto the data line then read the next bit such that on the rising edge of the clock pulse from the NES I could load in the next bit (the "B" button status), but that's creating a lot of work to do on the rising edge of the latch and I don't see it as strictly gaining any usefulness compared to how I have it working currently.

In terms of using one microcontroller with 3 interrupts, I think that's an issue with the ATMEGA 4809 I've been testing with.  It says that any pin can be an interrupt, but I suspect that it's not using true hardware interrupts.  When I use the exact same code that works for one pair of controllers and combine it with all 4 controllers, everything just goes haywire.  And I'm keeping the interrupts very small.  At most the interrupt take 10 instructions to finish, that is short enough to easily execute before the next interrupt would fire. 

I think that if I used a different microcontroller I might be able to get away with a single microcontroller.  I thought about trying this out with an ESP32, but it operates at 3v3 and I would have had to buy some additional level shifters to see if it *might* work, so I decided to pass on that for now.

For my testing methods I've gone about this with three boards, all of them were ATMEGAs the 328, 5206, and 4809. As I've jumped around between the three of them with different ideas I've started from the ground up many times, but my testing remains more or less the same.

I confirm that I'm getting accurate data from the controller to the microcontroller.  I confirm that I can send out a specific set of controller presses by hard coding my output with a given number (254 means A is pressed, 253 means B is pressed, 252 is A and B, etc) and that those presses are correctly read by the NES using the excellent testing program provided (seriously thank you, P, without that program this project would have been dead before it started). Then I combine it to get the controller to the NES debugging as necessary.

From this testing and looking up information online from people who have tested the timings with oscilloscopes, I've made the following observation the following about the NES reading process and how it relates to the four score.  I've tested this by testing when interrupts occur, counting how many pulses happen between latches, and testing what combinations actually occur between the latch and clock pins.


Hopefully this information helps anyone else who wants to DIY a solution.  I still plan on implementing a turbo feature as well as using a switch circuit to direct player's 3/4 data to 4016.D1 / 4017.D1, but that's going to have to be tested later on.
Title: Re: Creating a Built in 4 Score device
Post by: emerson on October 07, 2021, 04:27:49 pm
Quote from: lifewithmatthew on October 07, 2021, 11:24:47 amSo I think I may have done some miscommunication at some point here.

No this was my bad. After my post from yesterday I re-read yours and realized I did not fully read what you wrote. My apologies.

Quote from: lifewithmatthew on October 07, 2021, 11:24:47 amThe issue with trying to fully implement the code you suggested is with getting the timing worked out with the NES.  The moment the controller clock goes low, the NES has already read the value and moved on in its code.  Even if I got it out 62.2 ns later, it's still too late as far as the NES is concerned.  As a result, I have to have the data the NES is wanting to see queued up and ready to go on the rising edge of the clock pulse.

The latch portion was not handled correctly in my sample code. As soon as the 4021 receives the latch pulse it loads Q7 with the data on D7. Once the 4021 receives the first clock pulse it pushes D6 out to Q7, and the process repeats for 8 clocks total. My latch code should look like this.

case 0b00000111:  //latch pulse detected
   4016_cnt = 0;  //reset $4016.CLK counter
   4017_cnt = 0;  //reset $4017.CLK counter
   //possible delays needed here
   4016.D0 = CONT1.D0;
   4017.D0 = CONT2.D0;
break;

I disagree with some of the statements on the clock timings. The below image is of an oscilloscope capture of single clock pulse being sent to the controller. Note how small the low portion of the duty cycle is. It's more like 5% low and not 50%. Also note the frequency is about 64kHz and not 83kHz.

You cannot see attachments on this board.

Here is the same setup but with controller 1 connected through my four score in 4 player mode (still SMB1). The waveform is different but no significant difference in timing.

You cannot see attachments on this board.

If you would like me to do some hardware testing and get scope captures for you I would be happy to do what I can.
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on October 07, 2021, 09:29:48 pm
Quote from: emerson on October 07, 2021, 04:27:49 pm
Quote from: lifewithmatthew on October 07, 2021, 11:24:47 amSo I think I may have done some miscommunication at some point here.

No this was my bad. After my post from yesterday I re-read yours and realized I did not fully read what you wrote. My apologies.

No need to apologize, you've been extremely helpful :D

Quote from: emerson on October 07, 2021, 04:27:49 pmThe latch portion was not handled correctly in my sample code. As soon as the 4021 receives the latch pulse it loads Q7 with the data on D7. Once the 4021 receives the first clock pulse it pushes D6 out to Q7, and the process repeats for 8 clocks total. My latch code should look like this.

case 0b00000111:  //latch pulse detected
   4016_cnt = 0;  //reset $4016.CLK counter
   4017_cnt = 0;  //reset $4017.CLK counter
   //possible delays needed here
   4016.D0 = CONT1.D0;
   4017.D0 = CONT2.D0;
break;

Yeah, I had caught that and fixed it during testing.  The way you implemented a switch was extremely helpful in helping me figure out what conditions exist and never occur with the latch and clock pulses.  Specifically if we assume controller 1 clock, controller 2 clock, and latch are the lower 3 bits the following conditions are true:


Quote from: emerson on October 07, 2021, 04:27:49 pmI disagree with some of the statements on the clock timings. The below image is of an oscilloscope capture of single clock pulse being sent to the controller.

Very interesting.  I personally do not have an oscilloscope.  I relied on the following two pages for others who have used the scopes to examine pulse timings.
https://hackaday.io/project/170365-blueretro/log/181368-famicom-nes-controller-shift-register-parallel-in-serial-out
https://forums.nesdev.org/viewtopic.php?p=239781&sid=76e116fe248bf4a8458aacc4bf9870b2#p239781

I have no idea why the pulses are different.

I do like how many ways there are to replicate this though.  I do think that a part of the timing issue has to do with some quirks with the ATmega chips and would be interested in how a PIC would handle it.  While my personal belief is the more data the better, I've reached a solutions that I am... begrudgingly satisfied with for the moment.  I could try some more stuff with the ATMega5206.  It definitely has enough confirmed hardware interrupts, but one 5206 costs around 9 bucks whereas a 328 costs a buck fifty to 2 dollars.  Even if you count the extra cost from some power filtering components it's still a lot cheaper to just use two 328 chips that work.

I'm sure some day I'll break down and get some level shifters to test out with the ESP32.  That thing runs faster AND has 2 cores to work with... I might go to amazon right now, lol.  I wonder if the 4201 shift registers could run off 3v3....
Title: Re: Creating a Built in 4 Score device
Post by: emerson on October 08, 2021, 05:05:31 pm
Quote from: lifewithmatthew on October 07, 2021, 09:29:48 pmI do think that a part of the timing issue has to do with some quirks with the ATmega chips and would be interested in how a PIC would handle it.

So I took the time last evening and tried this for myself. Would you believe me if I said it didn't work, haha! The problem I am seeing is the loop that polls the three inputs. This must compile to some length of code that executes longer than the ~580ns low period of the clock pulse. I also found that when the clock is recognized, my switch case approach will finish executing before the next clock is received!

Here is a scope capture and the code modification to allow me to measure code execution time. Note how the pink pulses fit within the clock duration but are only triggered every other iteration. The extra pulses on D0 are from SMB1 polling $4017.
FourScoreEngine:
    D0_4016 = 0;                    //output is cleared at loop restart
    while (0x06 == (PORTB & 0x06)); //loop until any input is received
    D0_4016 = 1;                    //output is set for duration of code execution
    switch (PORTB & 0x07){
    //rest of the code as usual from here

You cannot see attachments on this board.

I found this interesting. I fired up my PowerPak and the boot screen polls the controllers at a rate of ~90kHz. Fortunately the low duty timing remains around ~580ns and only the high duty time changes. The scope capture below is one of the better responses from my circuit in terms of trigger quantity, and the code still executes fast enough at 90kHz.

You cannot see attachments on this board.

I will agree at this point that if programming in C, interrupts are probably required. I wrote up a potential solution in assembly during lunchtime at work today. The entire input polling loop takes only 437.5ns at 16MHz. Theoretically a clock pulse should never be missed at this rate. I did not count clocks for every possible execution route but I did label the required cycles. The biggest problem I see the lack of shadow registers. Below is my assembly code, written in mpasm.

Spoiler
;wreg is the working register, just like an accumulator
;
;clock period is:
; 1/16,000,000 = 62.5ns
;
;Loop movf to movf is:
; 1+1+1+1+2+1 = 7 cycles
;
;Loop execution time is:
; 7*62.5ns = 437.5ns

cblock 0x20 ;declare variables
x
cnt_4016
cnt_4017
sig1
sig2
endc

Loop: ;cycles
movf PORTB,0 ;1 load PORTB into wreg
andlw 0x07,0 ;1 isolate latch and clock inputs, store in wreg
xorlw 0x06,0 ;1 if inputs are idle then result is zero
btfsc STATUS,Z ;1,2 test zero flag and skip if an input is not idle
goto Loop ;2 repeat until an input changes

;if WREG can be used instead of x then code can be simplified

movwf x ;1 save the non-idle state of inputs
rrf x,1 ;1 rotate latch bit into carry, store remainder in x
btfsc STATUS,C ;1,2 test if latch bit is high
goto LatchHandler ;2 if yes then handle latch pulse
rrf x,1 ;1 rtoate 4016 clock into carry, store remainder in x
btfsc STATUS,C ;1,2 skip if 4016 clock is active
goto Cont24Handler ;2 run if carry is set
goto Cont13Handler ;2 run if carry is clear

LatchHandler:
movf D0_Cont1,0 ;1 shift cont1 d7 to console
movwf D0_4016 ;1
movf D0_Cont2,0 ;1 shift cont2 d7 to console
movwf D0_4017 ;1
clrf cnt_4016 ;1 clear controller clock counters
clrf cnt_4017 ;1
movlw 0xf7 ;1 reset sig1 0b11110111
movwf sig1 ;1
movlw 0xfb ;1 reset sig2 0b11111011
movwf sig2 ;1
goto Loop ;2

Cont13Handler:
movf cnt_4016,0 ;1 load clock counter
andlw 0x18,0 ;1 isolate count bits 8 and 16
btfsc STATUS,Z ;1 if less than 8 clocks have occured
goto ReadCont1 ;2 then read cont1
xorlw 0x18,0 ;1 toggle remaining bits
btfsc STATUS,Z ;1,2 if the result is zero then everything has already been sent
goto NullData ;2 so send null data
andlw 0x08,0 ;1 test the remaining bits, but remember they are now inverted
btfsc STATUS,Z ;1,2 if the result is zero, less than 16 clocks have occured so read cont3
goto ReadSig1 ;2 otherwise read signature

;continue to cont3 code below

bcf clk_cont3 ;1 send clock pulse to controller
nop ;1 and allow some time for controller to process
bsf clk_cont3 ;1
movf D0_Cont3 ;1 shift controller data to console
movwf D0_4016 ;1
incf cnt_4016 ;1 increment controller counter
goto Loop ;2

ReadCont1:
bcf clk_cont1 ;1 send clock pulse to controller
nop ;1 and allow some time for controller to process
bsf clk_cont1 ;1
movf D0_Cont1 ;1 shift controller data to console
movwf D0_4016 ;1
incf cnt_4016 ;1 increment controller counter
goto Loop ;2

NullData13:
setf D0_4016 ;1 this might not be the correct way to do this
goto Loop ;2

ReadSig1:
movf sig1,0 ;1 mov sig1 into wreg
andlw 0x01 ;1 isolate LSB
movwf D0_4016 ;1 shift data to console
incf cnt_4016 ;1 increment clock counter
goto Loop ;2



Cont24Handler:
movf cnt_4017,0 ;1 load clock counter
andlw 0x18,0 ;1 isolate count bits 8 and 16
btfsc STATUS,Z ;1 if less than 8 clocks have occured
goto ReadCont2 ;2 then read cont1
xorlw 0x18,0 ;1 toggle remaining bits
btfsc STATUS,Z ;1,2 if the result is zero then everything has already been sent
goto NullData ;2 so send null data
andlw 0x08,0 ;1 test the remaining bits, but remember they are now inverted
btfsc STATUS,Z ;1,2 if the result is zero, less than 16 clocks have occured so read cont3
goto ReadSig2 ;2 otherwise read signature

;continue to cont4 code below

bcf clk_cont4 ;1 send clock pulse to controller
nop ;1 and allow some time for controller to process
bsf clk_cont4 ;1
movf D0_Cont4 ;1 shift controller data to console
movwf D0_4017 ;1
incf cnt_4017 ;1 increment controller counter
goto Loop ;2

ReadCont2:
bcf clk_cont2 ;1 send clock pulse to controller
nop ;1 and allow some time for controller to process
bsf clk_cont2 ;1
movf D0_Cont2 ;1 shift controller data to console
movwf D0_4017 ;1
incf cnt_4017 ;1 increment controller counter
goto Loop ;2

NullData24:
setf D0_4017 ;1 this might not be the correct way to do this
goto Loop ;2

ReadSig2:
movf sig2,0 ;1 mov sig1 into wreg
andlw 0x01 ;1 isolate LSB
movwf D0_4017 ;1 shift data to console
incf cnt_4017 ;1 increment clock counter
goto Loop ;2
[close]

I may test this over the weekend after I tinker with my (many) other projects.
Title: Re: Creating a Built in 4 Score device
Post by: P on October 08, 2021, 05:28:12 pm
The 4000-series are CMOS so they are low-power and have a wide voltage range (something like 3-15 V I think).
It's nice to see that you got it to work!


Quote from: lifewithmatthew on October 07, 2021, 11:24:47 amI confirm that I'm getting accurate data from the controller to the microcontroller.  I confirm that I can send out a specific set of controller presses by hard coding my output with a given number (254 means A is pressed, 253 means B is pressed, 252 is A and B, etc) and that those presses are correctly read by the NES using the excellent testing program provided (seriously thank you, P, without that program this project would have been dead before it started).
I'm just glad that my little experiments came to use. It should be said that my program has a little bug that I was unable to locate: if B is pressed the SELECT indicator on the same controller won't update for some reason.


Oh and by the way about alternating clock pulses, this of course depends on the game. A game only using one controller might only clock $4016. It would be a silly way to read more controllers but of course it is possible to read all controllers without alternating the pulses by latching multiple times (my program actually latches twice per frame, once for the signature and once for the buttons, it's not very effective but my program is way too small to cause any slowdown so I didn't really worry about that). Not sure if that matters for this multitap project, I just want to make it clear.
Title: Re: Creating a Built in 4 Score device
Post by: WooCash on October 31, 2021, 02:41:47 am
Hello everyone! I am looking for a way to use Four Score PAL with Japanese and European games. My knowledge of electronics is very basic, but maybe the information I found will be useful to you.

A Polish fan of Pegasus (Famiclone) made a PCB acting as a HORI 4 Player Adaptor and Four Score adapter. Everything is based on EPM3064A. Picture of the PCB and link to the original topic. Krzysiobal did not share the code but he is also on this forum under nick krzy. Maybe he would share some information with the community.
http://archive.nes.science/nesdev-forums/f9/t18747.xhtml

Japanese Famicom fan Takuya Matsubar made a working HORI clone on the Arduino. Provides code and PCB.
https://sites.google.com/site/yugenkaisyanico/diy_fc_multitap
https://github.com/nicotakuya/diyfcmultitap

Cluster from Russia made a 2 in 1 adapter. 4 players adapter and arkanoid controller. He published the complete code for FPGA.
https://clusterrr.com/dendy-accessories/
https://pastebin.com/nt39ZGvH
Title: Re: Creating a Built in 4 Score device
Post by: lifewithmatthew on December 07, 2021, 02:09:59 pm
Quote from: P on September 18, 2021, 03:22:28 pmIf you build a Four-Score you need to make sure the signature is wired or games won't detect it as connected.
I made a test program for both the Four-Score and Famicom expansion controllers (the "Simple" method in the wiki). I've yet to add Hori's Famicom multitap though.
Hey P, I have a question about the rom you made for controller testing.

Since the last post, I learned to use PIC microcontrollers and have it all working with a single microcontroller.  4 players using the four score method works, 2 players works, turbo buttons work AND I have them all working through the expansion port on the bottom.

The last thing I want to do is get a "simple" mode working for four players.  The expansion port exposes $4016.D1 and $4017.D1 that I can use to write data to.  Do they shift the bits along with controller 1 and 2 or do they use a separate clock pulse?
Title: Re: Creating a Built in 4 Score device
Post by: P on December 07, 2021, 03:11:10 pm
Interesting, I'm more familiar with PIC than AVR myself (I've only used AVR with Arduino), what model did you use?

To answer your question, they do shift when controller 1 and 2 shifts respectively. There are just two clocks, the $4016 CLK and the $4017 CLK. So in summary the program does something like this:

1) Pulse $4016.
2) Read controller 1 ($4016.D0).
3) Read controller 3 ($4016.D1).
4) Pulse $4017.
5) Read controller 2 ($4017.D0).
6) Read controller 4 ($4017.D1).
7) First bit done, repeat 1 to 6 again until all 8 bits are read.


BTW I noticed that Nesdev is up again. Finally!
Title: Re: Creating a Built in 4 Score device
Post by: Akerasoft on January 02, 2022, 09:43:37 pm
I created a 4 player adapter that is compatible with Four Score.
It is not tested yet because I don't have all of the electronic parts yet.

https://github.com/Akerasoft/openfourplayer168

This is done in assembly language for speed.
It uses ATMEGA168P but probably should work on ATMEGA328P which is on Arduino Uno R3.

Due to the assembly language it might not work on Arduino.
You can still load it with an ICSP programmer, but it will likely erase the boot loader.
So just buying the chips and making a board is the way to go.

After complete, I plan on doing so myself also.

avr-gcc is complaining about my jmp statements so I'm not sure if it is assembling correctly.

Also it uses 3 interrupts.
2 standard interrupts (INT0 and INT1).
1 extra interrupt by using pin change interrupt and only enabling 1 pin.

I have a potentially slower C++ version for Teensy 2.0 but don't have the Micro USB cable to program it.
It uses INT0/INT1 and INT6.  The catch is Teensy 2.0 has an INT6 pin on it.  With an upgrade to Arduino Teensy 2.0 is supported.

It could be rewritten for avr-gcc/c++ but then it cannot be run on Arduino and also needs to be programmed with ICSP programmer.
In avr-gcc/C++ the 3 interrupt trick can be used.

I have programming experience in MS-DOS assembly and .Net Framework.  This is my first attempt making a usable project for ATMEGA168/ATMEGA328.

So I don't know arv-gcc very well and the assembler that it comes with.
If it turns out that the code does not compile or the warnings are very bad, I would greatly appreciate help with GCC.

I used the Programmer's Notepad that was included in the WinAVR project:
http://winavr.sourceforge.net/
Makefile is included.  As long as the full WinAVR or the avr-gcc compiler stack is in your path you should be able to build.
Title: Re: Creating a Built in 4 Score device
Post by: muramasa on January 08, 2022, 01:22:27 am
Quote from: Akerasoft on January 02, 2022, 09:43:37 pmI created a 4 player adapter that is compatible with Four Score.
It is not tested yet because I don't have all of the electronic parts yet.

I'm really glad you shared this and am hoping to give this a whirl.
Title: Re: Creating a Built in 4 Score device
Post by: Akerasoft on April 08, 2023, 09:52:16 am
After researching and experimenting.  I have found that the version that uses interrupts is too slow.
The solution requires reading the 4 NES Controllers using polling and then outputting to serial to parallel registers and connecting those to parallel to serial registers.  That is the best way with an ATMEGA168/328.
With a larger chip with more pins, the serial to parallel registers are not required.