435 lines
8.4 KiB
C
435 lines
8.4 KiB
C
|
|
#include <avr/io.h>
|
|
#include <util/delay.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "uart.h"
|
|
#include "mmc.h"
|
|
#include "fat.h"
|
|
|
|
// Debug
|
|
#define debug(x, fmt) printf("%s:%u: %s=" fmt, __FILE__, __LINE__, #x, x)
|
|
extern FILE uart_stdout;
|
|
|
|
//SREG defines
|
|
#define S_MOSI PB5
|
|
#define S_MISO PB6
|
|
#define S_SCK PB7
|
|
#define S_LATCH PB4
|
|
|
|
//DEBUG defines
|
|
#define D_LED0 PD6
|
|
|
|
//SRAM defines
|
|
#define R_WR PB1
|
|
#define R_RD PB0
|
|
|
|
#define RAM_PORT PORTA
|
|
#define RAM_DIR DDRA
|
|
#define RAM_REG PINA
|
|
|
|
#define CTRL_PORT PORTB
|
|
#define CTR_DIR DDRB
|
|
#define LATCH_PORT PORTB
|
|
#define LATCH_DIR DDRB
|
|
|
|
#define SPI_PORT PORTB
|
|
#define SPI_DIR DDRB
|
|
|
|
#define LED_PORT PORTD
|
|
#define LED_DIR DDRD
|
|
|
|
//#define FILENAME "sprite.raw" //ok
|
|
//#define FILENAME "ascii.smc" //ok
|
|
//#define FILENAME "rom.smc" //ok
|
|
//#define FILENAME "supert.smc"
|
|
//#define FILENAME "vortex.smc"
|
|
#define FILENAME "mrdo.smc"
|
|
//#define FILENAME "spacei.smc"
|
|
//#define FILENAME "bank01.smc" //ok
|
|
//#define FILENAME "bank02.smc" //ok
|
|
//#define FILENAME "bank03.smc" //ok
|
|
//#define FILENAME "bank04.smc" //ok
|
|
//#define FILENAME "bank05.smc" //ok
|
|
//#define FILENAME "bank06.smc" //ok
|
|
//#define FILENAME "bank07.smc" //ok
|
|
//#define FILENAME "banklo.smc" //ok
|
|
//#define FILENAME "bankhi.smc" //ok
|
|
//#define FILENAME "vram2.smc" //ok
|
|
|
|
#define DUMPNAME "dump256.smc"
|
|
#define BUFFER_SIZE 512
|
|
#define BLOCKS 512
|
|
#define MEMSIZE 0x80000
|
|
|
|
uint8_t read_buffer[BUFFER_SIZE];
|
|
|
|
|
|
uint16_t crc_xmodem_update (uint16_t crc, uint8_t data)
|
|
{
|
|
int i;
|
|
crc = crc ^ ((uint16_t)data << 8);
|
|
for (i=0; i<8; i++)
|
|
{
|
|
if (crc & 0x8000)
|
|
crc = (crc << 1) ^ 0x1021;
|
|
else
|
|
crc <<= 1;
|
|
}
|
|
|
|
return crc;
|
|
}
|
|
|
|
uint16_t do_crc(uint8_t * data,uint16_t size)
|
|
{
|
|
uint16_t crc =0;
|
|
uint16_t i;
|
|
for (i=0; i<size; i++){
|
|
crc = crc_xmodem_update(crc,data[i]);
|
|
//printf("%x : %x\n",crc,data[i]);
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
|
|
uint16_t do_crc_update(uint16_t crc,uint8_t * data,uint16_t size)
|
|
{
|
|
uint16_t i;
|
|
for (i=0; i<size; i++)
|
|
crc = crc_xmodem_update(crc,data[i]);
|
|
return crc;
|
|
}
|
|
|
|
|
|
void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet){
|
|
uint16_t i,j;
|
|
uint16_t sum = 0;
|
|
uint8_t clear=0;
|
|
|
|
for (i=0;i<len;i+=16) {
|
|
|
|
sum = 0;
|
|
for (j=0;j<16;j++) {
|
|
sum +=packet[i+j];
|
|
}
|
|
if (!sum){
|
|
clear=1;
|
|
continue;
|
|
}
|
|
if (clear){
|
|
printf("*\n");
|
|
clear = 0;
|
|
}
|
|
printf("%08lx:", addr + i);
|
|
for (j=0;j<16;j++) {
|
|
printf(" %02x", packet[i+j]);
|
|
}
|
|
printf(" |");
|
|
for (j=0;j<16;j++) {
|
|
if (packet[i+j]>=33 && packet[i+j]<=126 )
|
|
printf("%c", packet[i+j]);
|
|
else
|
|
printf(".");
|
|
}
|
|
printf("|\n");
|
|
}
|
|
}
|
|
|
|
|
|
void spi_init(void)
|
|
{
|
|
/* Set MOSI and SCK output, all others input */
|
|
SPI_DIR |= ((1<<S_MOSI) | (1<<S_SCK) | (1<<S_LATCH));
|
|
SPI_DIR &= ~(1<<S_MISO);
|
|
SPI_PORT |= (1<<S_MISO);
|
|
/* Enable SPI, Master*/
|
|
SPCR = ((1<<SPE) | (1<<MSTR));
|
|
}
|
|
|
|
void spi_master_transmit(unsigned char cData)
|
|
{
|
|
/* Start transmission */
|
|
SPDR = cData;
|
|
|
|
/* Wait for transmission complete */
|
|
while(!(SPSR & (1<<SPIF)));
|
|
}
|
|
|
|
|
|
void sram_set_addr(uint32_t addr)
|
|
{
|
|
spi_master_transmit((uint8_t)(addr>>16));
|
|
spi_master_transmit((uint8_t)(addr>>8));
|
|
spi_master_transmit((uint8_t)(addr>>0));
|
|
|
|
LATCH_PORT |= (1<<S_LATCH);
|
|
LATCH_PORT &= ~(1<<S_LATCH);
|
|
}
|
|
|
|
uint8_t sram_read(uint32_t addr)
|
|
{
|
|
uint8_t byte;
|
|
|
|
RAM_DIR = 0x00;
|
|
RAM_PORT = 0xff;
|
|
|
|
CTRL_PORT |= (1<<R_RD);
|
|
CTRL_PORT |= (1<<R_WR);
|
|
|
|
spi_master_transmit((uint8_t)(addr>>16));
|
|
spi_master_transmit((uint8_t)(addr>>8));
|
|
spi_master_transmit((uint8_t)(addr>>0));
|
|
|
|
LATCH_PORT |= (1<<S_LATCH);
|
|
LATCH_PORT &= ~(1<<S_LATCH);
|
|
CTRL_PORT &= ~(1<<R_RD);
|
|
|
|
asm volatile ("nop");
|
|
asm volatile ("nop");
|
|
asm volatile ("nop");
|
|
asm volatile ("nop");
|
|
asm volatile ("nop");
|
|
asm volatile ("nop");
|
|
asm volatile ("nop");
|
|
asm volatile ("nop");
|
|
|
|
byte = RAM_REG;
|
|
CTRL_PORT |= (1<<R_RD);
|
|
RAM_DIR =0x00;
|
|
RAM_PORT =0x00;
|
|
return byte;
|
|
}
|
|
|
|
void sram_write(uint32_t addr, uint8_t data)
|
|
{
|
|
RAM_DIR = 0xff;
|
|
|
|
CTRL_PORT |= (1<<R_RD);
|
|
CTRL_PORT |= (1<<R_WR);
|
|
|
|
spi_master_transmit((uint8_t)(addr>>16));
|
|
spi_master_transmit((uint8_t)(addr>>8));
|
|
spi_master_transmit((uint8_t)(addr>>0));
|
|
|
|
LATCH_PORT |= (1<<S_LATCH);
|
|
LATCH_PORT &= ~(1<<S_LATCH);
|
|
|
|
|
|
CTRL_PORT &= ~(1<<R_WR);
|
|
|
|
RAM_PORT = data;
|
|
CTRL_PORT |= (1<<R_WR);
|
|
|
|
RAM_DIR = 0x00;
|
|
RAM_PORT = 0x00;
|
|
}
|
|
|
|
void sram_init(void){
|
|
|
|
RAM_DIR = 0x00;
|
|
RAM_PORT = 0x00;
|
|
|
|
CTR_DIR |= ((1<<R_WR) | (1<<R_RD));
|
|
CTRL_PORT |= (1<<R_RD);
|
|
CTRL_PORT |= (1<<R_WR);
|
|
|
|
LED_PORT |= (1<<D_LED0);
|
|
}
|
|
|
|
void sram_snes_mode(void){
|
|
CTRL_PORT |= (1<<R_WR);
|
|
CTRL_PORT &= ~(1<<R_RD);
|
|
}
|
|
|
|
void sram_clear(uint32_t addr, uint32_t len){
|
|
|
|
uint32_t i;
|
|
for (i=addr; i<(addr + len);i++ ){
|
|
if (0==i%0xfff)
|
|
printf("sram_clear %lx\n\r",i);
|
|
sram_write(i, 0x00);
|
|
}
|
|
}
|
|
|
|
void sram_copy(uint32_t addr,uint8_t *src, uint32_t len){
|
|
|
|
uint32_t i;
|
|
uint8_t *ptr = src;
|
|
for (i=addr; i<(addr + len);i++ )
|
|
sram_write(i, *ptr++);
|
|
}
|
|
|
|
void sram_read_buffer(uint32_t addr,uint8_t *dst, uint32_t len){
|
|
|
|
uint32_t i;
|
|
uint8_t *ptr = dst;
|
|
for (i=addr; i<(addr + len);i++ ){
|
|
*ptr = sram_read(i);
|
|
ptr++;
|
|
}
|
|
}
|
|
uint8_t sram_check(uint8_t *buffer, uint32_t len){
|
|
|
|
for (uint16_t cnt=0; cnt<len; cnt++)
|
|
if (buffer[cnt])
|
|
return 1;
|
|
return 0;
|
|
}
|
|
int main(void)
|
|
{
|
|
|
|
uint16_t fat_cluster = 0;
|
|
uint8_t fat_attrib = 0;
|
|
uint32_t fat_size = 0;
|
|
uint32_t rom_addr = 0;
|
|
uint8_t bank_cnt = 0;
|
|
uint16_t crc = 0;
|
|
uint16_t block_cnt;
|
|
uart_init();
|
|
stdout = &uart_stdout;
|
|
|
|
sram_init();
|
|
printf("SRAM Init\n");
|
|
|
|
spi_init();
|
|
printf("SPI Init\n");
|
|
|
|
#if 0
|
|
uint8_t t[] = "david";
|
|
printf("Test CRC %x\n",do_crc(t,5));
|
|
while(1);
|
|
#endif
|
|
|
|
|
|
#if 0
|
|
sram_clear(0x000000, 0x80000);
|
|
printf("sram_clear\n");
|
|
#endif
|
|
|
|
#if 0
|
|
printf("read 0x0f0f\n");
|
|
sram_read(0x0f0f);
|
|
printf("write 0x0f0f\n");
|
|
sram_write(0x0f0f,0xaa);
|
|
#endif
|
|
|
|
#if 0
|
|
rom_addr = 0x4aaaa;
|
|
printf("write %lx\n",rom_addr);
|
|
sram_set_addr(rom_addr);
|
|
while(1);
|
|
#endif
|
|
|
|
|
|
while ( mmc_init() !=0) {
|
|
printf("No sdcard...\n");
|
|
}
|
|
printf("MMC Init done\n");
|
|
fat_init(read_buffer);
|
|
printf("FAT Init done.\n");
|
|
rom_addr = 0x000000;
|
|
printf("Look for %s\n",FILENAME);
|
|
|
|
if (fat_search_file((uint8_t*)FILENAME,
|
|
&fat_cluster,
|
|
&fat_size,
|
|
&fat_attrib,
|
|
read_buffer) == 1) {
|
|
|
|
|
|
for (block_cnt=0; block_cnt<BLOCKS; block_cnt++) {
|
|
fat_read_file (fat_cluster,read_buffer,block_cnt);
|
|
|
|
if (block_cnt && block_cnt % 64 == 0){
|
|
bank_cnt++;
|
|
printf("Write Ram Bank: 0x%x Addr: 0x%lx Block: %x CRC: %x\n",bank_cnt,rom_addr,block_cnt,crc);
|
|
crc = 0;
|
|
}
|
|
crc = do_crc_update(crc,read_buffer,512);
|
|
sram_copy(rom_addr,read_buffer,512);
|
|
rom_addr += 512;
|
|
}
|
|
printf("Write Ram Bank: 0x%x Addr: 0x%lx Block: %x CRC: %x\n",bank_cnt,rom_addr,block_cnt,crc);
|
|
printf("Done\n");
|
|
}
|
|
|
|
|
|
printf("Dump Headern\r");
|
|
rom_addr = 0x8000-512;
|
|
sram_read_buffer(rom_addr,read_buffer,512);
|
|
dump_packet(rom_addr,512,read_buffer);
|
|
|
|
#if 0
|
|
printf("Dump Memory\n\r");
|
|
rom_addr = 0x000000;
|
|
for (uint16_t block_cnt=0; block_cnt < 64; block_cnt++) {
|
|
sram_read_buffer(rom_addr,read_buffer,512);
|
|
dump_packet(rom_addr,512,read_buffer);
|
|
rom_addr += 512;
|
|
}
|
|
printf("\nDone 0x%lx\n",rom_addr);
|
|
#endif
|
|
|
|
#if 1
|
|
block_cnt = 0;
|
|
crc = 0;
|
|
rom_addr = 0x000000;
|
|
for (block_cnt=0; block_cnt<BLOCKS; block_cnt++) {
|
|
sram_read_buffer(rom_addr,read_buffer,512);
|
|
if (block_cnt && block_cnt % 64 == 0){
|
|
bank_cnt++;
|
|
printf("Read Ram Bank: 0x%x Addr: 0x%lx Block: %x CRC: %x\n",bank_cnt,rom_addr,block_cnt,crc);
|
|
crc = 0;
|
|
}
|
|
crc = do_crc_update(crc,read_buffer,512);
|
|
rom_addr += 512;
|
|
}
|
|
printf("Read Ram Bank: 0x%x Addr: 0x%lx Block: %x CRC: %x\n",bank_cnt,rom_addr,block_cnt,crc);
|
|
#endif
|
|
|
|
|
|
#if 0
|
|
|
|
printf("Look for %s\n",DUMPNAME);
|
|
|
|
fat_cluster = 0;
|
|
fat_attrib = 0;
|
|
fat_size = 0;
|
|
|
|
if (fat_search_file((uint8_t*)DUMPNAME,
|
|
&fat_cluster,
|
|
&fat_size,
|
|
&fat_attrib,
|
|
read_buffer) == 1) {
|
|
|
|
|
|
printf("Found %s\n",DUMPNAME);
|
|
rom_addr = 0x000000;
|
|
bank_cnt =0;
|
|
for (uint16_t block_cnt=0; block_cnt<BLOCKS; block_cnt++) {
|
|
printf("Write 1");
|
|
sram_read_buffer(rom_addr,read_buffer,512);
|
|
printf("Write 2");
|
|
fat_write_file (fat_cluster,read_buffer,block_cnt);
|
|
if (block_cnt % 64 == 0){
|
|
bank_cnt++;
|
|
}
|
|
printf("Write File Bank: 0x%x Addr: 0x%lx Skipped: %li\n",bank_cnt,rom_addr,skip_block);
|
|
rom_addr += 512;
|
|
}
|
|
printf("Done 0x%lx Skipped %li\n",rom_addr,skip_block);
|
|
}
|
|
#endif
|
|
|
|
sram_snes_mode();
|
|
printf("\nEnter Snes mode\n");
|
|
while(1);
|
|
return 0 ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|