/*************************************************************************** * 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 #include #include #include #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); }