Skip to content

Commit

Permalink
EEPROM Settings added, almost working
Browse files Browse the repository at this point in the history
  • Loading branch information
nonarkitten committed Apr 12, 2023
1 parent c6fb9cb commit ea57fa8
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 12 deletions.
223 changes: 221 additions & 2 deletions hal/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void SaveConfigEEPROM(int boot_good) {

cpu_state.config.is_dirty = 0;
cpu_state.config.last_boot_good = boot_good;
cpu_state.config.crc16 = crc16_ccitt(config, sizeof(config_t) - 6, 0xFFFF);
cpu_state.config.crc16 = crc16_ccitt(config, sizeof(config_t) - 8, 0xFFFF);
printf("[I2C0] Saving and verifying settings (CRC=%04X)\n", cpu_state.config.crc16);
I2C0SendCmd( 0x50, addr, 2, &cpu_state.config, sizeof(config_t));
WaitMSDMTimer(10);
Expand All @@ -125,7 +125,7 @@ void LoadConfigEEPROM(void) {

I2C0ReadCmd( 0x50, addr, 2, &i2c_config, sizeof(config_t));
if(i2c_config.ident == 0x704A4954) {
uint16_t calc_crc = crc16_ccitt(config, sizeof(config_t) - 6, 0xFFFF);
uint16_t calc_crc = crc16_ccitt(config, sizeof(config_t) - 8, 0xFFFF);
if(calc_crc == i2c_config.crc16) {
printf("[I2C0] Settings loaded, last boot was %s\n", i2c_config.last_boot_good ? "good" : "bad");
MakeGoodEEPROM();
Expand All @@ -152,4 +152,223 @@ int DetectEEPROM(void) {
cpu_state.config = default_config;
return 0;
}
}

static const char* GetConfigCPU(void) {
if(cpu_state.config.cpu_enable_68000) return "68000";
if(cpu_state.config.cpu_enable_68020) {
if(cpu_state.config.cpu_enable_32bits) {
return (cpu_state.config.cpu_enable_fpu) ? "68020/68882" : "68020";
} else {
return (cpu_state.config.cpu_enable_fpu) ? "68EC020/68882" : "68EC020";
}
}
if(cpu_state.config.cpu_enable_68030) {
if(!cpu_state.config.cpu_enable_mmu) return "68EC030";
if(!cpu_state.config.cpu_enable_fpu) return "68030";
return "68030/68882";
}
if(cpu_state.config.cpu_enable_68040) {
if(!cpu_state.config.cpu_enable_mmu) return "68EC040";
if(!cpu_state.config.cpu_enable_fpu) return "68LC040";
return "68040";
}
}

static int streq(const char* l, const char* r) {
while(*l && *r) {
if(*l != *r) return 0;
l++; r++;
}
return 1;
}

static void SetConfigCPU(const char* CPU) {
if(streq(CPU, "68000")) {
cpu_state.config.cpu_enable_68000 = 1;
cpu_state.config.cpu_enable_68020 = 0;
cpu_state.config.cpu_enable_68030 = 0;
cpu_state.config.cpu_enable_68040 = 0;
cpu_state.config.cpu_enable_32bits = 0;
cpu_state.config.cpu_enable_icache = 0;
cpu_state.config.cpu_enable_dcache = 0;
cpu_state.config.cpu_enable_fpu = 0;
cpu_state.config.cpu_enable_mmu = 0;
}
if(streq(CPU, "68EC020")) {
cpu_state.config.cpu_enable_68000 = 0;
cpu_state.config.cpu_enable_68020 = 1;
cpu_state.config.cpu_enable_68030 = 0;
cpu_state.config.cpu_enable_68040 = 0;
cpu_state.config.cpu_enable_32bits = 0;
cpu_state.config.cpu_enable_icache = 1;
cpu_state.config.cpu_enable_dcache = 0;
cpu_state.config.cpu_enable_fpu = streq(&CPU[7], "/68882");
cpu_state.config.cpu_enable_mmu = 0;
}
if(streq(CPU, "68020")) {
cpu_state.config.cpu_enable_68000 = 0;
cpu_state.config.cpu_enable_68020 = 1;
cpu_state.config.cpu_enable_68030 = 0;
cpu_state.config.cpu_enable_68040 = 0;
cpu_state.config.cpu_enable_32bits = 1;
cpu_state.config.cpu_enable_icache = 1;
cpu_state.config.cpu_enable_dcache = 0;
cpu_state.config.cpu_enable_fpu = streq(&CPU[7], "/68882");
cpu_state.config.cpu_enable_mmu = 0;
}
if(streq(CPU, "68EC030")) {
cpu_state.config.cpu_enable_68000 = 0;
cpu_state.config.cpu_enable_68020 = 0;
cpu_state.config.cpu_enable_68030 = 1;
cpu_state.config.cpu_enable_68040 = 0;
cpu_state.config.cpu_enable_32bits = 1;
cpu_state.config.cpu_enable_icache = 1;
cpu_state.config.cpu_enable_dcache = 1;
cpu_state.config.cpu_enable_fpu = streq(&CPU[7], "/68882");
cpu_state.config.cpu_enable_mmu = 0;
}
if(streq(CPU, "68030")) {
cpu_state.config.cpu_enable_68000 = 0;
cpu_state.config.cpu_enable_68020 = 0;
cpu_state.config.cpu_enable_68030 = 1;
cpu_state.config.cpu_enable_68040 = 0;
cpu_state.config.cpu_enable_32bits = 1;
cpu_state.config.cpu_enable_icache = 1;
cpu_state.config.cpu_enable_dcache = 1;
cpu_state.config.cpu_enable_fpu = streq(&CPU[7], "/68882");
cpu_state.config.cpu_enable_mmu = 1;
}
if(streq(CPU, "68EC040")) {
cpu_state.config.cpu_enable_68000 = 0;
cpu_state.config.cpu_enable_68020 = 0;
cpu_state.config.cpu_enable_68030 = 0;
cpu_state.config.cpu_enable_68040 = 1;
cpu_state.config.cpu_enable_32bits = 1;
cpu_state.config.cpu_enable_icache = 1;
cpu_state.config.cpu_enable_dcache = 1;
cpu_state.config.cpu_enable_fpu = 0;
cpu_state.config.cpu_enable_mmu = 0;
}
if(streq(CPU, "68LC030")) {
cpu_state.config.cpu_enable_68000 = 0;
cpu_state.config.cpu_enable_68020 = 0;
cpu_state.config.cpu_enable_68030 = 0;
cpu_state.config.cpu_enable_68040 = 1;
cpu_state.config.cpu_enable_32bits = 1;
cpu_state.config.cpu_enable_icache = 1;
cpu_state.config.cpu_enable_dcache = 1;
cpu_state.config.cpu_enable_fpu = 0;
cpu_state.config.cpu_enable_mmu = 1;
}
if(streq(CPU, "68030")) {
cpu_state.config.cpu_enable_68000 = 0;
cpu_state.config.cpu_enable_68020 = 0;
cpu_state.config.cpu_enable_68030 = 0;
cpu_state.config.cpu_enable_68040 = 1;
cpu_state.config.cpu_enable_32bits = 1;
cpu_state.config.cpu_enable_icache = 1;
cpu_state.config.cpu_enable_dcache = 1;
cpu_state.config.cpu_enable_fpu = 1;
cpu_state.config.cpu_enable_mmu = 1;
}
}

int toupper(int c) {
if(c < 'a' || c > 'z') return c;
else return c - 'a' + 'A';
}
double strtod(const char* in, char** out) {
int v = 0;
int d = 0;
int div = 1;
int c;

while(c = *in++) {
if(c == 0) break;
else if(c == '.') { d = 1; continue; }
else if(c >= '0' && c <= '9') {
v = (v * 10) + (c - '0');
if(d) div *= 10;
}
else break;
}

return (double)v / (double)div;
}

extern uint32_t toHex2(char* n, int len);
void ManageConfig(void) {
char option[12] = { 0 };
while(option[0] != 'x' && option[0] != 'X') {
printf("%s",
"1. Reload config from EEPROM\n"
"2. Save 'good boot' config to EEPROM\n"
"3. Save 'bad boot' config to EEPROM\n"
"4. Display & Change config\n"
"X. Exit to main menu\n"
"] "
);
gets(option);
switch(option[0]) {
default: break;
case '1': LoadConfigEEPROM(); break;
case '2': SaveConfigEEPROM(1); break;
case '3': SaveConfigEEPROM(0); break;
case '4':
while(1) {
printf("Config:\n");
printf("A. CPU: %s\n", GetConfigCPU());
printf("B. Clock: %0.3f MHz\n", cpu_state.config.kHz * 0.001);
printf("C. I$: %s\n", cpu_state.config.cpu_enable_icache ? "Enabled" : "Disabled");
printf("D. I$ Mask: %04X\n", cpu_state.config.icache_mask_24b);
printf("E. D$: %s\n", cpu_state.config.cpu_enable_dcache ? "Enabled" : "Disabled");
printf("F. D$ Mask: %04X\n", cpu_state.config.dcache_mask_24b);
printf("G. MAPROM %s\n", cpu_state.config.maprom_page != 0xFF ? "Enabled" : "Disabled");
if(cpu_state.config.maprom_page != 0xFF) {
uint32_t page = (cpu_state.config.maprom_page & 0xF8) << 16;
printf(" %06X~%06X\n", page, (page | 0x7FFFF));
}
printf(" POST:\n");
printf("H. Long Mem Test %s\n", cpu_state.config.post_enable_long_mem ? "Enabled" : "Disabled");
printf("I. GreenPAK Test %s\n", cpu_state.config.post_enable_gpack_ok ? "Enabled" : "Disabled");
printf("J. Bus Clock Test %s\n", cpu_state.config.post_enable_checkclk ? "Enabled" : "Disabled");
printf("K. Automap %s\n", cpu_state.config.post_enable_autommap ? "Enabled" : "Disabled");
printf("L. MCU CLK: %d\n" , cpu_state.config.dpll_mul);
printf("M. PMIC Voltage: %0.2f\n" , cpu_state.config.pmic_voltage * 0.01);
printf(" PJIT Cache:\n");
printf("N. Block Size: %d bytes\n", 8 << cpu_state.config.cache_block_bits);
printf("O. Block Count: %d\n", 1 << cpu_state.config.cache_index_bits);
printf(" Cache Size: %d bytes\n", 8 << (cpu_state.config.cache_index_bits + cpu_state.config.cache_block_bits));
printf("X. Return to previous menu\n");
printf("] ");
gets(option);
uint8_t choice = toupper(option[0]);
if(choice == 'X') { option[0] = '?'; break; }

printf("New value? ");
gets(option);
option[0] = toupper(option[0]);

switch(choice) {
case 'A': SetConfigCPU(option); break;
case 'B': cpu_state.config.kHz = (int)(1000.0 * strtod(option, NULL)); break;
case 'C': cpu_state.config.cpu_enable_icache = option[0] == 'E'; break;
case 'D': cpu_state.config.icache_mask_24b = toHex2(option, 4); break;
case 'E': cpu_state.config.cpu_enable_dcache = option[0] == 'E'; break;
case 'F': cpu_state.config.dcache_mask_24b = toHex2(option, 4); break;
case 'G': cpu_state.config.maprom_page = toHex2(option, 2); break;
case 'H': cpu_state.config.post_enable_long_mem = option[0] == 'E'; break;
case 'I': cpu_state.config.post_enable_gpack_ok = option[0] == 'E'; break;
case 'J': cpu_state.config.post_enable_checkclk = option[0] == 'E'; break;
case 'K': cpu_state.config.post_enable_autommap = option[0] == 'E'; break;
case 'L': cpu_state.config.dpll_mul = (int)strtod(option, NULL); break;
case 'M': cpu_state.config.pmic_voltage = (int)(100.0 * strtod(option, NULL)); break;
case 'N': cpu_state.config.cache_block_bits = toHex2(option, 1); break;
case 'O': cpu_state.config.cache_index_bits = toHex2(option, 1); break;
}
} ;
break;
}
}
}
16 changes: 16 additions & 0 deletions hal/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,3 +302,19 @@ void SPIDump(void) {
printf("\n");
}

void ManageSPI(void) {
char option[4] = { 0 };
while(option[0] != 'x' && option[0] != 'X') {
printf("%s",
"1. Erase SPI flash\n"
"2. Program SPI flash\n"
"X. Exit to main menu\n"
"] "
);
gets(option);
switch(option[0]) {
case '1': if (confirm()) EraseSPI(0, ERASE_ALL); break;
case '2': if (confirm()) WriteImage(&_image_start, &_image_end); break;
}
}
}
10 changes: 6 additions & 4 deletions hal/gpak.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,21 +148,23 @@ static const char* const nvmString[16] = {
static uint8_t nvmData[256] = { 0 };
static uint8_t nvmMask[256] = { 0 };

static uint8_t toHex2(char* n) {
uint32_t toHex2(char* n, int len) {
static const char TOHEX[32] = {
0, 10, 11, 12, 13, 14, 15,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0, 0, 0, 0, 0, 0,
};
return (TOHEX[n[0] & 0x1F] << 4) | TOHEX[n[1] & 0x1F];
uint32_t value = 0;
while(len--) value = (value << 4) | TOHEX[(*n++) & 0x1f];
return value; //(TOHEX[n[0] & 0x1F] << 4) | TOHEX[n[1] & 0x1F];
}

static void InitNvm(void) {
for (int i = 0; i < 16; i++) {
for (int b = 0; b < 16; b++) {
uint8_t D = toHex2(nvmString[i] + (b << 1));
uint8_t M = toHex2(nvmMasks[i] + (b << 1));
uint8_t D = toHex2(nvmString[i] + (b << 1), 2);
uint8_t M = toHex2(nvmMasks[i] + (b << 1), 2);
nvmData[(i << 4) + b] = D;
nvmMask[(i << 4) + b] = M;
}
Expand Down
3 changes: 1 addition & 2 deletions pjit/pjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,6 @@ typedef struct {
uint16_t dcache_mask_24b; // 1 to allow data caching of region
uint16_t icache_mask_24b; // 1 to allow instruction caching

uint8_t last_boot_good;

// PJIT SECTION

// Cache size = 8 << (cache_index_bits + cache_block_bits)
Expand All @@ -201,6 +199,7 @@ typedef struct {
uint16_t kHz;

//
uint8_t last_boot_good;
uint8_t is_dirty;

} config_t;
Expand Down
8 changes: 4 additions & 4 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ const char* menu =
"SETUP:\n"
" J. Jump to PJIT\n"
" C. Set E Clock Divider\n"
" S. Manage SPI Flash\n"
" E. Manage EEPROM Config\n"
" G. Manage GreenPAK\n"
" E. Erase SPI flash\n"
" P. Program SPI flash\n"
" H. Print help (this)\n"
" X. Reboot\n";

Expand Down Expand Up @@ -583,8 +583,8 @@ int main(void) {
// case 'R': case 'r': if (confirm()) run_mcl68k(0); break;
case 'C': case 'c': SetEClock(); break;
case 'G': case 'g': ManageGP(); break;
case 'E': case 'e': if (confirm()) EraseSPI(0, ERASE_ALL); break;
case 'P': case 'p': if (confirm()) WriteImage(&_image_start, &_image_end); break;
case 'E': case 'e': ManageConfig(); break;
case 'S': case 's': ManageSPI(); break;
case 'X': case 'x': if (confirm()) Reset(); break;

default: printf("Unimplemented\n"); // fallthru
Expand Down

0 comments on commit ea57fa8

Please sign in to comment.