⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lsys5.cpp

📁 ldraw_DOS游戏开发包
💻 CPP
字号:
#include <lsys.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>

///////////////////////////////////////////////////////////////////////////
char *lsys_dos_alloc(int size,short *selector);
void  lsys_dos_free(short selector);
void  lsys_mem_lock(void *mem,ushort size);
void  lsys_mem_unlock(void *mem,ushort size);
char  lsys_dma_alloc(int size,long *phy,short *selector);
char  lsys_dma_free(int size,long phy,short selector);

void  lsys_dma_start(char channel,unsigned long addr,short size,char auto_init,char input);
void  lsys_dma_stop(char channel);
long  lsys_dma_todo(char channel);
///////////////////////////////////////////////////////////////////////
char *lsys_dos_alloc(int size,short *selector)
{  union REGS r;
   r.x.eax = 0x0100; r.x.ebx = (size + 15) >> 4;
   int386(0x31, &r, &r); if (r.x.cflag) return NULL;
   *selector = r.w.dx;
   return (char*)((r.x.eax & 0xFFFF) << 4);
}
void  lsys_dos_free(short selector)
{ union REGS r;
  r.x.eax = 0x0101; r.w.dx = selector;
  int386(0x31, &r, &r);
}
void  lsys_mem_lock(void *mem,ushort size)
{   union REGS  r;
    r.x.eax = 0x0600;
    r.w.bx = (FP_OFF(mem) & 0xFFFF0000) >> 16;
    r.w.cx = FP_OFF(mem) & 0x0000FFFF;
    r.w.si = 0;
    r.w.di = size;
    int386(0x31, &r, &r);
}
void  lsys_mem_unlock(void *mem,ushort size)
{   union REGS  r;    
    r.x.eax = 0x0601;
    r.w.bx = (FP_OFF(mem) & 0xFFFF0000) >> 16;
    r.w.cx = FP_OFF(mem) & 0x0000FFFF;
    r.w.si = 0;
    r.w.di = size;
    int386(0x31, &r, &r);
}
char  lsys_dma_alloc(int size,long *phy,short *selector)
{ *phy=(long)lsys_dos_alloc(size*2,selector);
  if (*phy==NULL) return -1;
  if ((*phy>>16) != ((*phy+size)>>16) ) *phy+=size;
  lsys_mem_lock((char*)*phy,size);
  return 0;
}
char  lsys_dma_free(int size,long phy,short selector)
{ if (phy==0||size==0) return -1;
  lsys_mem_unlock((char*)phy,size);
  lsys_dos_free(selector);
  return 0;
}
///////////////////////////////////////////////////////////////////////
/* DMA Controler #1 (8-bit controller) */
#define DMA1_STAT       0x08            /* read status register */
#define DMA1_WCMD       0x08            /* write command register */
#define DMA1_WREQ       0x09            /* write request register */
#define DMA1_SNGL       0x0A            /* write single bit register */
#define DMA1_MODE       0x0B            /* write mode register */
#define DMA1_CLRFF      0x0C            /* clear byte ptr flip/flop */
#define DMA1_MCLR       0x0D            /* master clear register */
#define DMA1_CLRM       0x0E            /* clear mask register */
#define DMA1_WRTALL     0x0F            /* write all mask register */
/* DMA Controler #2 (16-bit controller) */
#define DMA2_STAT       0xD0            /* read status register */
#define DMA2_WCMD       0xD0            /* write command register */
#define DMA2_WREQ       0xD2            /* write request register */
#define DMA2_SNGL       0xD4            /* write single bit register */
#define DMA2_MODE       0xD6            /* write mode register */
#define DMA2_CLRFF      0xD8            /* clear byte ptr flip/flop */
#define DMA2_MCLR       0xDA            /* master clear register */
#define DMA2_CLRM       0xDC            /* clear mask register */
#define DMA2_WRTALL     0xDE            /* write all mask register */
/* stuff for each DMA channel */
#define DMA0_ADDR       0x00            /* chan 0 base adddress */
#define DMA0_CNT        0x01            /* chan 0 base count */
#define DMA1_ADDR       0x02            /* chan 1 base adddress */
#define DMA1_CNT        0x03            /* chan 1 base count */
#define DMA2_ADDR       0x04            /* chan 2 base adddress */
#define DMA2_CNT        0x05            /* chan 2 base count */
#define DMA3_ADDR       0x06            /* chan 3 base adddress */
#define DMA3_CNT        0x07            /* chan 3 base count */
#define DMA4_ADDR       0xC0            /* chan 4 base adddress */
#define DMA4_CNT        0xC2            /* chan 4 base count */
#define DMA5_ADDR       0xC4            /* chan 5 base adddress */
#define DMA5_CNT        0xC6            /* chan 5 base count */
#define DMA6_ADDR       0xC8            /* chan 6 base adddress */
#define DMA6_CNT        0xCA            /* chan 6 base count */
#define DMA7_ADDR       0xCC            /* chan 7 base adddress */
#define DMA7_CNT        0xCE            /* chan 7 base count */

#define DMA0_PAGE       0x87            /* chan 0 page register (refresh) */
#define DMA1_PAGE       0x83            /* chan 1 page register */
#define DMA2_PAGE       0x81            /* chan 2 page register */
#define DMA3_PAGE       0x82            /* chan 3 page register */
#define DMA4_PAGE       0x8F            /* chan 4 page register (unuseable) */
#define DMA5_PAGE       0x8B            /* chan 5 page register */
#define DMA6_PAGE       0x89            /* chan 6 page register */
#define DMA7_PAGE       0x8A            /* chan 7 page register */
typedef struct {
   unsigned char dma_disable;           /* bits to disable dma channel */
   unsigned char dma_enable;            /* bits to enable dma channel */
   unsigned short page;                 /* page port location */
   unsigned short addr;                 /* addr port location */
   unsigned short count;                /* count port location */
   unsigned short single;               /* single mode port location */
   unsigned short mode;                 /* mode port location */
   unsigned short clear_ff;             /* clear flip-flop port location */
   unsigned char write;                 /* bits for write transfer */
   unsigned char read;                  /* bits for read transfer */
} DMA_ENTRY;
static DMA_ENTRY mydma[] =
{  /* channel 0 */
   { 0x04, 0x00, DMA0_PAGE, DMA0_ADDR, DMA0_CNT,
     DMA1_SNGL, DMA1_MODE, DMA1_CLRFF, 0x48, 0x44 },
   /* channel 1 */
   { 0x05, 0x01, DMA1_PAGE, DMA1_ADDR, DMA1_CNT,
     DMA1_SNGL,DMA1_MODE,DMA1_CLRFF,0x49,0x45 },
   /* channel 2 */
   { 0x06, 0x02, DMA2_PAGE, DMA2_ADDR, DMA2_CNT,
     DMA1_SNGL, DMA1_MODE, DMA1_CLRFF, 0x4A, 0x46 },
   /* channel 3 */
   { 0x07, 0x03, DMA3_PAGE, DMA3_ADDR, DMA3_CNT,
     DMA1_SNGL, DMA1_MODE, DMA1_CLRFF, 0x4B, 0x47 },
   /* channel 4 */
   { 0x04, 0x00, DMA4_PAGE, DMA4_ADDR, DMA4_CNT,
     DMA2_SNGL, DMA2_MODE, DMA2_CLRFF, 0x48, 0x44 },
   /* channel 5 */
   { 0x05, 0x01, DMA5_PAGE, DMA5_ADDR, DMA5_CNT,
     DMA2_SNGL, DMA2_MODE, DMA2_CLRFF, 0x49, 0x45 },
   /* channel 6 */
   { 0x06, 0x02, DMA6_PAGE, DMA6_ADDR, DMA6_CNT,
     DMA2_SNGL, DMA2_MODE, DMA2_CLRFF, 0x4A, 0x46 },
   /* channel 7 */
   { 0x07, 0x03, DMA7_PAGE, DMA7_ADDR, DMA7_CNT,
     DMA2_SNGL, DMA2_MODE, DMA2_CLRFF, 0x4B, 0x47 }
};
// dma_start:
//  Starts the DMA controller for the specified channel, transferring
//  size bytes from addr (the block must not cross a page boundary).
//  If auto_init is set, it will use the endless repeat DMA mode.
void lsys_dma_start(char channel,unsigned long addr,short size,char auto_init,char input)
{  DMA_ENTRY *tdma;
   unsigned long page, offset;
   int mode;

   tdma = &mydma[channel];      page = addr >> 16;
   if (channel >= 4) {          /* 16 bit data is halved */
      addr >>= 1; size >>= 1;
   }
   offset = addr & 0xFFFF; size--;
   mode = (input) ? tdma->read : tdma->write;
   if (auto_init) mode |= 0x10;

   outp(tdma->single, tdma->dma_disable);      /* disable channel */
   outp(tdma->mode, mode);                     /* set mode */
   outp(tdma->clear_ff, 0);                    /* clear flip-flop */
   outp(tdma->addr, offset & 0xFF);            /* address LSB */
   outp(tdma->addr, offset >> 8);              /* address MSB */
   outp(tdma->page, page);                     /* page number */
   outp(tdma->clear_ff, 0);                    /* clear flip-flop */
   outp(tdma->count, size & 0xFF);             /* count LSB */
   outp(tdma->count, size >> 8);               /* count MSB */
   outp(tdma->single, tdma->dma_enable);       /* enable channel */
}
void lsys_dma_stop(char channel)
{  DMA_ENTRY *tdma = &mydma[channel];
   outp(tdma->single, tdma->dma_disable);
}
// dma_todo:
//  Returns the current position in a dma transfer. Interrupts should be
//  disabled before calling this function.
long lsys_dma_todo(char channel)
{  int val1, val2;
   DMA_ENTRY *tdma = &mydma[channel];

   outp(tdma->clear_ff, 0xff);
   do {
      val1 = inp(tdma->count);
      val1 |= inp(tdma->count) << 8;
      val2 = inp(tdma->count);
      val2 |= inp(tdma->count) << 8;
      val1 -= val2;
   } while (val1 > 0x40);
   if (channel > 3) val2 <<= 1;
   return val2;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -