| 86 | } |
| 87 | |
| 88 | u32 FLASHread32(u32 addr, int size) |
| 89 | { |
| 90 | u32 value, refill = 0; |
| 91 | |
| 92 | switch (addr) |
| 93 | { |
| 94 | case FLASH_R_DATA: |
| 95 | memcpy(&value, &data[counter], size); |
| 96 | counter += size; |
| 97 | DevCon.WriteLn("DEV9: *FLASH DATA %dbit read 0x%08lX %s", size * 8, value, (ctrl & FLASH_PP_READ) ? "READ_ENABLE" : "READ_DISABLE"); |
| 98 | if (cmd == SM_CMD_READ3) |
| 99 | { |
| 100 | if (counter >= PAGE_SIZE_ECC) |
| 101 | { |
| 102 | counter = PAGE_SIZE; |
| 103 | refill = 1; |
| 104 | } |
| 105 | } |
| 106 | else |
| 107 | { |
| 108 | if ((ctrl & FLASH_PP_NOECC) && (counter >= PAGE_SIZE)) |
| 109 | { |
| 110 | counter %= PAGE_SIZE; |
| 111 | refill = 1; |
| 112 | } |
| 113 | else if (!(ctrl & FLASH_PP_NOECC) && (counter >= PAGE_SIZE_ECC)) |
| 114 | { |
| 115 | counter %= PAGE_SIZE_ECC; |
| 116 | refill = 1; |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | if (refill) |
| 121 | { |
| 122 | ctrl &= ~FLASH_PP_READY; |
| 123 | address += PAGE_SIZE; |
| 124 | address %= CARD_SIZE; |
| 125 | memcpy(data, file + (address >> PAGE_SIZE_BITS) * PAGE_SIZE_ECC, PAGE_SIZE); |
| 126 | calculateECC(data); // calculate ECC; should be in the file already |
| 127 | ctrl |= FLASH_PP_READY; |
| 128 | } |
| 129 | |
| 130 | return value; |
| 131 | |
| 132 | case FLASH_R_CMD: |
| 133 | DevCon.WriteLn("DEV9: *FLASH CMD %dbit read %s DENIED", size * 8, getCmdName(cmd)); |
| 134 | return cmd; |
| 135 | |
| 136 | case FLASH_R_ADDR: |
| 137 | DevCon.WriteLn("DEV9: *FLASH ADDR %dbit read DENIED", size * 8); |
| 138 | return 0; |
| 139 | |
| 140 | case FLASH_R_CTRL: |
| 141 | DevCon.WriteLn("DEV9: *FLASH CTRL %dbit read 0x%08lX", size * 8, ctrl); |
| 142 | return ctrl; |
| 143 | |
| 144 | case FLASH_R_ID: |
| 145 | if (cmd == SM_CMD_READID) |
no test coverage detected