mem.c (4335B)
1 #include <stdlib.h> 2 #include <string.h> 3 #include <stdio.h> 4 #include "mem.h" 5 #include "types.h" 6 #include "util.h" 7 #include "log.h" 8 9 Channel* 10 CHANNEL_new(void) 11 { 12 Channel* ch = (Channel*)malloc(sizeof(Channel)); 13 ch->enable = 0; 14 ch->direction = DIR_TO_RAM; 15 ch->step = STEP_INCREMENT; 16 ch->sync = SYNC_MANUAL; 17 ch->base = 0; 18 ch->trigger = 0; 19 ch->chop = 0; 20 ch->chop_dma_sz = 0; 21 ch->chop_cpu_sz = 0; 22 ch->dummy = 0; 23 ch->block_size = 0; 24 ch->block_count = 0; 25 return ch; 26 } 27 28 u32 29 CHANNEL_control(Channel* ch) 30 { 31 u32 r; 32 r = 0; 33 34 r |= ((u32)ch->direction) << 0; 35 r |= ((u32)ch->step) << 1; 36 r |= ((u32)ch->chop) << 8; 37 r |= ((u32)ch->sync) << 9; 38 r |= ((u32)ch->chop_dma_sz) << 16; 39 r |= ((u32)ch->chop_cpu_sz) << 20; 40 r |= ((u32)ch->enable) << 24; 41 r |= ((u32)ch->trigger) << 28; 42 r |= ((u32)ch->dummy) << 29; 43 44 return r; 45 } 46 47 void 48 CHANNEL_set_control(Channel* ch, u32 val) 49 { 50 ch->direction = (Direction)(val & 1); 51 ch->step = (Step)((val >> 1) & 1); 52 ch->chop = (val >> 8) & 1; 53 ch->sync = (Sync)((val >> 9) & 3); 54 ch->chop_dma_sz = (u8)((val >> 16) & 7); 55 ch->chop_cpu_sz = (u8)((val >> 20) & 7); 56 ch->enable = ((val >> 24) & 1); 57 ch->trigger = ((val >> 28) & 1); 58 ch->dummy = (u8)((val >> 29) & 3); 59 } 60 61 u32 62 CHANNEL_base(Channel* ch) 63 { 64 return ch->base; 65 } 66 67 void 68 CHANNEL_set_base(Channel* ch, u32 val) 69 { 70 ch->base = val & 0xffffff; 71 } 72 73 u32 74 CHANNEL_block_control(Channel* ch) 75 { 76 u32 bs, bc; 77 78 bs = (u32)ch->block_size; 79 bc = (u32)ch->block_count; 80 81 return (bc << 16) | bs; 82 } 83 84 void 85 CHANNEL_set_block_control(Channel* ch, u32 val) 86 { 87 ch->block_size = (u16)val; 88 ch->block_count = (u16)(val >> 16); 89 } 90 91 u8 92 CHANNEL_active(Channel* ch) 93 { 94 u8 trigger; 95 switch (ch->sync) 96 { 97 case SYNC_MANUAL: trigger = ch->trigger; break; 98 default: trigger = 1; break; 99 } 100 return ch->enable && trigger; 101 102 } 103 104 u8 105 CHANNEL_transfer_size(Channel* ch, u32 *res) 106 { 107 switch (ch->sync) { 108 case SYNC_MANUAL: 109 *res = (u32)ch->block_size; 110 return 1; 111 case SYNC_REQUEST: 112 *res = (u32)((u32)ch->block_size * (u32)(ch->block_count)); 113 return 1; 114 case SYNC_LINKED_LIST: return 0; 115 default: log_fatal("UNREACHABLE"); exit(EXIT_FAILURE); 116 } 117 } 118 119 void 120 CHANNEL_done(Channel* ch) 121 { 122 ch->enable = 0; 123 ch->trigger = 0; 124 } 125 126 DMA* 127 DMA_new(void) 128 { 129 DMA* dma = (DMA*)malloc(sizeof(DMA)); 130 dma->control = 0x07654321; 131 dma->irq_en = 0; 132 dma->channel_irq_en = 0; 133 dma->channel_irq_flags = 0; 134 dma->force_irq = 0; 135 dma->irq_dummy = 0; 136 memset(dma->channels, 0, sizeof(Channel)*7); 137 return dma; 138 } 139 140 u32 141 DMA_control(DMA* dma) 142 { 143 return dma->control; 144 } 145 146 void 147 DMA_set_control(DMA* dma, u32 val) 148 { 149 dma->control = val; 150 } 151 152 u8 153 DMA_irq(DMA* dma) 154 { 155 u32 channel_irq; 156 channel_irq = dma->channel_irq_flags & dma->channel_irq_en; 157 return (dma->force_irq || (dma->irq_en && channel_irq != 0)); 158 } 159 160 u32 161 DMA_interrupt(DMA* dma) 162 { 163 u32 r; 164 r = 0; 165 166 r |= (u32)dma->irq_dummy; 167 r |= ((u32)dma->force_irq) << 15; 168 r |= ((u32)dma->channel_irq_en) << 16; 169 r |= ((u32)dma->irq_en) << 23; 170 r |= ((u32)dma->channel_irq_flags) << 24; 171 r |= ((u32)DMA_irq(dma)) << 31; 172 173 return r; 174 } 175 176 void 177 DMA_set_interrupt(DMA* dma, u32 val) 178 { 179 u32 ack; 180 181 dma->irq_dummy = (u8)(val & 0x3f); 182 dma->force_irq = (val >> 15) & 1; 183 dma->channel_irq_en = (u8)((val >> 16) & 0x7f); 184 dma->irq_en = (val >> 23) & 1; 185 186 ack = (u8)((val >> 24) & 0x3f); 187 dma->channel_irq_flags &= ~ack; 188 } 189 190 RAM* 191 RAM_new(void) 192 { 193 RAM* ram = (RAM*)(malloc(sizeof(RAM))); 194 ram->data = (u8*)(malloc(sizeof(u8) * RAM_SIZE)); 195 196 memset(ram->data, 0xca, RAM_SIZE); 197 return ram; 198 } 199 200 u32 201 RAM_load32(RAM* r, u32 offset) 202 { 203 return (r->data[offset + 3] << 24) | 204 (r->data[offset + 2] << 16) | 205 (r->data[offset + 1] << 8) | 206 (r->data[offset + 0]); 207 } 208 209 u16 210 RAM_load16(RAM* r, u32 offset) 211 { 212 u16 b0, b1; 213 214 b0 = (u16)r->data[offset]; 215 b1 = (u16)r->data[offset + 1]; 216 217 return b0 | (b1 << 8); 218 } 219 220 u8 221 RAM_load8(RAM* r, u32 offset) 222 { 223 return r->data[offset]; 224 } 225 226 void 227 RAM_store8(RAM* r, u32 offset, u8 val) 228 { 229 r->data[offset]=val; 230 } 231 232 void 233 RAM_store16(RAM* r, u32 offset, u16 val) 234 { 235 r->data[offset]=val; 236 r->data[offset+1] = val >> 8; 237 } 238 239 void 240 RAM_store32(RAM* r, u32 offset, u32 val) 241 { 242 u8 b0 = val; 243 u8 b1 = (val >> 8); 244 u8 b2 = (val >> 16); 245 u8 b3 = (val >> 24); 246 247 r->data[offset + 0] = b0; 248 r->data[offset + 1] = b1; 249 r->data[offset + 2] = b2; 250 r->data[offset + 3] = b3; 251 }