+ uint8_t ret;
+ uint8_t response;
+ uint8_t start_block[2];
+ int i;
+
+ ao_sdcard_lock();
+ if (!initialized) {
+ ao_sdcard_setup();
+ initialized = 1;
+ if (sdtype != ao_sdtype_unknown)
+ present = 1;
+ }
+ if (!present) {
+ ao_sdcard_unlock();
+ return 0;
+ }
+ if (sdtype != ao_sdtype_sd2block)
+ block <<= 9;
+ ao_sdcard_get();
+ ao_sdcard_select();
+
+ ret = ao_sdcard_send_cmd(SDCARD_WRITE_BLOCK, block);
+ ao_sdcard_recv_reply(NULL, 0);
+ if (ret != SDCARD_STATUS_READY_STATE)
+ goto bail;
+
+ /* Write a pad byte followed by the data start block marker */
+ start_block[0] = 0xff;
+ start_block[1] = SDCARD_DATA_START_BLOCK;
+ ao_sdcard_send(start_block, 2);
+
+ /* Send the data */
+ ao_sdcard_send(data, 512);
+
+ /* Fake the CRC */
+ ao_sdcard_send_fixed(0xff, 2);
+
+ /* See if the card liked the data */
+ ao_sdcard_recv(&response, 1);
+ if ((response & SDCARD_DATA_RES_MASK) != SDCARD_DATA_RES_ACCEPTED) {
+ ret = 0x3f;
+ goto bail;
+ }
+
+ /* Wait for the bus to go idle (should be done with an interrupt) */
+ for (i = 0; i < SDCARD_IDLE_TIMEOUT; i++) {
+ ao_sdcard_recv(&response, 1);
+ if (response == 0xff)
+ break;
+ }
+ if (i == SDCARD_IDLE_TIMEOUT)
+ ret = 0x3f;
+bail:
+ ao_sdcard_deselect();
+ ao_sdcard_put();
+ ao_sdcard_unlock();
+ return ret == SDCARD_STATUS_READY_STATE;
+}
+
+#if SDCARD_DEBUG
+static uint8_t test_data[512];
+
+static void
+ao_sdcard_test_read(void)
+{
+ int i;
+ if (!ao_sdcard_read_block(1, test_data)) {
+ printf ("read error\n");
+ return;
+ }
+ printf ("data:");
+ for (i = 0; i < 18; i++)
+ printf (" %02x", test_data[i]);
+ printf ("\n");