Revision 16f62432 hw/dma.c
b/hw/dma.c | ||
---|---|---|
39 | 39 |
#define ldebug(...) |
40 | 40 |
#endif |
41 | 41 |
|
42 |
#define MEM_REAL(addr) ((addr)+(uint32_t)(phys_ram_base)) |
|
43 | 42 |
#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0]))) |
44 | 43 |
|
45 | 44 |
struct dma_regs { |
... | ... | |
49 | 48 |
uint8_t page; |
50 | 49 |
uint8_t dack; |
51 | 50 |
uint8_t eop; |
52 |
DMA_read_handler read_handler;
|
|
53 |
DMA_misc_handler misc_handler;
|
|
51 |
DMA_transfer_handler transfer_handler;
|
|
52 |
void *opaque;
|
|
54 | 53 |
}; |
55 | 54 |
|
56 | 55 |
#define ADDR 0 |
... | ... | |
284 | 283 |
{ |
285 | 284 |
struct dma_regs *r; |
286 | 285 |
int n; |
287 |
int irq; |
|
288 |
uint32_t addr; |
|
286 |
target_ulong addr; |
|
289 | 287 |
/* int ai, dir; */ |
290 | 288 |
|
291 | 289 |
r = dma_controllers[ncont].regs + ichan; |
292 | 290 |
/* ai = r->mode & 16; */ |
293 | 291 |
/* dir = r->mode & 32 ? -1 : 1; */ |
294 | 292 |
|
295 |
addr = MEM_REAL ((r->page << 16) | r->now[ADDR]); |
|
296 |
|
|
297 |
irq = -1; |
|
298 |
n = r->read_handler (addr, (r->base[COUNT] << ncont) + (1 << ncont), &irq); |
|
293 |
addr = (r->page << 16) | r->now[ADDR]; |
|
294 |
n = r->transfer_handler (r->opaque, addr, |
|
295 |
(r->base[COUNT] << ncont) + (1 << ncont)); |
|
299 | 296 |
r->now[COUNT] = n; |
300 | 297 |
|
301 |
ldebug ("dma_pos %d irq %d size %d\n", |
|
302 |
n, irq, (r->base[1] << ncont) + (1 << ncont)); |
|
303 |
|
|
304 |
if (-1 != irq) { |
|
305 |
pic_set_irq (irq, 1); |
|
306 |
} |
|
298 |
ldebug ("dma_pos %d size %d\n", |
|
299 |
n, (r->base[1] << ncont) + (1 << ncont)); |
|
307 | 300 |
} |
308 | 301 |
|
309 | 302 |
void DMA_run (void) |
310 | 303 |
{ |
311 |
static int in_dma; |
|
312 | 304 |
struct dma_cont *d; |
313 | 305 |
int icont, ichan; |
314 | 306 |
|
315 |
if (in_dma) { |
|
316 |
log ("attempt to re-enter dma\n"); |
|
317 |
return; |
|
318 |
} |
|
319 |
|
|
320 |
in_dma = 1; |
|
321 | 307 |
d = dma_controllers; |
322 | 308 |
|
323 | 309 |
for (icont = 0; icont < 2; icont++, d++) { |
... | ... | |
330 | 316 |
channel_run (icont, ichan); |
331 | 317 |
} |
332 | 318 |
} |
333 |
in_dma = 0; |
|
334 | 319 |
} |
335 | 320 |
|
336 | 321 |
void DMA_register_channel (int nchan, |
337 |
DMA_read_handler read_handler,
|
|
338 |
DMA_misc_handler misc_handler)
|
|
322 |
DMA_transfer_handler transfer_handler,
|
|
323 |
void *opaque)
|
|
339 | 324 |
{ |
340 | 325 |
struct dma_regs *r; |
341 | 326 |
int ichan, ncont; |
... | ... | |
344 | 329 |
ichan = nchan & 3; |
345 | 330 |
|
346 | 331 |
r = dma_controllers[ncont].regs + ichan; |
347 |
r->read_handler = read_handler; |
|
348 |
r->misc_handler = misc_handler; |
|
332 |
r->transfer_handler = transfer_handler; |
|
333 |
r->opaque = opaque; |
|
334 |
} |
|
335 |
|
|
336 |
/* request the emulator to transfer a new DMA memory block ASAP */ |
|
337 |
void DMA_schedule(int nchan) |
|
338 |
{ |
|
339 |
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); |
|
349 | 340 |
} |
350 | 341 |
|
351 | 342 |
void DMA_init (void) |
Also available in: Unified diff