use physical memory access functions for DMA
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@649 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
8dc75d7535
commit
f9e92e973f
54
hw/fdc.c
54
hw/fdc.c
@ -26,7 +26,6 @@
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "vl.h"
|
||||
|
||||
/********************************************************/
|
||||
@ -218,8 +217,7 @@ static void fd_reset (fdrive_t *drv)
|
||||
|
||||
static void fdctrl_reset (int do_irq);
|
||||
static void fdctrl_reset_fifo (void);
|
||||
static int fdctrl_transfer_handler (uint32_t addr, int size, int *irq);
|
||||
static int fdctrl_misc_handler (int duknwo);
|
||||
static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size);
|
||||
static void fdctrl_raise_irq (uint8_t status);
|
||||
|
||||
static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg);
|
||||
@ -310,8 +308,7 @@ void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
|
||||
fdctrl.config = 0x40; /* Implicit seek, polling & FIFO enabled */
|
||||
if (fdctrl.dma_chann != -1) {
|
||||
fdctrl.dma_en = 1;
|
||||
DMA_register_channel(dma_chann, &fdctrl_transfer_handler,
|
||||
&fdctrl_misc_handler);
|
||||
DMA_register_channel(dma_chann, fdctrl_transfer_handler, &fdctrl);
|
||||
} else {
|
||||
fdctrl.dma_en = 0;
|
||||
}
|
||||
@ -721,6 +718,7 @@ static void fdctrl_start_transfer (int direction)
|
||||
* recall us...
|
||||
*/
|
||||
DMA_hold_DREQ(fdctrl.dma_chann);
|
||||
DMA_schedule(fdctrl.dma_chann);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -749,12 +747,13 @@ static void fdctrl_start_transfer_del (int direction)
|
||||
}
|
||||
|
||||
/* handlers for DMA transfers */
|
||||
static int fdctrl_transfer_handler (uint32_t addr, int size, int *irq)
|
||||
/* XXX: the partial transfer logic seems to be broken */
|
||||
static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size)
|
||||
{
|
||||
fdrive_t *cur_drv, *drv0, *drv1;
|
||||
void *orig;
|
||||
int len;
|
||||
uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00;
|
||||
uint8_t tmpbuf[FD_SECTOR_LEN];
|
||||
|
||||
fdctrl_reset_irq();
|
||||
if (!(fdctrl.state & FD_CTRL_BUSY)) {
|
||||
@ -764,8 +763,6 @@ static int fdctrl_transfer_handler (uint32_t addr, int size, int *irq)
|
||||
drv0 = &fdctrl.drives[fdctrl.bootsel];
|
||||
drv1 = &fdctrl.drives[1 - fdctrl.bootsel];
|
||||
cur_drv = fdctrl.cur_drv == 0 ? drv0 : drv1;
|
||||
// *irq = fdctrl.irq_lvl;
|
||||
*irq = -1;
|
||||
if (fdctrl.data_dir == FD_DIR_SCANE || fdctrl.data_dir == FD_DIR_SCANL ||
|
||||
fdctrl.data_dir == FD_DIR_SCANH)
|
||||
status2 = 0x04;
|
||||
@ -779,35 +776,34 @@ static int fdctrl_transfer_handler (uint32_t addr, int size, int *irq)
|
||||
fdctrl.data_len, fdctrl.cur_drv, cur_drv->head,
|
||||
cur_drv->track, cur_drv->sect, fd_sector(cur_drv),
|
||||
fd_sector(cur_drv) * 512);
|
||||
if (len < FD_SECTOR_LEN) {
|
||||
memset(&fdctrl.fifo[FD_SECTOR_LEN - len], 0,
|
||||
FD_SECTOR_LEN - len - 1);
|
||||
orig = fdctrl.fifo;
|
||||
} else {
|
||||
orig = (void *)(addr + fdctrl.data_pos);
|
||||
}
|
||||
if (fdctrl.data_dir != FD_DIR_WRITE) {
|
||||
/* READ & SCAN commands */
|
||||
if (cur_drv->bs == NULL) {
|
||||
fdctrl_stop_transfer(0x40, 0x00, 0x00);
|
||||
goto transfer_error;
|
||||
}
|
||||
|
||||
if (bdrv_read(cur_drv->bs, fd_sector(cur_drv), orig, 1) < 0) {
|
||||
if (bdrv_read(cur_drv->bs, fd_sector(cur_drv), tmpbuf, 1) < 0) {
|
||||
FLOPPY_DPRINTF("Floppy: error getting sector %d\n",
|
||||
fd_sector(cur_drv));
|
||||
/* Sure, image size is too small... */
|
||||
memset((void *)(addr + fdctrl.data_pos), 0, FD_SECTOR_LEN);
|
||||
memset(tmpbuf, 0, FD_SECTOR_LEN);
|
||||
}
|
||||
if (fdctrl.data_dir == FD_DIR_READ) {
|
||||
cpu_physical_memory_write(addr + fdctrl.data_pos,
|
||||
tmpbuf, len);
|
||||
if (len < FD_SECTOR_LEN) {
|
||||
memcpy((void *)(addr + fdctrl.data_pos),
|
||||
fdctrl.fifo, FD_SECTOR_LEN);
|
||||
memcpy(&fdctrl.fifo[0], tmpbuf + len, FD_SECTOR_LEN - len);
|
||||
memset(&fdctrl.fifo[FD_SECTOR_LEN - len], 0, len);
|
||||
}
|
||||
} else {
|
||||
int ret;
|
||||
ret = memcmp((void *)(addr + fdctrl.data_pos),
|
||||
fdctrl.fifo, FD_SECTOR_LEN);
|
||||
/* XXX: what to do if not enough data ? */
|
||||
cpu_physical_memory_read(addr + fdctrl.data_pos,
|
||||
fdctrl.fifo, len);
|
||||
if (len < FD_SECTOR_LEN) {
|
||||
memset(&fdctrl.fifo[len], 0, FD_SECTOR_LEN - len);
|
||||
}
|
||||
ret = memcmp(tmpbuf, fdctrl.fifo, FD_SECTOR_LEN);
|
||||
if (ret == 0) {
|
||||
status2 = 0x08;
|
||||
goto end_transfer;
|
||||
@ -820,8 +816,12 @@ static int fdctrl_transfer_handler (uint32_t addr, int size, int *irq)
|
||||
}
|
||||
} else {
|
||||
/* WRITE commands */
|
||||
cpu_physical_memory_read(addr + fdctrl.data_pos, tmpbuf, len);
|
||||
if (len < FD_SECTOR_LEN) {
|
||||
memset(tmpbuf + len, 0, FD_SECTOR_LEN - len);
|
||||
}
|
||||
if (cur_drv->bs == NULL ||
|
||||
bdrv_write(cur_drv->bs, fd_sector(cur_drv), orig, 1) < 0) {
|
||||
bdrv_write(cur_drv->bs, fd_sector(cur_drv), tmpbuf, 1) < 0) {
|
||||
FLOPPY_ERROR("writting sector %d\n", fd_sector(cur_drv));
|
||||
fdctrl_stop_transfer(0x60, 0x00, 0x00);
|
||||
goto transfer_error;
|
||||
@ -871,12 +871,6 @@ transfer_error:
|
||||
return fdctrl.data_pos;
|
||||
}
|
||||
|
||||
/* Unused... */
|
||||
static int fdctrl_misc_handler (int duknwo)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Data register : 0x05 */
|
||||
static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg)
|
||||
{
|
||||
|
21
hw/sb16.c
21
hw/sb16.c
@ -25,6 +25,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "vl.h"
|
||||
|
||||
#define MIN(a, b) ((a)>(b)?(b):(a))
|
||||
@ -569,6 +570,7 @@ void SB16_run (void)
|
||||
static int write_audio (uint32_t addr, int len, int size)
|
||||
{
|
||||
int temp, net;
|
||||
uint8_t tmpbuf[4096];
|
||||
|
||||
temp = size;
|
||||
|
||||
@ -582,8 +584,10 @@ static int write_audio (uint32_t addr, int len, int size)
|
||||
left_till_end = len - dsp.dma_pos;
|
||||
|
||||
to_copy = MIN (temp, left_till_end);
|
||||
|
||||
copied = AUD_write ((void *) (addr + dsp.dma_pos), to_copy);
|
||||
if (to_copy > sizeof(tmpbuf))
|
||||
to_copy = sizeof(tmpbuf);
|
||||
cpu_physical_memory_read(addr + dsp.dma_pos, tmpbuf, to_copy);
|
||||
copied = AUD_write (tmpbuf, to_copy);
|
||||
|
||||
temp -= copied;
|
||||
dsp.dma_pos += copied;
|
||||
@ -601,7 +605,7 @@ static int write_audio (uint32_t addr, int len, int size)
|
||||
return net;
|
||||
}
|
||||
|
||||
static int SB_read_DMA (uint32_t addr, int size, int *_irq)
|
||||
static int SB_read_DMA (void *opaque, target_ulong addr, int size)
|
||||
{
|
||||
int free, till, copy, written;
|
||||
|
||||
@ -644,7 +648,7 @@ static int SB_read_DMA (uint32_t addr, int size, int *_irq)
|
||||
mixer.regs[0x82] |= mixer.regs[0x80];
|
||||
if (0 == noirq) {
|
||||
ldebug ("request irq\n");
|
||||
*_irq = sb.irq;
|
||||
pic_set_irq(sb.irq, 1);
|
||||
}
|
||||
|
||||
if (0 == dsp.dma_auto) {
|
||||
@ -663,11 +667,6 @@ static int SB_read_DMA (uint32_t addr, int size, int *_irq)
|
||||
return dsp.dma_pos;
|
||||
}
|
||||
|
||||
static int dma_misc_handler (int moo)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int magic_of_irq (int irq)
|
||||
{
|
||||
switch (irq) {
|
||||
@ -731,6 +730,6 @@ void SB16_init (void)
|
||||
register_ioport_read (sb.port + 0x5, 1, mixer_read, 1);
|
||||
register_ioport_write (sb.port + 0x5, 1, mixer_write_datab, 1);
|
||||
|
||||
DMA_register_channel (sb.hdma, SB_read_DMA, dma_misc_handler);
|
||||
DMA_register_channel (sb.dma, SB_read_DMA, dma_misc_handler);
|
||||
DMA_register_channel (sb.hdma, SB_read_DMA, NULL);
|
||||
DMA_register_channel (sb.dma, SB_read_DMA, NULL);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user