Exemplo n.º 1
0
/* setup_x_magic:
 *  To make sure that things will go on working properly even if a few
 *  bits of code don't know about mode-X screens, we do special magic
 *  inside the bank switch functions to emulate a linear image surface.
 *  Whenever someone tries to access the screen directly, these routines
 *  copy the planar image into a temporary buffer, let the client write
 *  there, and then automatically refresh the screen with the updated
 *  graphics. Very slow, but it makes 100% sure that everything will work.
 */
static void setup_x_magic(BITMAP *b)
{
   #ifdef ALLEGRO_DOS

      /* DOS buffer has to go in conventional memory */
      int seg = __dpmi_allocate_dos_memory((b->w+15)/16, &magic_sel);

      if (seg > 0)
	 _x_magic_buffer_addr = seg*16;
      else
	 _x_magic_buffer_addr = 0;

   #else

      /* other platforms can put the buffer wherever they like */
      _x_magic_buffer_addr = (unsigned long)_AL_MALLOC(b->w);

   #endif

   _x_magic_screen_addr = 0;
   _x_magic_screen_width = 0;

   LOCK_VARIABLE(_x_magic_buffer_addr);
   LOCK_VARIABLE(_x_magic_screen_addr);
   LOCK_VARIABLE(_x_magic_screen_width);
   LOCK_FUNCTION(_x_bank_switch);

   b->write_bank = b->read_bank = _x_bank_switch;
}
Exemplo n.º 2
0
Arquivo: emm.c Projeto: stsp/pmdapi
int emm_init(void)
{
  /* TODO: check EMM presence */

  /* allocate 1 para for page map array */
  rmseg = __dpmi_allocate_dos_memory(1, &rmsel);
  if (rmseg == -1)
    return -1;
  __dpmi_get_segment_base_address(rmsel, &rmaddr);
  return 0;
}
Exemplo n.º 3
0
/*
 * Called from setup_pkt_inf() in pcpkt.c
 */
static DWORD setup_pkt_inf_fast (void)
{
  /* Allocate space for asmpkt_inf, temp area, pkt-stub and Tx buffer.
   */
  DWORD  rdata_size = PKT_TMP();
  size_t stub_size  = sizeof(real_stub_array);

#if (DOSX)
  rdata_size += PKT_TMP_SIZE + ETH_MAX + 10;
#endif

  if (rdata_size >= 64*1024UL)
  {
    TCP_CONSOLE_MSG (0, ("%s (%u): Development error:\nsize %u too large\n",
                         __FILE__, __LINE__, (unsigned int)rdata_size));
    return (0);
  }
  if (stub_size < 0xC0)
  {
    TCP_CONSOLE_MSG (0, ("%s (%u): Development error:\n\"pkt_stub.h\""
                         " seems truncated (%d bytes)\n",
                         __FILE__, __LINE__, SIZEOF(real_stub_array)));
    return (0);
  }

#if (DOSX & DJGPP)
  {
    int i, seg, sel;

    seg = __dpmi_allocate_dos_memory ((rdata_size+15)/16, &sel);
    if (seg < 0)
       return (0);

    _pkt_inf->rm_seg = seg;
    _pkt_inf->rm_sel = sel;
    rm_base = (_pkt_inf->rm_seg << 4);

    for (i = 0; i < (int)rdata_size; i += 4)  /* clear area */
        POKEL (_pkt_inf->rm_seg, i, 0);
  }

#elif (DOSX & DOS4GW)
  {
    WORD seg, sel;

    seg = dpmi_real_malloc (rdata_size, &sel);
    if (!seg)
       return (0);

    _pkt_inf->rm_seg = seg;
    _pkt_inf->rm_sel = sel;
    rm_base = (_pkt_inf->rm_seg) << 4;
    memset ((void*)rm_base, 0, rdata_size);
  }

#elif (DOSX & PHARLAP)
  {
    WORD largest, seg;
    int  i;

    if (_dx_real_alloc ((rdata_size+15)/16, &seg, &largest) != 0)
       return (0);

    _pkt_inf->rm_seg = seg;
    _pkt_inf->rm_sel = 0;
    RP_SET (rm_base, 0, _pkt_inf->rm_seg);
    for (i = 0; i < (int)rdata_size; i += 4)
        POKEL (_pkt_inf->rm_seg, i, 0);
  }

#elif (DOSX & X32VM)
  {
    int i;

    rm_base = _x32_real_alloc (rdata_size);
    if (!rm_base)
       return (0);

    _pkt_inf->rm_seg = _x32_real_segment (rm_base);
    _pkt_inf->rm_sel = 0;
    for (i = 0; i < (int)rdata_size; i += 4)
        POKEL (_pkt_inf->rm_seg, i, 0);
  }

#elif (DOSX & POWERPAK)
  {
    WORD seg, sel;
    int  i;

    seg = dpmi_real_malloc ((rdata_size+15)/16, &sel);
    if (!seg)
       return (0);

    _pkt_inf->rm_seg = seg;
    _pkt_inf->rm_sel = sel;
    RP_SET (rm_base, 0, _pkt_inf->rm_seg);
    for (i = 0; i < (int)rdata_size; i += 4)
        POKEL (_pkt_inf->rm_seg, i, 0);
  }

#elif (DOSX == 0)
  {
    char _far *buf = _fcalloc (rdata_size, 0);

    if (!buf)
       return (0);
    _pkt_inf->rm_seg = FP_SEG (buf);
    rm_base = (DWORD) buf;
  }

#else
  #error Help!
#endif

  pktq_far_init (sizeof(struct pkt_rx_element), RX_BUFS, ASMPKT_INF);
  _pkt_inf->pkt_queue.num_buf = RX_BUFS;
  return (rm_base);
}
Exemplo n.º 4
0
dma_buffer *dma_allocate(unsigned int channel, unsigned int size)
{
	int parsize = (size + 15) >> 4;	/* size in paragraphs */
	int par = 0;				/* Real-mode paragraph */
	int selector = 0;			/* Protected-mode selector */
	int mask = channel <= 3 ? 0xfff : 0x1fff;	/* Alignment mask in para. */
	int allocsize = parsize;	/* Allocated size in paragraphs */
	int count;					/* Try count */
	int bound = 0;				/* Nearest bound address */
	int maxsize;				/* Maximal possible block size */
	dma_buffer *buffer = NULL;
	__dpmi_meminfo buff_info, struct_info;

	if (!dma_initialize())
		return NULL;

	/* Loop until we'll get a properly aligned memory block */
	for (count = 8; count; count--) {
		int resize = (selector != 0);

		/* Try first to resize (possibly previously) allocated block */
		if (resize) {
			maxsize = (bound + parsize) - par;
			if (maxsize > parsize * 2)
				maxsize = parsize * 2;
			if (maxsize == allocsize)
				resize = 0;
			else {
				allocsize = maxsize;
				/* BUG WARNING: there is an error in dpmi.h DJGPP 2.01 library:
				   the order of "selector" and "alloc size" should be
				   reversed */
				if (__dpmi_resize_dos_memory(allocsize, selector, &maxsize) !=
					0) resize = 0;
			}
		}

		if (!resize) {
			if (selector)
				__dpmi_free_dos_memory(selector), selector = 0;
			par = __dpmi_allocate_dos_memory(allocsize, &selector);
		}

		if ((par == 0) || (par == -1))
			goto exit;

		/* If memory block contains a properly aligned portion, quit loop */
		bound = (par + mask + 1) & ~mask;
		if (par + parsize <= bound)
			break;
		if (bound + parsize <= par + allocsize) {
			par = bound;
			break;
		}
	}
	if (!count) {
		__dpmi_free_dos_memory(selector);
		goto exit;
	}

	buffer = malloc(sizeof(dma_buffer));
	buffer->linear = (void *)(__djgpp_conventional_base + bound * 16);
	buffer->physical = bound * 16;
	buffer->size = parsize * 16;
	buffer->selector = selector;
	buffer->channel = channel;

	buff_info.address = buffer->physical;
	buff_info.size = buffer->size;
	/*
	   Don't pay attention to return code since under plain DOS it often
	   returns error (at least under HIMEM/CWSDPMI and EMM386/DPMI)
	 */
	__dpmi_lock_linear_region(&buff_info);

	/* Lock the DMA buffer control structure as well */
	struct_info.address = __djgpp_base_address + (unsigned long)buffer;
	struct_info.size = sizeof(dma_buffer);
	if (__dpmi_lock_linear_region(&struct_info)) {
		__dpmi_unlock_linear_region(&buff_info);
		__dpmi_free_dos_memory(selector);
		free(buffer);
		buffer = NULL;
		goto exit;
	}

  exit:
	if (buffer)
		__buffer_count++;
	else if (--__buffer_count == 0)
		dma_finalize();
	return buffer;
}