Skip to content

Instantly share code, notes, and snippets.

@arpruss
Created July 9, 2021 17:05
Show Gist options
  • Save arpruss/d607aec41258f09669a28efb87ba154d to your computer and use it in GitHub Desktop.
Save arpruss/d607aec41258f09669a28efb87ba154d to your computer and use it in GitHub Desktop.
// try to read a badly damaged 32k Gameboy Cartridge
const uint32_t aPins[16] = { PB8, PB9, PC13, PB7, PA0, PA1, PA2, PA3,
PA4, PA5, PA6, PA7, PB0, PB1, PB10, PB11 };
const uint32_t dPins[8] = { PB4, PB3, PA9, PA8, PB15, PB14, PB13, PA10 };
// all 5V tolerant: PB4, PB3, PA9, PA8, PB15, PB14, PB13, PA10
uint16_t address;
uint16_t RD = PB5;
#define CHUNK 0x4
#define VERIFY_TIMES 5
uint8_t data[CHUNK];
uint8_t dataCheck[CHUNK];
void setAddress(uint16_t address) {
uint16_t mask = 1;
for (unsigned bit = 0 ; mask ; bit++, mask <<= 1)
digitalWrite(aPins[bit], (mask & address) ? 1 : 0);
}
uint8_t readData() {
uint8_t out = 0;
uint8_t mask = 1;
for (unsigned bit = 0 ; mask ; bit++, mask <<= 1)
if (digitalRead(dPins[bit]))
out |= mask;
return out;
}
void waitTime(uint16_t address, uint8_t value, uint32_t ms) {
setAddress(address);
uint32_t t0 = millis();
do {
if (readData() != value)
t0 = millis();
} while (millis()-t0 < ms);
}
uint8_t readByte(uint16_t address, unsigned del) {
// 10,10,1: 30x5
// 10,10,10: better
// 15,15,10: better
// 5,15,10: decent , 4.5v better
// 1,5,10
setAddress(address);
digitalWrite(RD,0);
for (int i=0;i<200;i++);
// delayMicroseconds(0);
uint8_t v = readData();
// digitalWrite(RD,1);
// delayMicroseconds(5);
return v;
}
void dumpChunk(uint8_t* d) {
char buf[3];
for (unsigned i = 0 ; i < CHUNK ; i++) {
sprintf(buf, "%02x", (unsigned)d[i]);
Serial.write((uint8*)buf, 2);
}
}
void readChunkRaw(uint8_t* d, uint16_t address, unsigned del) {
for (int i=0; i<CHUNK; i++)
d[i]=readByte(address+i, del);
}
void readChunk(uint16_t address) {
int count = 0;
int errorCount=0;
int numVerifies = VERIFY_TIMES;
unsigned del = 10;
do {
readChunkRaw(data, address, del);
if (count == 0 || memcmp(data,dataCheck,CHUNK)) {
if (count>0) {
/* Serial.write('\n');
Serial.println(count);
Serial.write('+');
dumpChunk(data);
Serial.write('\n'); */
//Serial.write('*');
del = 250;
errorCount++;
if (errorCount > 80)
numVerifies = 3;
}
count = 1;
memcpy(dataCheck,data,CHUNK);
}
else {
count++;
}
} while(count < numVerifies);
}
void setup() {
for (int i=0;i<15;i++)
pinMode(aPins[i],OUTPUT);
for (int i=0;i<8;i++)
pinMode(dPins[i],INPUT_PULLDOWN);
pinMode(RD,OUTPUT);
digitalWrite(RD,0);
pinMode(PB12,OUTPUT);
digitalWrite(PB12,1);
Serial.begin();
delay(3000);
digitalWrite(PB12,0);
address = 0;
// setAddress(0b101010101010101);
// while(1);
}
uint8_t carefulRead(uint16_t address) {
setAddress(address);
uint8_t datum = 0;
for (int i=0;i<20;i++) {
digitalWrite(RD,0);
delayMicroseconds(1); //1
for (int j=0;j<120;j++)
datum |= readData();
digitalWrite(RD,1);
delayMicroseconds(100); //50
}
return datum;
}
void zzloop() {
uint8_t data[4000];
address = 0x7FF5;
digitalWrite(RD,0);
delayMicroseconds(100); // 7ff3 = c3, 7ff5 = 69
for (; address <= 0x7ff5; address++) {
Serial.println(address,HEX);
setAddress(address);
digitalWrite(RD,0);
delayMicroseconds(1);
// for (volatile int j=0;j<10;j++);
for (int i=0;i<4000;i++) {
//delayMicroseconds(50);
data[i] = readData();
}
digitalWrite(RD,1);
for (int i=0;i<4000;i++) {
Serial.print(data[i],HEX);
Serial.print(" ");
}
Serial.write('\n');
}
// while(1);
}
void loop() {
if (address >= 0x8000)
return;
char buf[12];
sprintf(buf, "%04x: ", (unsigned)address);
Serial.print(buf);
for (int i=0; i<0x20; i++) {
uint8_t r = carefulRead(address);
sprintf(buf, "%02x", r);
Serial.print(buf);
address++;
}
Serial.write('\n');
}
void cloop() {
char buf[12];
sprintf(buf, "\n%04x: ", (unsigned)address);
Serial.print(buf);
readChunk(address);
dumpChunk(data);
address += CHUNK;
if (address >= 0x8000) {
Serial.write('\n');
while(1) ;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment