+static void
+ao_storage_zapall(void)
+{
+ ao_cmd_white();
+ if (!ao_match_word("DoIt"))
+ return;
+ ao_storage_erase(0, ao_storage_log_max);
+}
+
+#if AO_STORAGE_TEST
+
+#define AO_STORAGE_TEST_SIZE 256
+static uint8_t storage_test[AO_STORAGE_TEST_SIZE];
+
+static void
+ao_storage_failure(uint32_t pos, char *format, ...)
+{
+ va_list a;
+ printf("TEST FAILURE AT %08x: ", pos);
+ va_start(a, format);
+ vprintf(format, a);
+ va_end(a);
+}
+
+static uint8_t
+ao_storage_check_block(uint32_t pos, uint8_t value)
+{
+ uint32_t offset;
+ uint32_t byte;
+
+ for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_test)) {
+ if (!ao_storage_read(pos + offset, storage_test, sizeof (storage_test))) {
+ ao_storage_failure(pos + offset, "read failed\n");
+ return 0;
+ }
+ for (byte = 0; byte < sizeof (storage_test); byte++)
+ if (storage_test[byte] != value) {
+ ao_storage_failure(pos + offset + byte,
+ "want %02x got %02x\n",
+ value, storage_test[byte]);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static uint8_t
+ao_storage_fill_block(uint32_t pos, uint8_t value)
+{
+ uint32_t offset;
+ uint32_t byte;
+
+ for (byte = 0; byte < sizeof (storage_test); byte++)
+ storage_test[byte] = value;
+ for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_test)) {
+ if (!ao_storage_write(pos + offset, storage_test, sizeof (storage_test))) {
+ ao_storage_failure(pos + offset, "write failed\n");
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static uint8_t
+ao_storage_check_incr_block(uint32_t pos)
+{
+ uint32_t offset;
+ uint32_t byte;
+
+ for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_test)) {
+ if (!ao_storage_read(pos + offset, storage_test, sizeof (storage_test))) {
+ ao_storage_failure(pos + offset, "read failed\n");
+ return 0;
+ }
+ for (byte = 0; byte < sizeof (storage_test); byte++) {
+ uint8_t value = offset + byte;
+ if (storage_test[byte] != value) {
+ ao_storage_failure(pos + offset + byte,
+ "want %02x got %02x\n",
+ value, storage_test[byte]);
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+static uint8_t
+ao_storage_fill_incr_block(uint32_t pos)
+{
+ uint32_t offset;
+ uint32_t byte;
+
+ for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_test)) {
+ for (byte = 0; byte < sizeof (storage_test); byte++)
+ storage_test[byte] = offset + byte;
+ if (!ao_storage_write(pos + offset, storage_test, sizeof (storage_test))) {
+ ao_storage_failure(pos + offset, "write failed\n");
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static uint8_t
+ao_storage_fill_check_block(uint32_t pos, uint8_t value)
+{
+ return ao_storage_fill_block(pos, value) && ao_storage_check_block(pos, value);
+}
+
+static uint8_t
+ao_storage_incr_check_block(uint32_t pos)
+{
+ return ao_storage_fill_incr_block(pos) && ao_storage_check_incr_block(pos);
+}
+
+static uint8_t
+ao_storage_test_block(uint32_t pos)
+{
+ ao_storage_erase(pos, ao_storage_block);
+ printf(" erase"); flush();
+ if (!ao_storage_check_block(pos, 0xff))
+ return 0;
+ printf(" zero"); flush();
+ if (!ao_storage_fill_check_block(pos, 0x00))
+ return 0;
+ ao_storage_erase(pos, ao_storage_block);
+ printf(" 0xaa"); flush();
+ if (!ao_storage_fill_check_block(pos, 0xaa))
+ return 0;
+ ao_storage_erase(pos, ao_storage_block);
+ printf(" 0x55"); flush();
+ if (!ao_storage_fill_check_block(pos, 0x55))
+ return 0;
+ ao_storage_erase(pos, ao_storage_block);
+ printf(" increment"); flush();
+ if (!ao_storage_incr_check_block(pos))
+ return 0;
+ ao_storage_erase(pos, ao_storage_block);
+ printf(" pass\n"); flush();
+ return 1;
+}
+
+static void
+ao_storage_test(void)