at the end of ata_init()... RAM:1060437E LDR R1, =0x6000B000 ; R1 = 0x6000B000 RAM:10604380 MOV R0, #0 ; R0 = 0 RAM:10604382 STR R0, [R1] ; outl(0, 0x6000B000) RAM:10604382 ; RAM:10604384 LDR R1, =0x6000A000 ; R1 = 0x6000A000 RAM:10604386 STR R0, [R1] ; outl(0, 0x6000A000) RAM:10604388 BX LR ; return RAM:10604388 ; End of function ata_init RAM:10611BC4 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ RAM:10611BC4 RAM:10611BC4 RAM:10611BC4 ata_write_sectors ; CODE XREF: sub_106115F4+1Cp RAM:10611BC4 ; RAM:10611996p ... RAM:10611BC4 RAM:10611BC4 var_40 = -0x40 RAM:10611BC4 var_3C = -0x3C RAM:10611BC4 var_34 = -0x34 RAM:10611BC4 var_30 = -0x30 RAM:10611BC4 var_2C = -0x2C RAM:10611BC4 var_28 = -0x28 RAM:10611BC4 var_20 = -0x20 RAM:10611BC4 var_1C = -0x1C RAM:10611BC4 var_18 = -0x18 RAM:10611BC4 RAM:10611BC4 PUSH {R0-R7,LR} RAM:10611BC6 SUB SP, SP, #0x1C ; SP -= 0x1C RAM:10611BC8 ADD R4, R0, #0 ; R4 = R0 RAM:10611BCA LDR R0, [SP,#0x20] ; R0 = inl(SP + 0x20) = start_block RAM:10611BCC LDR R7, [SP,#0x24] ; R7 = inl(SP + 0x24) = block_count RAM:10611BCE STR R0, [SP,#0x14] ; outl(start_block, SP + 0x14) RAM:10611BD0 MOV R0, #0 ; R0 = 0 RAM:10611BD2 STR R0, [SP,#0xC] ; outl(0, SP + 0xC) RAM:10611BD4 RAM:10611BD4 loc_10611BD4 ; CODE XREF: ata_write_sectors+13Cj RAM:10611BD4 LDR R0, [R4,#0xC] ; do { RAM:10611BD4 ; R0 = inl(R4 + 0xC) RAM:10611BD6 CMP R0, #0 ; if (R0 != 0) RAM:10611BD8 BEQ loc_10611BF6 ; { RAM:10611BDA LDR R0, =0x7A7800 ; R0 = 0x7A7800 = BLOCKS_PER_BANK RAM:10611BDC LDR R1, [SP,#0x14] ; R1 = inl(SP + 0x14) = start_block RAM:10611BDE CMP R1, R0 ; if (R1 >= BLOCKS_PER_BANK) RAM:10611BE0 BCC loc_10611BEE ; { RAM:10611BE2 LDR R1, [SP,#0x14] ; R1 = inl(SP + 0x14) = start_block RAM:10611BE4 NEG R0, R0 ; R0 = -BLOCKS_PER_BANK RAM:10611BE6 ADD R1, R1, R0 ; start_block -= BLOCKS_PER_BANK RAM:10611BE8 STR R1, [SP,#0x20] ; outl(start_block, SP + 0x20) RAM:10611BE8 ; RAM:10611BEA MOV R1, #1 ; R1 = 1 RAM:10611BEC B loc_10611BF0 ; } RAM:10611BEE ; --------------------------------------------------------------------------- RAM:10611BEE RAM:10611BEE loc_10611BEE ; CODE XREF: ata_write_sectors+1Cj RAM:10611BEE MOV R1, #0 ; else RAM:10611BEE ; { RAM:10611BEE ; R1 = 0 RAM:10611BEE ; } RAM:10611BF0 RAM:10611BF0 loc_10611BF0 ; CODE XREF: ata_write_sectors+28j RAM:10611BF0 ADD R0, R4, #0 ; R0 = R4 RAM:10611BF2 BL sd_select_bank ; sd_select_bank(R1) RAM:10611BF2 ; } RAM:10611BF6 RAM:10611BF6 loc_10611BF6 ; CODE XREF: ata_write_sectors+14j RAM:10611BF6 ; ata_write_sectors+3Cj RAM:10611BF6 MOV R1, #1 ; do { RAM:10611BF6 ; R1 = 1 RAM:10611BF8 ADD R0, R4, #0 ; R0 = R4 RAM:10611BFA BL sd_get_state ; state = sd_get_state() RAM:10611BFE CMP R0, #4 RAM:10611C00 BNE loc_10611BF6 ; } while (state != TRAN) RAM:10611C00 ; RAM:10611C02 LDR R0, [SP,#0x24] ; R0 = inl(SP + 0x24) = total_count RAM:10611C04 ADD R5, R7, #0 RAM:10611C06 SUB R1, R0, R7 ; R1 = R0 - R7 = total_count - block_count = blocks_done RAM:10611C08 STR R1, [SP,#0x18] ; outl(blocks_done, SP + 0x18) RAM:10611C08 ; RAM:10611C0A CMP R7, #0x80 RAM:10611C0C BLS loc_10611C10 ; if (R7 > 128) RAM:10611C0E MOV R5, #0x80 ; R5 = 128 RAM:10611C0E ; else RAM:10611C0E ; R5 = R7 RAM:10611C0E ; RAM:10611C0E ; count = R5 RAM:10611C10 RAM:10611C10 loc_10611C10 ; CODE XREF: ata_write_sectors+48j RAM:10611C10 LDR R1, =0x70008200 ; R1 = 0x70008200 (ATA_BASE) RAM:10611C12 MOV R0, #4 ; R0 = 4 = TRAN RAM:10611C14 STR R0, [R1,#0x38] ; SD_STATE_REG = TRAN RAM:10611C16 STR R5, [R1,#0x20] ; BLOCK_COUNT_REG = count RAM:10611C16 ; RAM:10611C18 LDRH R0, [R4,#0x10] ; R0 = inh(R4 + 0x10) = sector_size RAM:10611C1A LDR R1, [SP,#0x20] ; R1 = inl(SP + 0x20) = start_block RAM:10611C1C LDR R2, =0x1C2D ; R2 = 0x1C2D = type RAM:10611C1E MUL R0, R1 ; R0 = sector_size * start_block RAM:10611C20 LSL R1, R0, #0x10 RAM:10611C22 LSR R1, R1, #0x10 ; R1 = (R0 << 16) >> 16 = (sector_size*start_block) & 0xFFFF = arg2 RAM:10611C24 STR R1, [SP] ; outl(R1, SP) RAM:10611C26 STR R2, [SP,#4] ; outl(0x1C2D, SP + 4) RAM:10611C28 MOV R2, #0 ; R2 = 0 = cmd2 RAM:10611C2A MOV R1, #0x19 ; R1 = 0x19 = WRITE_MULTIPLE_BLOCK = cmd1 RAM:10611C2C LSR R3, R0, #0x10 ; R3 = (sector_size*start_block) >> 16 = arg1 RAM:10611C2E ADD R0, R4, #0 ; R0 = R4 RAM:10611C30 BL sd_command ; sd_command(WRITE_MULTIPLE_BLOCK, 0, arg1, arg2, 0x1C2D) RAM:10611C30 ; RAM:10611C34 MOV R1, #1 ; R1 = 1 RAM:10611C36 ADD R0, R4, #0 ; R0 = R4 RAM:10611C38 BL sd_response ; sd_response(1) RAM:10611C38 ; RAM:10611C3C LDRH R0, [R4,#0x10] ; R0 = inh(R4 + 0x10) = sector_size RAM:10611C3E LDR R1, [SP,#0x18] ; R1 = inl(SP + 0x18) = blocks_done RAM:10611C40 MOV R6, #0x10 ; R6 = 16 = FIFO_LEN RAM:10611C42 ADD R3, R0, #0 ; R3 = R0 = sector_size RAM:10611C44 LSR R0, R0, #1 ; R0 = R0 >> 1 = sector_size/2 RAM:10611C46 MUL R0, R1 ; R0 = blocks_done * (sector_size / 2) RAM:10611C48 LDR R1, [SP,#0x28] ; R1 = inl(SP + 0x28) = buf RAM:10611C4A LSL R0, R0, #1 ; R0 = R0 << 1 = 2*R0 = 2*(blocks_done*(sector_size/2)) RAM:10611C4C ADD R2, R0, R1 ; R2 = buf + 2*(blocks_done*(sector_size/2)) RAM:10611C4C ; RAM:10611C4E LDR R1, =0x70008200 ; R1 = 0x70008200 (ATA_BASE) RAM:10611C50 MUL R3, R5 ; R3 = R3*R5 = count*sector_size RAM:10611C52 SUB R3, #0x10 ; R3 = count*sector_size - FIFO_LEN /* dma transfer all but the last 16 bytes */ RAM:10611C52 ; RAM:10611C54 ADD R1, #0x80 ; R1 = 0x70008280 (DATA_REG) RAM:10611C56 ADD R0, R4, #0 ; R0 = R4 RAM:10611C58 BL dma_write_setup ; dma_write_setup(0x70008280, R2, R3) RAM:10611C58 ; RAM:10611C5C ADD R0, R4, #0 ; R0 = R4 RAM:10611C5E BL dma_start ; dma_start() RAM:10611C5E ; RAM:10611C62 LDR R1, =0x70008200 ; /* copy the last 16 bytes */ RAM:10611C62 ; R1 = 0x70008200 (ATA_BASE) RAM:10611C64 MOV R0, #7 ; R0 = 7 = PRG RAM:10611C66 STR R0, [R1,#0x38] ; SD_STATE_REG = PRG RAM:10611C66 ; RAM:10611C68 LDR R1, [SP,#0x18] ; R1 = inl(SP + 0x18) = blocks_done RAM:10611C6A LDR R2, =0x70008200 ; R2 = 0x70008200 (ATA_BASE) RAM:10611C6C ADD R0, R1, R5 ; R0 = blocks_done + count RAM:10611C6E LDRH R1, [R4,#0x10] ; R1 = inh(R4 + 0x10) = sector_size RAM:10611C70 LSR R1, R1, #1 ; R1 = sector_size >> 1 = sector_size/2 RAM:10611C72 MUL R0, R1 ; R0 = (blocks_done + count)*(sector_size/2) RAM:10611C74 LDR R1, [SP,#0x28] ; R1 = inl(SP + 0x28) = buf RAM:10611C76 LSL R0, R0, #1 ; R0 = R0 << 1 = 2*R0 = 2*(blocks_done + count)*(sector_size/2) RAM:10611C78 ADD R0, R0, R1 ; R0 = buf + 2*(blocks_done + count)*(sector_size/2) RAM:10611C7A SUB R0, #0x10 ; R0 = buf + 2*(blocks_done + count)*(sector_size/2) - FIFO_LEN RAM:10611C7A ; RAM:10611C7C ADD R2, #0x80 ; R2 = 0x70008280 (DATA_REG) RAM:10611C7E RAM:10611C7E loc_10611C7E ; CODE XREF: ata_write_sectors+C2j RAM:10611C7E LDRH R1, [R0] ; for (R6 = FIFO_LEN; R6 > 0; R6 -= 2) RAM:10611C80 STR R1, [R2] ; { RAM:10611C82 ADD R0, #2 ; DATA_REG = inh(R0) RAM:10611C84 SUB R6, #2 ; R0 += 2 RAM:10611C86 BNE loc_10611C7E ; } RAM:10611C86 ; RAM:10611C88 LDR R6, =0x7A120 ; R6 = 0x7A120 = 500000 RAM:10611C8A RAM:10611C8A loc_10611C8A ; CODE XREF: ata_write_sectors+E4j RAM:10611C8A LDR R0, =0x70008200 ; for (R6 = 50000; R6 > 0; R6--) RAM:10611C8A ; { RAM:10611C8A ; R0 = 0x70008200 (ATA_BASE) RAM:10611C8C LDR R0, [R0,#4] ; R0 = inl(0x70008204) = STATUS_REG RAM:10611C8E MOVL R1, 0x1000 ; R1 = 0x1000 = DATA_DONE RAM:10611C92 AND R0, R1 ; status = STATUS_REG & DATA_DONE RAM:10611C94 STR R0, [SP,#0x10] ; outl(status, SP + 0x10) RAM:10611C94 ; RAM:10611C96 SUB R6, #1 RAM:10611C98 MOV R1, #0xA ; R1 = 0xA RAM:10611C9A ADD R0, R4, #0 ; R0 = R4 RAM:10611C9C BL sub_10610D94 ; udelay(10) RAM:10611C9C ; RAM:10611CA0 LDR R0, [SP,#0x10] ; R0 = inl(SP + 0x10) = status RAM:10611CA2 CMP R0, #0 ; if (status != 0) /* done */ RAM:10611CA4 BNE loc_10611CAA ; break RAM:10611CA4 ; RAM:10611CA6 CMP R6, #0 RAM:10611CA8 BNE loc_10611C8A ; } RAM:10611CAA RAM:10611CAA loc_10611CAA ; CODE XREF: ata_write_sectors+E0j RAM:10611CAA LDR R0, [SP,#0x10] ; R0 = inl(SP + 0x10) = status RAM:10611CAC CMP R0, #0 ; if (status == 0) RAM:10611CAE BNE loc_10611CB4 ; { /* status was not done */ RAM:10611CB0 MOV R0, #1 ; R0 = 1 RAM:10611CB2 STR R0, [SP,#0xC] ; outl(1, SP + 0xC) RAM:10611CB2 ; } RAM:10611CB4 RAM:10611CB4 loc_10611CB4 ; CODE XREF: ata_write_sectors+EAj RAM:10611CB4 MOV R2, #1 ; R2 = 1 = type RAM:10611CB6 MOV R1, #0 ; R1 = 0 = arg2 RAM:10611CB8 STR R1, [SP] ; outl(0, SP) RAM:10611CBA STR R2, [SP,#4] ; outl(1, SP + 4) RAM:10611CBC MOV R2, #0 ; R2 = 0 = cmd2 RAM:10611CBE MOV R1, #0xC ; R1 = 0xC = STOP_TRANSMISSION = cmd1 RAM:10611CC0 MOV R3, #0 ; R3 = 0 = arg1 RAM:10611CC2 ADD R0, R4, #0 ; R0 = R4 RAM:10611CC4 BL sd_command ; sd_command(STOP_TRANSMISSION, 0, 0, 0, 1) RAM:10611CC4 ; RAM:10611CC8 MOV R1, #1 ; R1 = 1 RAM:10611CCA ADD R0, R4, #0 ; R0 = R4 RAM:10611CCC BL sd_response ; sd_response(1) RAM:10611CD0 RAM:10611CD0 loc_10611CD0 ; CODE XREF: ata_write_sectors+116j RAM:10611CD0 MOV R1, #1 ; do { RAM:10611CD0 ; R1 = 1 RAM:10611CD2 ADD R0, R4, #0 ; R0 = R4 RAM:10611CD4 BL sd_get_state ; state = sd_get_state() RAM:10611CD8 CMP R0, #4 RAM:10611CDA BNE loc_10611CD0 ; } while (state != TRAN) RAM:10611CDA ; RAM:10611CDC LDR R2, =0x70008200 ; R2 = 0x70008200 (ATA_BASE) RAM:10611CDE ADD R2, #0x44 ; R2 = 0x70008244 (REG_12) RAM:10611CE0 LDR R0, [R2] ; R0 = inl(0x70008244) = REG_12 RAM:10611CE2 MOVL R1, 0x8000 ; R1 = 0x8000 RAM:10611CE6 ORR R0, R1 ; R0 = REG_12 | 0x8000 RAM:10611CE8 STR R0, [R2] ; REG_12 |= 0x8000 RAM:10611CE8 ; RAM:10611CEA CMP R6, #0 ; if (R6 != 0) RAM:10611CEC BEQ loc_10611CFC ; { /* transmission didn't timeout, increment */ RAM:10611CEE LDR R1, [SP,#0x20] ; R1 = inl(SP + 0x20) = start_block RAM:10611CF0 LDR R0, [SP,#0x14] ; R0 = inl(SP + 0x14) RAM:10611CF2 ADD R1, R1, R5 ; start_block += count RAM:10611CF4 ADD R0, R0, R5 ; R0 += count RAM:10611CF6 STR R0, [SP,#0x14] ; outl(R0, SP + 0x14) RAM:10611CF6 ; RAM:10611CF8 SUB R7, R7, R5 ; block_count -= count RAM:10611CFA STR R1, [SP,#0x20] ; outl(start_block, SP + 0x20) RAM:10611CFA ; } RAM:10611CFC RAM:10611CFC loc_10611CFC ; CODE XREF: ata_write_sectors+128j RAM:10611CFC CMP R7, #0 RAM:10611CFE BEQ loc_10611D02 RAM:10611D00 B loc_10611BD4 ; } while (block_count != 0) RAM:10611D02 ; --------------------------------------------------------------------------- RAM:10611D02 RAM:10611D02 loc_10611D02 ; CODE XREF: ata_write_sectors+13Aj RAM:10611D02 LDR R0, [SP,#0xC] ; R0 = inl(SP + 0xC) /* 1 if write failed, 0 if successful */ RAM:10611D04 ADD SP, SP, #0x2C ; SP += 0x2C RAM:10611D06 POP {R4-R7} RAM:10611D08 POP {R3} RAM:10611D0A BX R3 ; return RAM:10611D0A ; End of function ata_write_sectors RAM:1060D52C ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ RAM:1060D52C RAM:1060D52C RAM:1060D52C ata_read_sectors ; CODE XREF: read_firmware_header+3Ep RAM:1060D52C ; read_firmware_header+6Cp ... RAM:1060D52C RAM:1060D52C var_38 = -0x38 RAM:1060D52C var_34 = -0x34 RAM:1060D52C var_2C = -0x2C RAM:1060D52C var_28 = -0x28 RAM:1060D52C var_1C = -0x1C RAM:1060D52C var_18 = -0x18 RAM:1060D52C RAM:1060D52C PUSH {R0-R7,LR} RAM:1060D52E SUB SP, SP, #0x14 ; SP -= 0x14 RAM:1060D530 LDR R6, [SP,#0x1C] ; R6 = inl(SP + 0x1C) = block_count RAM:1060D532 ADD R4, R0, #0 ; R4 = R0 RAM:1060D534 ADD R7, R1, #0 ; R7 = R1 = start_block RAM:1060D536 STR R1, [SP,#0xC] ; outl(start_block, SP + 0xC) RAM:1060D538 RAM:1060D538 loc_1060D538 ; CODE XREF: ata_read_sectors+B6j RAM:1060D538 LDR R0, [R4,#0xC] ; do { RAM:1060D538 ; R0 = inl(R4 + 0xC) RAM:1060D53A CMP R0, #0 ; if (R0 != 0) RAM:1060D53C BEQ loc_1060D558 ; { RAM:1060D53E LDR R0, =0x7A7800 ; R0 = 0x7A7800 = BLOCKS_PER_BANK RAM:1060D540 LDR R1, [SP,#0xC] ; R1 = inl(SP + 0xC) = start_block RAM:1060D542 CMP R1, R0 ; if (start_block >= BLOCKS_PER_BANK) RAM:1060D544 BCC loc_1060D550 ; { RAM:1060D546 LDR R1, [SP,#0xC] ; R1 = inl(SP + 0xC) = start_block RAM:1060D548 NEG R0, R0 ; R0 = -BLOCKS_PER_BANK RAM:1060D54A ADD R7, R1, R0 ; start_block -= BLOCKS_PER_BANK RAM:1060D54C MOV R1, #1 ; R1 = 1 RAM:1060D54E B loc_1060D552 ; } RAM:1060D550 ; --------------------------------------------------------------------------- RAM:1060D550 RAM:1060D550 loc_1060D550 ; CODE XREF: ata_read_sectors+18j RAM:1060D550 MOV R1, #0 ; else RAM:1060D550 ; { RAM:1060D550 ; R1 = 0 RAM:1060D550 ; } RAM:1060D552 RAM:1060D552 loc_1060D552 ; CODE XREF: ata_read_sectors+22j RAM:1060D552 ADD R0, R4, #0 ; R0 = R4 RAM:1060D554 BL sd_select_bank ; sd_select_bank(R1) RAM:1060D554 ; } RAM:1060D558 RAM:1060D558 loc_1060D558 ; CODE XREF: ata_read_sectors+10j RAM:1060D558 LDR R0, [SP,#0x1C] ; R0 = inl(SP + 0x1C) = total_count RAM:1060D55A ADD R5, R6, #0 RAM:1060D55C SUB R1, R0, R6 ; R1 = R0 - R6 = total_count - block_count = blocks_done RAM:1060D55E STR R1, [SP,#0x10] ; outl(blocks_done, SP + 0x10) RAM:1060D55E ; RAM:1060D560 CMP R6, #0x80 ; if (R6 > 128) RAM:1060D562 BLS loc_1060D566 ; R5 = 128 RAM:1060D564 MOV R5, #0x80 ; else RAM:1060D564 ; R5 = R6 RAM:1060D564 ; RAM:1060D564 ; count = R5 RAM:1060D566 RAM:1060D566 loc_1060D566 ; CODE XREF: ata_read_sectors+36j RAM:1060D566 LDR R0, =0x70008200 ; R0 = 0x70008200 (ATA_BASE) RAM:1060D568 MOV R1, #4 ; R1 = 4 = TRAN RAM:1060D56A STR R1, [R0,#0x38] ; SD_STATE_REG = TRAN RAM:1060D56C STR R5, [R0,#0x20] ; BLOCK_COUNT_REG = count RAM:1060D56C ; RAM:1060D56E LDRH R0, [R4,#0x10] ; R0 = inh(R4 + 0x10) = sector_size RAM:1060D570 LDR R2, =0x1C25 ; R2 = 0x1C25 = type RAM:1060D572 MUL R0, R7 ; R0 = start_block*sector_size RAM:1060D574 LSL R1, R0, #0x10 ; R1 = R0 << 16 RAM:1060D576 LSR R1, R1, #0x10 ; R1 = R1 >> 16 = R0 & 0xFFFF = (start_block*sector_size) & 0xFFFF = arg2 RAM:1060D578 STR R1, [SP] ; outl(arg2, SP) RAM:1060D57A STR R2, [SP,#4] ; outl(0x1C25, SP + 4) RAM:1060D57C MOV R2, #0 ; R2 = 0 = cmd2 RAM:1060D57E MOV R1, #0x12 ; R1 = 0x12 = READ_MULTIPLE_BLOCK = cmd1 RAM:1060D580 LSR R3, R0, #0x10 ; R3 = R0 >> 16 = (start_block*sector_size) >> 16 = arg1 RAM:1060D582 ADD R0, R4, #0 ; R0 = R4 RAM:1060D584 BL sd_command ; sd_command(READ_MULTIPLE_BLOCK, 0, arg1, arg2, 0x1C25) RAM:1060D584 ; RAM:1060D588 MOV R1, #1 ; R1 = 1 RAM:1060D58A ADD R0, R4, #0 ; R0 = R4 RAM:1060D58C BL sd_response ; sd_response(1) RAM:1060D58C ; RAM:1060D590 LDRH R0, [R4,#0x10] ; R0 = inh(R4 + 0x10) = sector_size RAM:1060D592 LDR R1, [SP,#0x10] ; R1 = inl(SP + 0x10) = blocks_done RAM:1060D594 ADD R3, R5, #0 ; R3 = R5 = count RAM:1060D596 LSR R0, R0, #1 ; R0 = R0 >> 1 = sector_size/2 RAM:1060D598 MUL R0, R1 ; R0 = R0*R1 = blocks_done*(sector_size/2) RAM:1060D59A LDR R1, [SP,#0x20] ; R1 = inl(SP + 0x20) = buf RAM:1060D59C LSL R0, R0, #1 ; R0 = R0 << 1 = 2*blocks_done*(sector_size/2) RAM:1060D59E ADD R2, R0, R1 ; R2 = R0 + R1 = buf + 2*blocks_done*(sector_size/2) RAM:1060D59E ; RAM:1060D5A0 LDR R1, =0x70008200 ; R1 = 0x70008200 (ATA_BASE) RAM:1060D5A2 ADD R1, #0x80 ; R1 = 0x70008280 (DATA_REG) RAM:1060D5A4 ADD R0, R4, #0 ; R0 = R4 RAM:1060D5A6 BL dma_read_setup ; dma_read_setup(0x70008280, R2, count) RAM:1060D5A6 ; RAM:1060D5AA ADD R0, R4, #0 ; R0 = R4 RAM:1060D5AC BL dma_start ; dma_start() RAM:1060D5AC ; RAM:1060D5B0 MOV R2, #1 ; R2 = 1 = type RAM:1060D5B2 MOV R1, #0 ; R1 = 0 = arg2 RAM:1060D5B4 STR R1, [SP] ; outl(0, SP) RAM:1060D5B6 STR R2, [SP,#4] ; outl(1, SP + 4) RAM:1060D5B8 MOV R2, #0 ; R2 = 0 = cmd2 RAM:1060D5BA MOV R1, #0xC ; R1 = 0xC = STOP_TRANSMISSION = cmd1 RAM:1060D5BC MOV R3, #0 ; R3 = 0 = arg1 RAM:1060D5BE ADD R0, R4, #0 ; R0 = R4 RAM:1060D5C0 BL sd_command ; sd_command(STOP_TRANSMISSION, 0, 0, 0, 1) RAM:1060D5C0 ; RAM:1060D5C4 MOV R1, #1 ; R1 = 1 RAM:1060D5C6 ADD R0, R4, #0 ; R0 = R4 RAM:1060D5C8 BL sd_response ; sd_response(1) RAM:1060D5CC RAM:1060D5CC loc_1060D5CC ; CODE XREF: ata_read_sectors+AAj RAM:1060D5CC MOV R1, #1 ; do { RAM:1060D5CC ; R1 = 1 RAM:1060D5CE ADD R0, R4, #0 ; R0 = R4 RAM:1060D5D0 BL sd_get_state ; state = sd_get_state() RAM:1060D5D4 CMP R0, #4 RAM:1060D5D6 BNE loc_1060D5CC ; } while (state != TRAN) RAM:1060D5D6 ; RAM:1060D5D8 LDR R0, [SP,#0xC] ; R0 = inl(SP + 0xC) /* this is also start_block */ RAM:1060D5DA ADD R7, R7, R5 ; start_block += count RAM:1060D5DC ADD R0, R0, R5 ; R0 += count RAM:1060D5DE STR R0, [SP,#0xC] ; outl(R0, SP + 0xC) RAM:1060D5DE ; RAM:1060D5E0 SUB R6, R6, R5 ; block_count -= count RAM:1060D5E2 BNE loc_1060D538 ; } while (block_count != 0) RAM:1060D5E2 ; RAM:1060D5E4 ADD SP, SP, #0x24 ; SP += 0x24 RAM:1060D5E6 POP {R4-R7} RAM:1060D5E8 POP {R3} RAM:1060D5EA MOV R0, #0 ; R0 = 0 RAM:1060D5EC BX R3 ; return RAM:1060D5EC ; End of function ata_read_sectors RAM:10603BA0 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ RAM:10603BA0 RAM:10603BA0 ; dma_read_setup(src=R1, dest=R2, count=R3) RAM:10603BA0 ; R1 = src = 0x70008280 (DATA_REG) RAM:10603BA0 ; R2 = dest RAM:10603BA0 ; R3 = block count RAM:10603BA0 ; RAM:10603BA0 RAM:10603BA0 dma_read_setup ; CODE XREF: sd_init_device+1EEp RAM:10603BA0 ; ata_read_sectors+7Ap RAM:10603BA0 CMP R3, #0x80 ; if (count > 0x80) RAM:10603BA2 BLS loc_10603BA8 ; { RAM:10603BA4 MOV R0, #1 ; R0 = 1 RAM:10603BA6 BX LR ; return RAM:10603BA6 ; } RAM:10603BA8 ; --------------------------------------------------------------------------- RAM:10603BA8 RAM:10603BA8 loc_10603BA8 ; CODE XREF: dma_read_setup+2j RAM:10603BA8 LDR R0, =0x6000B000 ; R0 = 0x6000B000 RAM:10603BAA STR R1, [R0,#0x18] ; outl(src, 0x6000B018) RAM:10603BAA ; RAM:10603BAC STR R2, [R0,#0x10] ; outl(dest, 0x6000B010) RAM:10603BAC ; RAM:10603BAE LDR R1, =0x10010000 ; R1 = 0x10010000 RAM:10603BB0 STR R1, [R0,#0x1C] ; outl(0x10010000, 0x6000B01C) RAM:10603BB0 ; RAM:10603BB2 LSL R1, R2, #0x1C ; R1 = dest << 28 RAM:10603BB4 BNE loc_10603BBC ; if (R1 == 0) RAM:10603BB6 MOVL R1, 0x5000000 ; R1 = 0x5000000 RAM:10603BBA B loc_10603BC0 ; else RAM:10603BBC ; --------------------------------------------------------------------------- RAM:10603BBC RAM:10603BBC loc_10603BBC ; CODE XREF: dma_read_setup+14j RAM:10603BBC MOVL R1, 0x4000000 ; R1 = 0x4000000 RAM:10603BC0 RAM:10603BC0 loc_10603BC0 ; CODE XREF: dma_read_setup+1Aj RAM:10603BC0 STR R1, [R0,#0x14] ; outl(R1, 0x6000B014) /* aligned/unaligned ?? */ RAM:10603BC0 ; RAM:10603BC2 LSL R1, R3, #7 ; R1 = count << 7 RAM:10603BC4 SUB R1, #1 ; R1 = (count << 7) - 1 RAM:10603BC6 LDR R2, =0x850D0000 ; R2 = 0x850D0000 RAM:10603BC8 LSL R1, R1, #2 ; R1 = ((count << 7) - 1) << 2 = 4*(128*count - 1) RAM:10603BCA ORR R1, R2 ; R1 = (((count << 7) - 1) << 2) | 0x850D0000 RAM:10603BCC STR R1, [R0] ; outl(R1, 0x6000B000) RAM:10603BCC ; RAM:10603BCE MOV R0, #0 ; R0 = 0 RAM:10603BD0 BX LR ; return RAM:10603BD0 ; End of function dma_read_setup RAM:10603BE0 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ RAM:10603BE0 RAM:10603BE0 ; dma_write_setup(dest=R1, src=R2, len=R3) RAM:10603BE0 ; R1 = dest = 0x70008280 (DATA_REG) RAM:10603BE0 ; R2 = src RAM:10603BE0 ; R3 = len RAM:10603BE0 ; RAM:10603BE0 RAM:10603BE0 dma_write_setup ; CODE XREF: sd_select_bank+8Ap RAM:10603BE0 ; ata_write_sectors+94p RAM:10603BE0 PUSH {R4-R6,LR} RAM:10603BE2 ADD R6, R1, #0 ; R6 = dest RAM:10603BE4 ADD R5, R2, #0 ; R5 = src RAM:10603BE6 ADD R4, R3, #0 ; R4 = len RAM:10603BE8 ADD R1, R3, #0 ; R1 = len RAM:10603BE8 ; RAM:10603BEA LDRH R0, [R0,#0x10] ; R0 = inh(R0 + 0x10) = sector_size RAM:10603BEC BL divide ; R0 = divide(R0, R1) = len/sector_size RAM:10603BF0 CMP R0, #0x80 ; if (R0 > 128) RAM:10603BF2 BLE loc_10603BFC ; { RAM:10603BF4 MOV R0, #1 ; R0 = 1 RAM:10603BF6 RAM:10603BF6 loc_10603BF6 ; CODE XREF: dma_write_setup+4Cj RAM:10603BF6 POP {R4-R6} RAM:10603BF8 POP {R3} ; return RAM:10603BFA BX R3 ; } RAM:10603BFC ; --------------------------------------------------------------------------- RAM:10603BFC RAM:10603BFC loc_10603BFC ; CODE XREF: dma_write_setup+12j RAM:10603BFC LDR R0, =0x6000B000 ; R0 = 0x6000B000 RAM:10603BFE STR R6, [R0,#0x18] ; outl(dest, 0x6000B018) RAM:10603C00 STR R5, [R0,#0x10] ; outl(src, 0x6000B010) RAM:10603C00 ; RAM:10603C02 LDR R1, =0x10010000 ; R1 = 0x10010000 RAM:10603C04 STR R1, [R0,#0x1C] ; outl(0x10010000, 0x6000B01C) RAM:10603C04 ; RAM:10603C06 LSL R1, R5, #0x1C ; R1 = src << 28 RAM:10603C08 BNE loc_10603C10 ; if (R1 == 0) RAM:10603C0A MOVL R1, 0x5000000 ; R1 = 0x5000000 RAM:10603C0E B loc_10603C14 ; else RAM:10603C10 ; --------------------------------------------------------------------------- RAM:10603C10 RAM:10603C10 loc_10603C10 ; CODE XREF: dma_write_setup+28j RAM:10603C10 MOVL R1, 0x4000000 ; R1 = 0x4000000 RAM:10603C14 RAM:10603C14 loc_10603C14 ; CODE XREF: dma_write_setup+2Ej RAM:10603C14 STR R1, [R0,#0x14] ; outl(R1, 0x6000B014) /* aligned/unaligned ?? */ RAM:10603C14 ; RAM:10603C16 CMP R4, #4 RAM:10603C18 BLS loc_10603C1E ; if (len > 4) RAM:10603C1A LSR R1, R4, #2 ; R1 = R4 >> 2 RAM:10603C1C B loc_10603C20 ; else RAM:10603C1E ; --------------------------------------------------------------------------- RAM:10603C1E RAM:10603C1E loc_10603C1E ; CODE XREF: dma_write_setup+38j RAM:10603C1E MOV R1, #1 ; R1 = 1 RAM:10603C20 RAM:10603C20 loc_10603C20 ; CODE XREF: dma_write_setup+3Cj RAM:10603C20 SUB R1, #1 ; R1-- RAM:10603C22 LDR R2, =0x8D0D0000 ; R2 = 0x8D0D0000 RAM:10603C24 LSL R1, R1, #2 ; R1 = R1 << 2 RAM:10603C26 ORR R1, R2 ; R1 = R1 | 0x8D0D0000 RAM:10603C28 STR R1, [R0] ; outl(R1 | 0x8D0D0000, 0x6000B000) RAM:10603C28 ; RAM:10603C2A MOV R0, #0 ; R0 = 0 RAM:10603C2C B loc_10603BF6 ; return RAM:10603C2C ; End of function dma_write_setup RAM:10603CB8 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ RAM:10603CB8 RAM:10603CB8 RAM:10603CB8 dma_start ; CODE XREF: sd_select_bank+90p RAM:10603CB8 ; sd_init_device+1F4p ... RAM:10603CB8 MOV R0, #1 ; R0 = 1 RAM:10603CBA LDR R1, =0x6000A000 ; R1 = 0x6000A000 RAM:10603CBC LSL R0, R0, #0x1F ; R0 = 1 << 0x1F = 0x80000000 RAM:10603CBE STR R0, [R1] ; outl(0x80000000, 0x6000A000) RAM:10603CBE ; RAM:10603CC0 LDR R1, =0x6000B000 ; R1 = 0x6000B000 RAM:10603CC2 RAM:10603CC2 loc_10603CC2 ; CODE XREF: dma_start+Ej RAM:10603CC2 LDR R0, [R1,#4] ; do { RAM:10603CC2 ; R0 = inl(0x6000B004) RAM:10603CC4 CMP R0, #0 RAM:10603CC6 BLT loc_10603CC2 ; } while (R0 < 0) RAM:10603CC6 ; RAM:10603CC8 BX LR ; return RAM:10603CC8 ; End of function dma_start