diff --git a/bin/GWRAM.dbg.po b/bin/GWRAM.dbg.po index f3f8c8c..7d0f5df 100644 Binary files a/bin/GWRAM.dbg.po and b/bin/GWRAM.dbg.po differ diff --git a/bin/GWRAM.po b/bin/GWRAM.po index 70cdb07..0a46eb8 100644 Binary files a/bin/GWRAM.po and b/bin/GWRAM.po differ diff --git a/ram2gs.c b/ram2gs.c index ed84b3e..7533edf 100644 --- a/ram2gs.c +++ b/ram2gs.c @@ -9,15 +9,15 @@ #include "gwconio.h" #include "ram2gs_asm.h" -static void ram2gs_erase() { ram2gs_cmd(0x28); } -static void ram2gs_program() { ram2gs_cmd(0x24); } static void ram2gs_set(char en8meg, char enled) { char cmd = 0x10; if (en8meg) { cmd |= 0x01; } if (enled) { cmd |= 0x02; } ram2gs_cmd(cmd); } -static void ram2gs_set_nvm(char en8meg, char enled) { + +static void ram2gs_max_erase() { ram2gs_cmd(0x28); } +static void ram2gs_max_set_nvm(char en8meg, char enled) { char i; // Clock in 0 to enable this setting entry ram2gs_cmd(0x20); @@ -49,7 +49,64 @@ static void ram2gs_set_nvm(char en8meg, char enled) { ram2gs_cmd(0x23); } - ram2gs_program(); + // Program + ram2gs_cmd(0x24); +} + +static void ram2gs_spi_select() { ram2gs_cmd(0x34); } +static void ram2gs_spi_deselect() { ram2gs_cmd(0x30); } +static void ram2gs_spi_tx8(char data) { + char i; + for (i = 0; i < 8; i++) { + ram2gs_cmd(0x34 + ((data >> (7-i)) & 1)); + ram2gs_cmd(0x36 + ((data >> (7-i)) & 1)); + } +} +static void ram2gs_spi_wren() { + ram2gs_spi_deselect(); + ram2gs_spi_select(); + ram2gs_spi_tx8(0x06); // 0x06 is write enable + ram2gs_spi_deselect(); +} +static void ram2gs_spi_erase() { + ram2gs_spi_wren(); + ram2gs_spi_select(); + ram2gs_spi_tx8(0x20); // 0x20 is sector erase (4 kB) + ram2gs_spi_tx8(0x00); // address[23:16] + ram2gs_spi_tx8(0x10); // address[15:8] + ram2gs_spi_tx8(0x00); // address[7:0] + ram2gs_spi_deselect(); +} +static void ram2gs_spi_set_nvm(char en8meg, char enled) { + ram2gs_spi_erase(); // First erase + spin(33, 8); // Wait for >= 500ms on even the fastest systems. + ram2gs_spi_wren(); + ram2gs_spi_select(); + ram2gs_spi_tx8(0x02); // 0x02 is page (byte) program + ram2gs_spi_tx8(0x00); // address[23:16] + ram2gs_spi_tx8(0x10); // address[15:8] + ram2gs_spi_tx8(0x00); // address[7:0] + // data[7:0] + if (!en8meg && !enled) { ram2gs_spi_tx8(0x7F); } + else if (!en8meg && enled) { ram2gs_spi_tx8(0x3F); } + else if ( en8meg && !enled) { ram2gs_spi_tx8(0xFF); } + else if ( en8meg && enled) { ram2gs_spi_tx8(0xBF); } + ram2gs_spi_deselect(); +} + +static void ram2gs_erase(char typecode) { + switch (typecode) { + case 0x00: ram2gs_max_erase(); break; // Altera MAX II / V + case 0x04: ram2gs_spi_erase(); break; // Lattice MachXO / iCE40 / AGM AG256 + //case 0x08: ram2gs_erase_lcmxo2(); break; // Lattice MachXO2 + } +} +static void ram2gs_set_nvm(char typecode, char en8meg, char enled) { + switch (typecode) { + case 0x00: ram2gs_max_set_nvm(en8meg, enled); break; // Altera MAX II / V + case 0x04: ram2gs_spi_set_nvm(en8meg, enled); break; // Lattice MachXO / iCE40 / AGM AG256 + //case 0x08: ram2gs_set_nvm_lcmxo2(en8meg, enled); break; // Lattice MachXO2 + } } static void menu_led(char enled) { @@ -62,13 +119,11 @@ static void menu_led(char enled) { static void menu() { - uint8_t bankcount = ram2gs_getsize(); + uint8_t bankcount; + clrscr(); // Clear screen + gwcputsxy(5, 1, "-- RAM2GS Capacity Settings --"); - - gotoxy(4, 3); - gwcputs("Current RAM2GS capacity: "); - printf("%d", bankcount * 64); - gwcputs(" kB"); + gwcputsxy(4, 3, "Current RAM2GS capacity: ..."); gwcputsxy(1, 6, "Select desired memory capacity:"); @@ -77,24 +132,40 @@ static void menu() gwcputsxy(1, 18, "Capacity will be saved until power-off."); - gwcputsxy(1, 20, "To remember capacity setting in"); + gwcputsxy(1, 20, "To remember capacity and LED setting in"); gwcputsxy(1, 21, "nonvolatile memory, press Apple+number."); gwcputsxy(1, 23, "Press [Q] to quit without saving."); + + bankcount = ram2gs_getsize(); + gotoxy(29, 3); + printf("%d", bankcount * 64); + gwcputs(" kB"); +} + +static void loading_screen() +{ + clrscr(); // Clear screen + gwcputsxy(8, 1, "Loading RAM2GS settings..."); } int ram2gs_main(void) { - char hasled = 1; - char typecode = 0; - char enled = 0; - char en8meg = 1; - char nvm = 0; - int reset_count = 0; + char hasled = true; + char typecode = false; + char enled = false; + char en8meg = true; + char nvm = false; + int reset_count = false; - if (ram2gs_detect(0 << 2)) { + loading_screen(); + + if (ram2gs_detect(0x00)) { + typecode = 0x00; hasled = !ram2gs_detect(0x04); - typecode = 0x0; + } else if (ram2gs_detect(0x04)) { + typecode = 0x04; + hasled = true; } else { #ifndef SKIP_RAM2GS_DETECT // If no RAM2GS, show an error message and quit @@ -118,11 +189,11 @@ int ram2gs_main(void) clrscr(); return EXIT_SUCCESS; } - case '1': en8meg = 0; ram2gs_set(0, enled); break; - case '2': en8meg = 1; ram2gs_set(1, enled); break; + case '1': en8meg = false; ram2gs_set(en8meg, enled); break; + case '2': en8meg = true; ram2gs_set(en8meg, enled); break; case 'L': { - if (enled == 0) { enled = 1; } - else { enled = 0; } + enled = !enled; + ram2gs_set(en8meg, enled); if (hasled) { menu_led(enled); }; continue; } case 'R': { @@ -133,7 +204,7 @@ int ram2gs_main(void) gwcputsxy(1, 8, "Resetting RAM2GS settings."); gwcputsxy(1, 9, "Do not turn off your Apple."); - ram2gs_erase(); // Erase RAM2GS settings memory + ram2gs_erase(typecode); // Erase RAM2GS settings memory ram2gs_set(1, 0); // Enable 8 megabytes and disable LED // Wait for >= 500ms on even the fastest systems. @@ -142,6 +213,7 @@ int ram2gs_main(void) // Show success message and quit clrscr(); // Clear screen gwcputsxy(1, 8, "RAM2GS settings reset successfully."); + nvm = true; goto end; } continue; @@ -161,7 +233,7 @@ int ram2gs_main(void) gwcputsxy(1, 8, "Saving RAM2GS capacity setting."); gwcputsxy(1, 9, "Do not turn off your Apple."); // Save capacity in nonvolatile memory. - ram2gs_set_nvm(en8meg, enled); + ram2gs_set_nvm(typecode, en8meg, enled); // Wait for >= 500ms on even the fastest systems. spin(33, 8); // Print success message