problems with Using the Arduino as ROM

Instead of using an Ardunio to Program an EEPROM i thought why not use the Arduino as ROM itself?

So i made this small code to use my Arduino 2560 as potential 64kB ROM. in this small program i only used 16B though.

int ROM[16] = {0x00, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
word Address;
int Prev;
int Current;

void setup() {
  DDRA = 0x00;                        //Pins 22-29 (lower 8b of Address Input) 22 = 0, > 29 = 7
  DDRC = 0x00;                        //Pins 30-37 (upper 8b of Address Input) 37 = 0, < 30 = 7
  DDRL = 0xFF;                        //Pins 42-49 (8b Data Output)            49 = 0, > 42 = 7
  Prev = 0xFF;
  Address = 0x0000;
  Serial.begin(500000);

}

void loop() {
    Address = word(PINC,PINA);        //Combines PORTC and PORTA into a single 16b Value
    PORTL = ROM[Address];             //Reads from the ROM Array and puts it onto the Data Output
    
    Current = Address;
    if(Prev != Current){              //If the Address from one cycle beofre is the same as the Current one it will not print anything on the Serial Monitor. to keep it clean
      if (PORTL < 0x10 ) {
        Serial.print("$0");
      }
      else{
        Serial.print("$");
      };
      Serial.print(PORTL, HEX);       //Prints the Data on the current Address as HEX with leading 0.
      Serial.print("    ");
        if (Address < 0x0010 ) {
          Serial.print("$000");
          goto EOSP;
        };
        if (Address < 0x0100 ) {
          Serial.print("$00");
          goto EOSP;
       };
       if (Address < 0x1000 ) {
         Serial.print("$0");
         goto EOSP;
       }
       else{
         Serial.print("$");
       };
      EOSP:
      Serial.print(Address, HEX);     //Prints the Currently accessed Address as HEX with leading 0s.
      Serial.println();
      Prev = Current;                 //Sets the used Address as the "previous" one, so it can be compared next cycle.
      };
}

now al lthis code does is that it takes a usermade Array as Storage, and if anything accesses some Address it will present the Data on that Address to the output. it also shows the currently accessed address and Data on it over the Serial Monitor.

The problem with it is that it doesn't appear to be working on a Hardware level. The Program itself works fine i can see what data is there on the Monitor and on my connected LEDs, but the CPU i wanted to test this with doesn't appear to be getting the Data correctly

I'm trying to test a Z80 CPU with this, so as seen in the code i made a single Program that looks like this:

NOP
NOP
NOP
NOP
JP, $0000
HALT

usually this would make the CPU just jump to the first address over and over again. but it doesn't work. the CPU starts to access data very weirdly.
here is the log of the Serial Monitor while i was wirting this.

PASTEBIN

This confuses me greatly and i have no idea why this is a thing.

and i couldn't think of anything that i pinned wrong. i mean you are supposed to pull down/up input and output pins right? like every single pin (even the clock) has a Resitor to either pull it high or low.

Doesn’t your z80 program have to do something with the data after it’s jumped to 0000, like LDA , etc ? With your z80 you need to
Look at how it interacts with ROM addressing , timing etc . I’d expect clocking of the data to be very critical and can’t see how you’d ever achieve that, given how much work the Arduino is doing to provide the data or are you trying to do DMA ? In which case how is going to interract with the Arduino processor .
If you must , have a look at the z80 pio chip as a possible way around it .

Unless it’s a technical challenge I really wouldn’t bother , this looks very hard/impossible/ not worth it .Can you still get Z80 stuff ? that’s been around since the 70’s

I'm planning on doing a Z80 Computer project, and theffore i need to test using test programs, in this case i just wanted to test the CPU itself.

it is just Direct addressing, Port A and C together on the Mega2560 are the 16b Address input that the CPU accesses and Port L is the 8b Output for the Data.

it should be a very simple circuit with nothing more than the CPU, a clock, and this Emulated ROM. the PIO shouldn't be needed at all for this.

also JP just takes the next 2 bytes in memory and puts that into the PC. which in turn makes the program "jump" to that set Address. there is nothing being loaded in any other Register, no condition needs to be met, etc. it is a simple and complete Instruction.

timing is not hard, i got a NE555 as a slow clock and a 10MHz Oscilator to let the CPU run at max speed. the Arduino's CPU is much faster than a Z80 so it will never be too slow, even at the full 10MHz

What is Your Z80 doing before and during Your load if the code?
Are You sure that the Z80 is not changing those 7 bytes? Using the reset, hoe?
I have been working a lot with the Z80 in the past.

before the loading it is doing nothing, as soon as i connect it to Power it starts to go up the addresses until it reaches $C3 (JP), the CPU can't be changing any of those Bytes, it's ROM it cannot take in Data and none of the Instructions write anything to Memory.

i hooked up an LED to pin M1 to see when it is fetching an Opcode, and (when reaching the Jump Instruction) it only fetches the Instruction and the LED stays on during the reading of the next 2 bytes, which is exactly what it should do.

after that though it appears to be splitting up the process. you can see that in the pastebin that every 2nd Address is counting up.

so it's jumps back to 0 and also continues to go beyong the Jump "at the same time" (it switching between doing both back and forth with each clock pulse)

basically this makes it clearer that it is doing 2 things
PASTEBIN

also why is it that everytime i make a reply it just throws me back onto the Main Forum page instead of staying in this thread?

Came across this for testing Z80’s , which looked neat

You might yourself a Nascom 1 too

well i mean mine is also doing NOP Instructions well, but my test program just confuses it.

i might ge ta PIO and see if it works with a complexer circuit.

How does the Z80 know what the data is valid. I suspect that your ARDU-ROM is just to slow!

Timing between a CPU and it's memory is very important. See "wait states"

Mark

Fetching a NOP ought to set M1, "Machine cycle 1" I think.
Having the Z80 connected to address- and data-lines could give power to the Z80 or not? In that case it is executing whatever it reads.

Your testsequence is allright. You could even use a code with Jump $0000 at address 0000. Plug all memory with Jump $0000.

Do I give You any idea?

Good tip holmes4. Memory accesstime versus Z80 clock and timing requirements.
Check it!

I cannot see how both controllers are wired together. What about synchronizing signals?

Perhaps you also see the DRAM refresh addresses in your Serial output?

Is there not a hardware signal "op code fetch" that needs to be used when accessing the tedt memory?

holmes4:
How does the Z80 know what the data is valid. I suspect that your ARDU-ROM is just to slow!

Timing between a CPU and it's memory is very important. See "wait states"

Mark

well the Z80 is being controlled by a slow NE555 Timer, so the Arduino should be magnitudes faster than the Z80. even at full 10MHz it appears to keep up with it. so either i'm missin what you mean with the timing between both, since the Arduino responds faster than the Z80 could. or that is not the problem.

Railroader:
Good tip holmes4. Memory accesstime versus Z80 clock and timing requirements.
Check it!

the OPcode Fetch of the Z80 should be more than long enough, it needs around 2 clock pulses, which in my testing case are each around 1-2Hz fast, or made using debounced button presses. so the Arduino should be more than fast enough to display the data on the Bus.

DrDiettrich:
I cannot see how both controllers are wired together. What about synchronizing signals?

Perhaps you also see the DRAM refresh addresses in your Serial output?

the Serial monitor is purely to show the current Address and Data. it might do more in the future, like show Op Code fetches, Interupts, etc.

i'm not using any Shift registers, latches, or anything. just a lot of wires, LEDs, and Clock circuits here: PIC

TECHNICALLY, i could use the Arduino as clock, so that i make sure it only does a cycle AFTER the "present data" part of the Program is done. hmm, i might try that

Railroader:
Is there not a hardware signal "op code fetch" that needs to be used when accessing the tedt memory?

no not really, there are only outputs to be used to see when the CPU is fetching Op codes, M1, Memory Rquest, IO Request, Halt, etc

Please provide a circuit diagram.

You seem not to understand the Z80 hardware and operation :frowning:

@DrDiettrich
The think the opposite, quite a good knowledge about the Z80.

I don't remember the minimum clock frequency for Z80. Did it vary from Z80, Z80A,... X80C at 10 MHz?

In Your testdata there are signs of executing Jmp 0000 coming later on.
Strange might be the opcode, and argument fetch of none C3 and 00 bytes.

Keep on, crack it!

DrDiettrich:
Please provide a circuit diagram.

You seem not to understand the Z80 hardware and operation :frowning:

well then i will need some time to draw one, i don't have fancy circuit software...
done! Here's the PIC
here is the Pinout as reference: PIC

all pull resitors are 1 kΩ large, the thick black wire is suppsoed to mean a "bundle" of wires. each of them also has a pull down Resitor.

the CLK is just connected to a NE555 Timer and a debounced button.

Clock timing requirements, for Z80, like raise and fall times? I have a memory that the clock need to have rather sharp edges.
Sad I dumped my old Z80 dicuments some time ago.
Keep on!

Railroader:
@DrDiettrich
The think the opposite, quite a good knowledge about the Z80.

I don't remember the minimum clock frequency for Z80. Did it vary from Z80, Z80A,... X80C at 10 MHz?

In Your testdata there are signs of executing Jmp 0000 coming later on.
Strange might be the opcode, and argument fetch of none C3 and 00 bytes.

Keep on, crack it!

well there is no Minimum clock freq. just a max. one, which is 10MHz.

also, might it be that the ever increasing address half of the time is just the CPU refreshing all 64kB of Memory each second Instruction cycle...

ok now i feel absolutely stupid. half of the Instruction execution the CPU is going through another Address to refresh the Memory (because old DRAM), but the other half it is doing the code as normal. so if i were to record only every second change on the Address bus i SHOULD get the infinite loop of my Program repeating itself.

well, i really really really feel stupid now.
after using an LED to check the RFSH Pin i can confirm that it was literally just the CPU using the lower 7 bits to refresh RAM.

now i need to modify the Program so that when the RFSH Pin is low that it simply ignores anything from the Address Bus until RFSH is high again. should be a single while() loop.

EDIT: works. here is the Refresh Filtered LOG

once this program is finished i will publish it as the Offical Z80 Testing Program©! i'm sure someone will find it useful.

Bingo!
Developing a quite powerful Z80 interface in the end of the 1970:s i missed to use one signal, an IRQ answer. 3 years later my development ran into serious trouble that made me creat my own designed dynamuc memory boards. It took me a year until the clock wad ringing, remembering the dropper IRQA......
A write protectable memory was made using the selfdesigned DRAM.
No shame to You! I lift my hat.
Good luck continuing!