void sd_write_data(SDState *sd, uint8_t value)

{

    int i;



    if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable)

        return;



    if (sd->state != sd_receivingdata_state) {

        fprintf(stderr, "sd_write_data: not in Receiving-Data state\n");

        return;

    }



    if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))

        return;



    switch (sd->current_cmd) {

    case 24:	/* CMD24:  WRITE_SINGLE_BLOCK */

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sd->blk_len) {

            /* TODO: Check CRC before committing */

            sd->state = sd_programming_state;

            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);

            sd->blk_written ++;

            sd->csd[14] |= 0x40;

            /* Bzzzzzzztt .... Operation complete.  */

            sd->state = sd_transfer_state;

        }

        break;



    case 25:	/* CMD25:  WRITE_MULTIPLE_BLOCK */

        if (sd->data_offset == 0) {

            /* Start of the block - let's check the address is valid */

            if (sd->data_start + sd->blk_len > sd->size) {

                sd->card_status |= ADDRESS_ERROR;

                break;

            }

            if (sd_wp_addr(sd, sd->data_start)) {

                sd->card_status |= WP_VIOLATION;

                break;

            }

        }

        sd->data[sd->data_offset++] = value;

        if (sd->data_offset >= sd->blk_len) {

            /* TODO: Check CRC before committing */

            sd->state = sd_programming_state;

            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);

            sd->blk_written++;

            sd->data_start += sd->blk_len;

            sd->data_offset = 0;

            sd->csd[14] |= 0x40;



            /* Bzzzzzzztt .... Operation complete.  */

            sd->state = sd_receivingdata_state;

        }

        break;



    case 26:	/* CMD26:  PROGRAM_CID */

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sizeof(sd->cid)) {

            /* TODO: Check CRC before committing */

            sd->state = sd_programming_state;

            for (i = 0; i < sizeof(sd->cid); i ++)

                if ((sd->cid[i] | 0x00) != sd->data[i])

                    sd->card_status |= CID_CSD_OVERWRITE;



            if (!(sd->card_status & CID_CSD_OVERWRITE))

                for (i = 0; i < sizeof(sd->cid); i ++) {

                    sd->cid[i] |= 0x00;

                    sd->cid[i] &= sd->data[i];

                }

            /* Bzzzzzzztt .... Operation complete.  */

            sd->state = sd_transfer_state;

        }

        break;



    case 27:	/* CMD27:  PROGRAM_CSD */

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sizeof(sd->csd)) {

            /* TODO: Check CRC before committing */

            sd->state = sd_programming_state;

            for (i = 0; i < sizeof(sd->csd); i ++)

                if ((sd->csd[i] | sd_csd_rw_mask[i]) !=

                    (sd->data[i] | sd_csd_rw_mask[i]))

                    sd->card_status |= CID_CSD_OVERWRITE;



            /* Copy flag (OTP) & Permanent write protect */

            if (sd->csd[14] & ~sd->data[14] & 0x60)

                sd->card_status |= CID_CSD_OVERWRITE;



            if (!(sd->card_status & CID_CSD_OVERWRITE))

                for (i = 0; i < sizeof(sd->csd); i ++) {

                    sd->csd[i] |= sd_csd_rw_mask[i];

                    sd->csd[i] &= sd->data[i];

                }

            /* Bzzzzzzztt .... Operation complete.  */

            sd->state = sd_transfer_state;

        }

        break;



    case 42:	/* CMD42:  LOCK_UNLOCK */

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sd->blk_len) {

            /* TODO: Check CRC before committing */

            sd->state = sd_programming_state;

            sd_lock_command(sd);

            /* Bzzzzzzztt .... Operation complete.  */

            sd->state = sd_transfer_state;

        }

        break;



    case 56:	/* CMD56:  GEN_CMD */

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sd->blk_len) {

            APP_WRITE_BLOCK(sd->data_start, sd->data_offset);

            sd->state = sd_transfer_state;

        }

        break;



    default:

        fprintf(stderr, "sd_write_data: unknown command\n");

        break;

    }

}

void sd_write_data(SDState *sd, uint8_t value)

{

    int i;



    if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable)

        return;



    if (sd->state != sd_receivingdata_state) {

        fprintf(stderr, "sd_write_data: not in Receiving-Data state\n");

        return;

    }



    if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))

        return;



    switch (sd->current_cmd) {

    case 24:	

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sd->blk_len) {

            

            sd->state = sd_programming_state;

            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);

            sd->blk_written ++;

            sd->csd[14] |= 0x40;

            

            sd->state = sd_transfer_state;

        }

        break;



    case 25:	

        if (sd->data_offset == 0) {

            

            if (sd->data_start + sd->blk_len > sd->size) {

                sd->card_status |= ADDRESS_ERROR;

                break;

            }

            if (sd_wp_addr(sd, sd->data_start)) {

                sd->card_status |= WP_VIOLATION;

                break;

            }

        }

        sd->data[sd->data_offset++] = value;

        if (sd->data_offset >= sd->blk_len) {

            

            sd->state = sd_programming_state;

            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);

            sd->blk_written++;

            sd->data_start += sd->blk_len;

            sd->data_offset = 0;

            sd->csd[14] |= 0x40;



            

            sd->state = sd_receivingdata_state;

        }

        break;



    case 26:	

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sizeof(sd->cid)) {

            

            sd->state = sd_programming_state;

            for (i = 0; i < sizeof(sd->cid); i ++)

                if ((sd->cid[i] | 0x00) != sd->data[i])

                    sd->card_status |= CID_CSD_OVERWRITE;



            if (!(sd->card_status & CID_CSD_OVERWRITE))

                for (i = 0; i < sizeof(sd->cid); i ++) {

                    sd->cid[i] |= 0x00;

                    sd->cid[i] &= sd->data[i];

                }

            

            sd->state = sd_transfer_state;

        }

        break;



    case 27:	

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sizeof(sd->csd)) {

            

            sd->state = sd_programming_state;

            for (i = 0; i < sizeof(sd->csd); i ++)

                if ((sd->csd[i] | sd_csd_rw_mask[i]) !=

                    (sd->data[i] | sd_csd_rw_mask[i]))

                    sd->card_status |= CID_CSD_OVERWRITE;



            

            if (sd->csd[14] & ~sd->data[14] & 0x60)

                sd->card_status |= CID_CSD_OVERWRITE;



            if (!(sd->card_status & CID_CSD_OVERWRITE))

                for (i = 0; i < sizeof(sd->csd); i ++) {

                    sd->csd[i] |= sd_csd_rw_mask[i];

                    sd->csd[i] &= sd->data[i];

                }

            

            sd->state = sd_transfer_state;

        }

        break;



    case 42:	

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sd->blk_len) {

            

            sd->state = sd_programming_state;

            sd_lock_command(sd);

            

            sd->state = sd_transfer_state;

        }

        break;



    case 56:	

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sd->blk_len) {

            APP_WRITE_BLOCK(sd->data_start, sd->data_offset);

            sd->state = sd_transfer_state;

        }

        break;



    default:

        fprintf(stderr, "sd_write_data: unknown command\n");

        break;

    }

}

void FUNC_0(SDState *VAR_0, uint8_t VAR_1)

{

    int VAR_2;



    if (!VAR_0->bdrv || !bdrv_is_inserted(VAR_0->bdrv) || !VAR_0->enable)

        return;



    if (VAR_0->state != sd_receivingdata_state) {

        fprintf(stderr, "FUNC_0: not in Receiving-Data state\n");

        return;

    }



    if (VAR_0->card_status & (ADDRESS_ERROR | WP_VIOLATION))

        return;



    switch (VAR_0->current_cmd) {

    case 24:	

        VAR_0->data[VAR_0->data_offset ++] = VAR_1;

        if (VAR_0->data_offset >= VAR_0->blk_len) {

            

            VAR_0->state = sd_programming_state;

            BLK_WRITE_BLOCK(VAR_0->data_start, VAR_0->data_offset);

            VAR_0->blk_written ++;

            VAR_0->csd[14] |= 0x40;

            

            VAR_0->state = sd_transfer_state;

        }

        break;



    case 25:	

        if (VAR_0->data_offset == 0) {

            

            if (VAR_0->data_start + VAR_0->blk_len > VAR_0->size) {

                VAR_0->card_status |= ADDRESS_ERROR;

                break;

            }

            if (sd_wp_addr(VAR_0, VAR_0->data_start)) {

                VAR_0->card_status |= WP_VIOLATION;

                break;

            }

        }

        VAR_0->data[VAR_0->data_offset++] = VAR_1;

        if (VAR_0->data_offset >= VAR_0->blk_len) {

            

            VAR_0->state = sd_programming_state;

            BLK_WRITE_BLOCK(VAR_0->data_start, VAR_0->data_offset);

            VAR_0->blk_written++;

            VAR_0->data_start += VAR_0->blk_len;

            VAR_0->data_offset = 0;

            VAR_0->csd[14] |= 0x40;



            

            VAR_0->state = sd_receivingdata_state;

        }

        break;



    case 26:	

        VAR_0->data[VAR_0->data_offset ++] = VAR_1;

        if (VAR_0->data_offset >= sizeof(VAR_0->cid)) {

            

            VAR_0->state = sd_programming_state;

            for (VAR_2 = 0; VAR_2 < sizeof(VAR_0->cid); VAR_2 ++)

                if ((VAR_0->cid[VAR_2] | 0x00) != VAR_0->data[VAR_2])

                    VAR_0->card_status |= CID_CSD_OVERWRITE;



            if (!(VAR_0->card_status & CID_CSD_OVERWRITE))

                for (VAR_2 = 0; VAR_2 < sizeof(VAR_0->cid); VAR_2 ++) {

                    VAR_0->cid[VAR_2] |= 0x00;

                    VAR_0->cid[VAR_2] &= VAR_0->data[VAR_2];

                }

            

            VAR_0->state = sd_transfer_state;

        }

        break;



    case 27:	

        VAR_0->data[VAR_0->data_offset ++] = VAR_1;

        if (VAR_0->data_offset >= sizeof(VAR_0->csd)) {

            

            VAR_0->state = sd_programming_state;

            for (VAR_2 = 0; VAR_2 < sizeof(VAR_0->csd); VAR_2 ++)

                if ((VAR_0->csd[VAR_2] | sd_csd_rw_mask[VAR_2]) !=

                    (VAR_0->data[VAR_2] | sd_csd_rw_mask[VAR_2]))

                    VAR_0->card_status |= CID_CSD_OVERWRITE;



            

            if (VAR_0->csd[14] & ~VAR_0->data[14] & 0x60)

                VAR_0->card_status |= CID_CSD_OVERWRITE;



            if (!(VAR_0->card_status & CID_CSD_OVERWRITE))

                for (VAR_2 = 0; VAR_2 < sizeof(VAR_0->csd); VAR_2 ++) {

                    VAR_0->csd[VAR_2] |= sd_csd_rw_mask[VAR_2];

                    VAR_0->csd[VAR_2] &= VAR_0->data[VAR_2];

                }

            

            VAR_0->state = sd_transfer_state;

        }

        break;



    case 42:	

        VAR_0->data[VAR_0->data_offset ++] = VAR_1;

        if (VAR_0->data_offset >= VAR_0->blk_len) {

            

            VAR_0->state = sd_programming_state;

            sd_lock_command(VAR_0);

            

            VAR_0->state = sd_transfer_state;

        }

        break;



    case 56:	

        VAR_0->data[VAR_0->data_offset ++] = VAR_1;

        if (VAR_0->data_offset >= VAR_0->blk_len) {

            APP_WRITE_BLOCK(VAR_0->data_start, VAR_0->data_offset);

            VAR_0->state = sd_transfer_state;

        }

        break;



    default:

        fprintf(stderr, "FUNC_0: unknown command\n");

        break;

    }

}

void FUNC_0(SDState *VAR_0, uint8_t VAR_1)
{ int VAR_2; if (!VAR_0->bdrv || !bdrv_is_inserted(VAR_0->bdrv) || !VAR_0->enable)
return; if (VAR_0->state != sd_receivingdata_state) { fprintf(stderr, "FUNC_0: not in Receiving-Data state\n"); return; } if (VAR_0->card_status & (ADDRESS_ERROR | WP_VIOLATION))
return; switch (VAR_0->current_cmd) { case 24:
VAR_0->data[VAR_0->data_offset ++] = VAR_1; if (VAR_0->data_offset >= VAR_0->blk_len) { VAR_0->state = sd_programming_state; BLK_WRITE_BLOCK(VAR_0->data_start, VAR_0->data_offset); VAR_0->blk_written ++; VAR_0->csd[14] |= 0x40; VAR_0->state = sd_transfer_state; } break; case 25:
if (VAR_0->data_offset == 0) { if (VAR_0->data_start + VAR_0->blk_len > VAR_0->size) { VAR_0->card_status |= ADDRESS_ERROR; break; } if (sd_wp_addr(VAR_0, VAR_0->data_start)) { VAR_0->card_status |= WP_VIOLATION; break; } } VAR_0->data[VAR_0->data_offset++] = VAR_1; if (VAR_0->data_offset >= VAR_0->blk_len) { VAR_0->state = sd_programming_state; BLK_WRITE_BLOCK(VAR_0->data_start, VAR_0->data_offset); VAR_0->blk_written++; VAR_0->data_start += VAR_0->blk_len; VAR_0->data_offset = 0; VAR_0->csd[14] |= 0x40; VAR_0->state = sd_receivingdata_state; } break; case 26:
VAR_0->data[VAR_0->data_offset ++] = VAR_1; if (VAR_0->data_offset >= sizeof(VAR_0->cid)) { VAR_0->state = sd_programming_state; for (VAR_2 = 0; VAR_2 < sizeof(VAR_0->cid); VAR_2 ++) if ((VAR_0->cid[VAR_2] | 0x00) != VAR_0->data[VAR_2])
VAR_0->card_status |= CID_CSD_OVERWRITE; if (!(VAR_0->card_status & CID_CSD_OVERWRITE))
for (VAR_2 = 0; VAR_2 < sizeof(VAR_0->cid); VAR_2 ++) { VAR_0->cid[VAR_2] |= 0x00; VAR_0->cid[VAR_2] &= VAR_0->data[VAR_2]; } VAR_0->state = sd_transfer_state; } break; case 27:
VAR_0->data[VAR_0->data_offset ++] = VAR_1; if (VAR_0->data_offset >= sizeof(VAR_0->csd)) { VAR_0->state = sd_programming_state; for (VAR_2 = 0; VAR_2 < sizeof(VAR_0->csd); VAR_2 ++) if ((VAR_0->csd[VAR_2] | sd_csd_rw_mask[VAR_2]) !=
(VAR_0->data[VAR_2] | sd_csd_rw_mask[VAR_2]))
VAR_0->card_status |= CID_CSD_OVERWRITE; if (VAR_0->csd[14] & ~VAR_0->data[14] & 0x60)
VAR_0->card_status |= CID_CSD_OVERWRITE; if (!(VAR_0->card_status & CID_CSD_OVERWRITE))
for (VAR_2 = 0; VAR_2 < sizeof(VAR_0->csd); VAR_2 ++) { VAR_0->csd[VAR_2] |= sd_csd_rw_mask[VAR_2]; VAR_0->csd[VAR_2] &= VAR_0->data[VAR_2]; } VAR_0->state = sd_transfer_state; } break; case 42:
VAR_0->data[VAR_0->data_offset ++] = VAR_1; if (VAR_0->data_offset >= VAR_0->blk_len) { VAR_0->state = sd_programming_state; sd_lock_command(VAR_0); VAR_0->state = sd_transfer_state; } break; case 56:
VAR_0->data[VAR_0->data_offset ++] = VAR_1; if (VAR_0->data_offset >= VAR_0->blk_len) { APP_WRITE_BLOCK(VAR_0->data_start, VAR_0->data_offset); VAR_0->state = sd_transfer_state; } break; default:
fprintf(stderr, "FUNC_0: unknown command\n"); break; } }