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)
|