/***************************************************************************
* NAME: DMADRAM.C
** COPYRIGHT:
** "Copyright (c) 1992, by FORTE
**
** "This software is furnished under a license and may be used,
** copied, or disclosed only in accordance with the terms of such
** license and with the inclusion of the above copyright notice.
** This software or any other copies thereof may not be provided or
** otherwise made available to any other person. No title to and
** ownership of the software is hereby transfered."
****************************************************************************
* CREATION DATE: 11/18/92
*--------------------------------------------------------------------------*
* VERSION DATE NAME DESCRIPTION
*> 1.0 11/18/92 Original
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include "forte.h"
#include "gf1hware.h"
#include "extern.h"
#include "gf1os.h"
#include "dma.h" /* Hardware defs for PC's dma controllers */
#include "gf1proto.h"
#include "osproto.h"
#include "ultraerr.h"
extern DMA_ENTRY _gf1_dma[]; /* Structure that holds data on PC's dma chan */
extern ULTRA_DATA _gf1_data; /* OS data structure */
int
UltraDramDmaBusy(void)
{
return(_gf1_dma[_gf1_data.dram_dma_chan-1].flags & DMA_PENDING);
}
void
UltraWaitDramDma(void)
{
_gf1_data.flags &= ~DRAM_DMA_NOWAIT;
ENTER_CRITICAL_ON;
while (_gf1_data.flags & DRAM_DMA_BUSY) /* wait for irq to clear this */
{
}
LEAVE_CRITICAL_ON;
}
/***************************************************************
* This function will prime the pc's dma controller for sending to
* or receiving data from the UltraSound. The last thing it does is
* start the transfer. It either wait for it to complete or it
* could return immediately ...
*
* NOTE: This example will NOT attempt to explain how the pc's
* dma controller works. If you want to know more than you
* can by looking at this code, there are lots of documents
* available that go into great detail.
***************************************************************/
int
UltraDmaDram_64K(void far *pc_ptr, unsigned int size, unsigned long ultra_ptr, unsigned char control, int wait)
//void far *pc_ptr; /* pointer to buffer in pc ram */
//unsigned int size; /* # of bytes to send/recieve */
//unsigned long ultra_ptr; /* physical addr in ultrasound to get/put data */
//unsigned char control; /* read or write dram (see gf1hware.h) */
//int wait;
{
DMA_ENTRY *tdma;
unsigned long dram_address;
int type;
int ret;
tdma = &_gf1_dma[_gf1_data.dram_dma_chan-1]; /* point to this dma data */
if (control & DMA_READ)
{
if (control & DMA_AUTO_INIT)
type = INDEF_READ;
else
type = READ_DMA;
}
else
{
if (control & DMA_AUTO_INIT)
type = INDEF_WRITE;
else
type = WRITE_DMA;
}
control &= ~DMA_AUTO_INIT; /* turn this off now ... */
ret = PrimeDma(pc_ptr,type,size,_gf1_data.dram_dma_chan);
if (ret != ULTRA_OK)
return(ret);
/* If its a 16 bit dma channel, an extra translation is necessary */
if (_gf1_data.dram_dma_chan >= 4)
dram_address = convert_to_16bit(ultra_ptr);
else
dram_address = ultra_ptr;
/* Only use the upper 16 bits. This means that an 8 bit xfer MUST */
/* start on a 16 byte boundary and a 16 bit xfer MUST start on a 32 */
/* byte boundary. */
dram_address >>= 4;
ENTER_CRITICAL;
outp(_gf1_data.reg_select,SET_DMA_ADDRESS);
outpw(_gf1_data.data_low,(unsigned int)dram_address);
LEAVE_CRITICAL;
/* Set flag that irq handler clears when the xfer is complete */
_gf1_data.flags |= DRAM_DMA_BUSY;
/* Now tell GF1 to start xfer ... */
tdma->cur_control = control;
UltraStartDramDma(control);
/* if required, wait till dma is done ... */
if (wait)
UltraWaitDramDma();
else
_gf1_data.flags |= DRAM_DMA_NOWAIT;
return(ULTRA_OK);
}
/***************************************************************
* This function will download/upload up to 64K of data into/out the
* dram on the ultrasound card. Since the card cannot DMA
* across 256K boundaries, this routine will split up the xfer ....
***************************************************************/
static int
UltraDmaDram(void far *pc_ptr, unsigned int size, unsigned long ultra_ptr, unsigned char control, int wait)
// void far *pc_ptr; /* pointer to buffer in pc ram */
// unsigned int size; /* # of bytes to send/recieve */
// unsigned long ultra_ptr; /* physical addr in ultrasound to get/put data */
// unsigned char control;/* read or write dram (see gf1defs.h) */
// int wait; /* flag to wait until xfer is complete.... */
{
unsigned long end;
long start_page,end_page;
unsigned int start_size;
void far *nxt_pc_ptr;
unsigned long nxt_ptr;
unsigned int nxt_size;
int two_flag = 0;
int ret;
end = ultra_ptr + (unsigned long)size - 1;
start_page = ultra_ptr >> 18; /* isolate the 256K page */
end_page = end >> 18; /* isolate the 256K page */
if (start_page != end_page) /* crossed page boundary ... */
{
nxt_ptr = end_page << 18; /* where second part goes in DRAM */
nxt_size = end - nxt_ptr; /* How much to put there */
start_size = size - nxt_size; /* How much in first page of DRAM */
nxt_pc_ptr = (void far *)((char far *)pc_ptr + start_size); /* where in PC RAM is second part */
two_flag = 1;
}
else
{
start_size = size;
}
ret = UltraDmaDram_64K(pc_ptr, start_size, ultra_ptr, control, wait);
if (ret != ULTRA_OK)
return(ret);
/* Now send second half */
/* Probably SHOULD put this in the IRQ handler ... */
if (two_flag)
{
if (!wait) /* Gotta wait so I can send next page ... */
UltraWaitDramDma();
ret = UltraDmaDram_64K(nxt_pc_ptr, nxt_size, nxt_ptr, control, wait);
if (ret != ULTRA_OK)
return(ret);
}
return(ULTRA_OK);
}
int
UltraDownload(void far *dataptr,unsigned char control,unsigned long dram_loc,unsigned int len,int wait)
// void far *dataptr;
// unsigned char control;
// unsigned long dram_loc;
// unsigned int len;
// int wait;
{
int val;
control &= ~DMA_READ; /* turn off read bit ... (write to dram) */
val = UltraDmaDram(dataptr, len, dram_loc, control, wait);
return(val);
}
int
UltraUpload(void far *dataptr,unsigned char control,unsigned long dram_loc,unsigned int len,int wait)
// void far *dataptr;
// unsigned char control;
// unsigned long dram_loc;
// unsigned int len;
// int wait;
{
int val;
control |= DMA_READ; /* turn on read bit ... */
val = UltraDmaDram(dataptr, len, dram_loc, control, wait);
return(val);
}