diff --git a/hw/dma.c b/hw/dma.c index ee7cc42ec9647f78278049fa2c7d5b0b504ce072..2c85b6e7bb86e37d815ae4eed02ea4f9885d6c56 100644 --- a/hw/dma.c +++ b/hw/dma.c @@ -39,7 +39,6 @@ #define ldebug(...) #endif -#define MEM_REAL(addr) ((addr)+(uint32_t)(phys_ram_base)) #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0]))) struct dma_regs { @@ -49,8 +48,8 @@ struct dma_regs { uint8_t page; uint8_t dack; uint8_t eop; - DMA_read_handler read_handler; - DMA_misc_handler misc_handler; + DMA_transfer_handler transfer_handler; + void *opaque; }; #define ADDR 0 @@ -284,40 +283,27 @@ static void channel_run (int ncont, int ichan) { struct dma_regs *r; int n; - int irq; - uint32_t addr; + target_ulong addr; /* int ai, dir; */ r = dma_controllers[ncont].regs + ichan; /* ai = r->mode & 16; */ /* dir = r->mode & 32 ? -1 : 1; */ - addr = MEM_REAL ((r->page << 16) | r->now[ADDR]); - - irq = -1; - n = r->read_handler (addr, (r->base[COUNT] << ncont) + (1 << ncont), &irq); + addr = (r->page << 16) | r->now[ADDR]; + n = r->transfer_handler (r->opaque, addr, + (r->base[COUNT] << ncont) + (1 << ncont)); r->now[COUNT] = n; - ldebug ("dma_pos %d irq %d size %d\n", - n, irq, (r->base[1] << ncont) + (1 << ncont)); - - if (-1 != irq) { - pic_set_irq (irq, 1); - } + ldebug ("dma_pos %d size %d\n", + n, (r->base[1] << ncont) + (1 << ncont)); } void DMA_run (void) { - static int in_dma; struct dma_cont *d; int icont, ichan; - if (in_dma) { - log ("attempt to re-enter dma\n"); - return; - } - - in_dma = 1; d = dma_controllers; for (icont = 0; icont < 2; icont++, d++) { @@ -330,12 +316,11 @@ void DMA_run (void) channel_run (icont, ichan); } } - in_dma = 0; } void DMA_register_channel (int nchan, - DMA_read_handler read_handler, - DMA_misc_handler misc_handler) + DMA_transfer_handler transfer_handler, + void *opaque) { struct dma_regs *r; int ichan, ncont; @@ -344,8 +329,14 @@ void DMA_register_channel (int nchan, ichan = nchan & 3; r = dma_controllers[ncont].regs + ichan; - r->read_handler = read_handler; - r->misc_handler = misc_handler; + r->transfer_handler = transfer_handler; + r->opaque = opaque; +} + +/* request the emulator to transfer a new DMA memory block ASAP */ +void DMA_schedule(int nchan) +{ + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); } void DMA_init (void) diff --git a/vl.h b/vl.h index ebc809a1c3cbeb49ba9cd938f81ccebf3f978909..c8c22ac397382b0a2562b723302a0f92447734a9 100644 --- a/vl.h +++ b/vl.h @@ -24,8 +24,9 @@ #ifndef VL_H #define VL_H +#include "cpu.h" + /* vl.c */ -struct CPUState; extern int reset_requested; extern int64_t ticks_per_sec; @@ -128,17 +129,15 @@ int AUD_get_buffer_size (void); void AUD_init (void); /* dma.c */ -typedef int (*DMA_read_handler) (uint32_t addr, int size, int *irq); -typedef int (*DMA_misc_handler) (int); - +typedef int (*DMA_transfer_handler) (void *opaque, target_ulong addr, int size); int DMA_get_channel_mode (int nchan); void DMA_hold_DREQ (int nchan); void DMA_release_DREQ (int nchan); +void DMA_schedule(int nchan); void DMA_run (void); void DMA_init (void); void DMA_register_channel (int nchan, - DMA_read_handler read_handler, - DMA_misc_handler misc_handler); + DMA_transfer_handler transfer_handler, void *opaque); /* sb16.c */ void SB16_run (void);