Found a very good use for the A15 signal on the expansion port. I'm using it in conjunction with one of the 3 $4016 latch bits & Joy2Strobe to write a full byte of data to the expansion port WITHOUT using any signals from the cart.
The basic idea is this...
- One of the latch bits (I'm using b1) is used as a R/W flag to the peripheral. If it's low, you're doing a normal read from $4017. If it's high, you want to write.
- A buffer on the expansion port device latches the PRG bus when A15 goes low.
- When Joy2Strobe ($4017 read) goes low, the peripheral accepts the last byte in the buffer as input.
There are a couple caveats. ..
- You pretty much have to use a programmable logic device due to the number of discrete logic chips this setup would require.
- A peripheral and the second controller port could not be used at the same time. I'm sure there is a way to detect the presence of a device on the controller port and disable the peripheral, though.
- The code performing the write must be executed from $8000-$FFFF. You can't load code to, say, $6000-$7FFF and execute it from there.
Good news is that any cart can talk to a device on the expansion port without doing serial writes. No more need to send /CE and R/W signals down the Cart-EXP pins!
I've been running a test transfer for about an hour now without any hiccups. For those who are curious, I'm using a Xilinx XC9572XL-VQ44 because it has 5v tolerant inputs. That and it's the largest one I could find that would still fit on a PCB plugged into the EXP port. All but about 5 pins are used...
- 8 pins NES PRG Bus
- 5 pins NES Joy2In bits
- 1 pin NES Joy2Strobe
- 1 pin NES A15
- 8 pins PIC32 data bus
- 1 pin CPLD to PIC INT0
- 1 pin CPLD to PIC R/W
- 1 pin PIC to CPLD /CE
- 1 pin PIC to CPLD R/W
The basic idea is this...
- One of the latch bits (I'm using b1) is used as a R/W flag to the peripheral. If it's low, you're doing a normal read from $4017. If it's high, you want to write.
- A buffer on the expansion port device latches the PRG bus when A15 goes low.
- When Joy2Strobe ($4017 read) goes low, the peripheral accepts the last byte in the buffer as input.
There are a couple caveats. ..
- You pretty much have to use a programmable logic device due to the number of discrete logic chips this setup would require.
- A peripheral and the second controller port could not be used at the same time. I'm sure there is a way to detect the presence of a device on the controller port and disable the peripheral, though.
- The code performing the write must be executed from $8000-$FFFF. You can't load code to, say, $6000-$7FFF and execute it from there.
Good news is that any cart can talk to a device on the expansion port without doing serial writes. No more need to send /CE and R/W signals down the Cart-EXP pins!
Code:
// Read a byte from Joy2 port and put it in scratchVar (normal read)
lda $4017
sta scratchVar
// Set Latch.b1 High to tell the peripheral we want to write
lda #%00000010
sta $4016
// Load a byte from an address under $8000 (we'll read the WRAM)
lda $6000
// Trigger the Joy2 strobe; this tell the peripheral to output since b1 is High
lda $4017
// Set Latch.b1 back to Low
lda #%00000000
sta $4016
lda $4017
sta scratchVar
// Set Latch.b1 High to tell the peripheral we want to write
lda #%00000010
sta $4016
// Load a byte from an address under $8000 (we'll read the WRAM)
lda $6000
// Trigger the Joy2 strobe; this tell the peripheral to output since b1 is High
lda $4017
// Set Latch.b1 back to Low
lda #%00000000
sta $4016
I've been running a test transfer for about an hour now without any hiccups. For those who are curious, I'm using a Xilinx XC9572XL-VQ44 because it has 5v tolerant inputs. That and it's the largest one I could find that would still fit on a PCB plugged into the EXP port. All but about 5 pins are used...
- 8 pins NES PRG Bus
- 5 pins NES Joy2In bits
- 1 pin NES Joy2Strobe
- 1 pin NES A15
- 8 pins PIC32 data bus
- 1 pin CPLD to PIC INT0
- 1 pin CPLD to PIC R/W
- 1 pin PIC to CPLD /CE
- 1 pin PIC to CPLD R/W