Reading cart with a microcontroller

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Reading cart with a microcontroller
by on (#112684)
Building off of this project, I've built myself a cart-slot interface, and now I'm trying to write the software to talk to the cart. For now, I'm just dealing with non-coprocessor games. My current code is just returning all 0xFF for the entire 16MB address space. I've checked all of my wiring, as well as the pin assignments in software. I'm assuming that a read operation consists of the following steps:

-Set address (with /CART and /RD high)
-Pull /CART low
-Pull /RD low
-Read data
-Pull /CART and /RD high

Here is the interface I've built, the only difference being that all I had on hand were '573 octal latches, instead of the D-flip flops. I wrote my code such that it should work for either ('574s are posedge-triggered, '573s are active-low latched, so once the address is set, I pull the clk/latch line high, then low). All of the ALL_CAPS_NAMES are pin assignment #defines.

Code:
void Init()
{
  // Address lines as outputs, init to 0x00
  ADDR_DDR_0 = 0xFF;
  ADDR_DDR_1 = 0xFF;
 
  ADDR_PORT_0 = 0x00;
  ADDR_PORT_1 = 0x00;
 
  // Init address latches to 0x00 and enable their outputs
  delayMicroseconds(1);
 
  LATCH_PORT |= (ADDR2_BIT | BANK_BIT | EX_BANK_BIT);
 
  delayMicroseconds(1);
 
  LATCH_PORT &= ~(ADDR2_BIT | BANK_BIT | EX_BANK_BIT | LATCH_OE_BIT);
 
  // Data line defaults to input (read mode)
  DATA_DDR   = 0x00;
 
  // Enable pull-up to keep data line from floating
  DATA_PORT  = 0xFF;
 
  // Control lines as outputs, pulled high
  CONTROL_PORT |= (CART_BIT | RD_BIT | WR_BIT | RST_BIT);
}


uint8_t ReadByte(uint16_t address)
{
  // Set data line as input, pulled high
  DATA_DDR   = 0x00;
  DATA_PORT  = 0xFF;
 
  // Pull all control lines high
  CONTROL_PORT |= (CART_BIT | RD_BIT | WR_BIT);
 
  // Set up address
  ADDR_PORT_0 = address & 0xFF;
  ADDR_PORT_1 = (address >> 8) & 0xFF;
 
  delayMicroseconds(1);
 
  LATCH_PORT |= ADDR2_BIT;
 
  delayMicroseconds(1);
 
  LATCH_PORT &= ~ADDR2_BIT;
 
  // Pull CS low, then OE low
  CONTROL_PORT &= ~CART_BIT;
  CONTROL_PORT &= ~RD_BIT;

  delayMicroseconds(1);
 
  // Read data
  uint8_t data = DATA_PIN;
 
  // Pull all control lines high
  CONTROL_PORT |= (CART_BIT | RD_BIT);
 
  return data;
}


Any ideas what I'm doing wrong?
Re: Reading cart with a microcontroller
by on (#112687)
I wouldn't expect you to see 0xFF everywhere, but you shouldn't be pulling up the data lines while you're trying to read them. It's really not a problem for the data lines to be floating from one read to another. That's what the SNES is doing anyways. So I'd start by disabling pull-ups during reads.

Assuming that doesn't fix it there is a pretty easy way to figure out why a chip isn't giving you data when you expect it to. Put an infinite loop in your code at the time you're trying to read data (preferably a byte you know isn't 0xFF). So your reader will 'jam' in the middle of the read, that will allow you to probe around with a DMM or LED test light and look at all the control signals and address signals and find the one(s) that aren't the value you expect and use that to troubleshoot where your bug is.
Re: Reading cart with a microcontroller
by on (#112697)
Herp derp, never set the LATCH_DDR or CONTROL_DDR to output... the pause-and-probe method with the DMM helped figure it out, thanks :)