TMS2532 EPROM READER
While working on my Z-80 was looking over some of the other Z-80 boards I had sitting around, one was an Arcade Board for Spy Hunter which uses the Z-80 processor. I wanted to see the code for the sound board which had the TNS2532 EPROM's, So with a little board with a DIP socket to place the EPROMS in and made a some ribbon cables configured to attach to my interface board. With maybe and hours work and a little code change I was able to read the code off the EPROM's from my Beaglebone Black I2C host device .
The code is sloppy but works writes a binary file of the EPROM in the socket, it uses my MCP23017P host interface and library.
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include "i2c-dev.h"
#include "mcp23017.h"
#include "z80host.h"
#include "host.h"
#include "i2c_util.h"
FILE *fileptr;
char *buffer;
long filelen;
void main()
{
int file, size, delay;
int adapter_nr = 1; /* probably dynamically determined */
char filename[20];
int addr = 0x21; /* address of I2C device */
__u8 reg; /* Device register to access */
__u8 res, out;
char buf[56],k[32];
int x;
file = Open_i2c_bus(adapter_nr);
init_ports_reset( file );
/*set data code */
write_program_ram( file );
init_ports_reset( file );
printf("read done!\n");
close(file);
}
int Z80_reset(int file )
{
int x, delay;
/* set Reset pin low for 3 Clock cycles */
Write_i2c_port_bit( file, 0x21, 0x01, 5, 0); // Turn on Reset line
Write_i2c_port_bit( file, 0x21, 0x13, 5, 0); /* Reset pin low */
for(delay=0; delay < 200; delay++);
Write_i2c_port_bit( file, 0x21, 0x13, 5, 1); /* Reset pin high */
Write_i2c_port_bit( file, 0x21, 0x01, 5, 1); // Turn off Reset line
printf("Reset done!\n");
}
int init_ports( int file )
{
int x;
printf("init ports\n");
for(x=0; x < 18; x=x+3)
{
Write_i2c_port( file, Z80_host_port_config[x], Z80_host_port_config[x+1], Z80_host_port_config[x+2] );
}
/*Set INT, NMI, BUSREQ, WAIT, RESET high */
Write_i2c_port_bit( file, 0x21, 0x13, 3, 1);
Write_i2c_port_bit( file, 0x21, 0x13, 4, 1);
Write_i2c_port_bit( file, 0x21, 0x13, 5, 1);
Write_i2c_port_bit( file, 0x22, 0x12, 3, 1);
Write_i2c_port_bit( file, 0x22, 0x12, 4, 1);
Write_i2c_port_bit( file, 0x22, 0x12, 5, 1);
printf("init ports done!\n");
}
int init_ports_read( int file )
{
int x;
printf("init ports read mode\n");
for(x=0; x < 18; x=x+3)
{
Write_i2c_port( file, Z80_host_port_config_read_bus[x], Z80_host_port_config_read_bus[x+1], Z80_host_port_config_read_bus[x+2] );
}
/*Set INT, NMI, BUSREQ, WAIT, RESET high */
Write_i2c_port_bit( file, 0x21, 0x13, 3, 1);
Write_i2c_port_bit( file, 0x21, 0x13, 4, 1);
Write_i2c_port_bit( file, 0x21, 0x13, 5, 1);
Write_i2c_port_bit( file, 0x22, 0x12, 3, 1);
Write_i2c_port_bit( file, 0x22, 0x12, 4, 1);
Write_i2c_port_bit( file, 0x22, 0x12, 5, 1);
printf("init ports done!\n");
}
int init_ports_write( int file )
{
int x;
printf("init ports read mode\n");
for(x=0; x < 18; x=x+3)
{
Write_i2c_port( file, Z80_host_port_config_write_bus[x], Z80_host_port_config_write_bus[x+1], Z80_host_port_config_write_bus[x+2] );
}
/*Set INT, NMI, BUSREQ, WAIT, RESET high */
Write_i2c_port_bit( file, 0x21, 0x13, 3, 1);
Write_i2c_port_bit( file, 0x21, 0x13, 4, 1);
Write_i2c_port_bit( file, 0x21, 0x13, 5, 1);
Write_i2c_port_bit( file, 0x22, 0x12, 3, 1);
Write_i2c_port_bit( file, 0x22, 0x12, 4, 1);
Write_i2c_port_bit( file, 0x22, 0x12, 5, 1);
printf("init ports done!\n");
}
int init_ports_reset( int file )
{
int x;
printf("init ports reset\n");
for(x=0; x < 18; x=x+3)
{
Write_i2c_port( file, Z80_host_port_config_reset[x], Z80_host_port_config_reset[x+1], Z80_host_port_config_reset[x+2] );
}
printf("reset ports done!\n");
}
int write_program_ram(int file)
{
int i,la, ha, delay;
unsigned char k[32];
Write_i2c_port_bit( file, 0x21, 0x01, 2, 1); // Bus act
Write_i2c_port_bit( file, 0x21, 0x01, 4, 0); // Bus Request
Write_i2c_port_bit( file, 0x21, 0x13, 4, 0); // Bus Request
// Clock until Z80 releases bus
printf("Waiting for Z80 to release bus \n");
while(BUSACK_o != 0 )
{
read_bus_state( file );
// Write_i2c_port_bit( file, 0x22, 0x12, 5, 0);
// for(delay=0; delay < 200; delay++);
// Write_i2c_port_bit( file, 0x22, 0x12, 5, 1);
// for(delay=0; delay < 200; delay++);
}
printf("Bus ack %2x \n", BUSACK_o);
fileptr = fopen("rom.bin", "wb"); // Open the file in binary mode
if (fileptr == NULL) printf("Error opening bin file\n");
Write_i2c_port( file, 0x20, 0x00, 0b00000000);
Write_i2c_port( file, 0x20, 0x01, 0b00000000);
Write_i2c_port( file, 0x21, 0x00, 0b11111111); // read data port
la = 0;
ha = 0;
for( i=0; i<0x01000; i++)
{
// Write data
Write_i2c_port( file, 0x20, 0x13, ha);
Write_i2c_port( file, 0x20, 0x12, la);
//printf("Press Enter to cont. \n");
//fgets(k,31,stdin);
for(delay=0; delay < 200; delay++);
read_bus_state( file );
fputc(Z80_data_bus, fileptr);
la++;
if (la > 0xff )
{
la = 0;
ha++;
};
read_bus_state( file );
printf("loading ram ");
printf("Address_bus =%2x%2x Data_bus =%2x \n ", Z80_address_bus_b, Z80_address_bus_a, (unsigned char)Z80_data_bus );
}
fclose(fileptr);
}
int read_bus_state( int file )
{
char low_byte, high_byte;
int address_temp;
/* Read Address Bus */
Z80_address_bus_a = Read_i2c_port( file, 0x20, 0x12);
Z80_address_bus_b = Read_i2c_port( file, 0x20, 0x13);
Z80_data_bus = Read_i2c_port( file, 0x21, 0x12);
Z80_control_bus_a = Read_i2c_port( file, 0x21, 0x13);
Z80_control_bus_b = Read_i2c_port( file, 0x22, 0x12);
M1_o = (Z80_control_bus_a & Bit_mask6) != 0;
MREQ_o = (Z80_control_bus_b & Bit_mask1) != 0;
RD_o = (Z80_control_bus_a & Bit_mask0) != 0;
WR_o = (Z80_control_bus_a & Bit_mask1) != 0;
RFSH_o = (Z80_control_bus_a & Bit_mask7) != 0;
HALT_o = (Z80_control_bus_b & Bit_mask2) != 0;
WAIT_i = (Z80_control_bus_a & Bit_mask3) != 0;
INT_i = (Z80_control_bus_b & Bit_mask4) != 0;
NMI_i = (Z80_control_bus_b & Bit_mask3) != 0;
RESET_i = (Z80_control_bus_a & Bit_mask5) != 0;
BUSREQ_i = (Z80_control_bus_a & Bit_mask4) != 0;
BUSACK_o = (Z80_control_bus_a & Bit_mask2) != 0;
CLK_i = (Z80_control_bus_b & Bit_mask5) != 0;
IOREQ_o = (Z80_control_bus_b & Bit_mask0) != 0;
}