/****************************************************************************
NAME
    mvdSetUuids

DESCRIPTION
    Write supported profile UUIDS data to eir_loc.
*/
static void mvdSetUuids (uint8* eir_loc, mvdProfiles supported_profiles)
{
    /* Set field to UUID16 Complete */
    *eir_loc++ = EIR_TYPE_UUID16_COMPLETE;
    
    /* Set up Profile UUIDS */
    if(supported_profiles & ProfileAghfp)
    {
        /* Write AGHFP UUID */
        *eir_loc++ = GET_BYTE(BT_UUID_SERVICE_CLASS_AGHFP, 0);
        *eir_loc++ = GET_BYTE(BT_UUID_SERVICE_CLASS_AGHFP, 1);
    }
    if(supported_profiles & ProfileAghsp)
    {
        /* Write AGHSP UUID */
        *eir_loc++ = GET_BYTE(BT_UUID_SERVICE_CLASS_AGHSP, 0);
        *eir_loc++ = GET_BYTE(BT_UUID_SERVICE_CLASS_AGHSP, 1);
    }
    if(supported_profiles & ProfileA2dp)
    {
        /* Write Audio Source UUID */
        *eir_loc++ = GET_BYTE(BT_UUID_SERVICE_CLASS_AUDIO_SOURCE, 0);
        *eir_loc++ = GET_BYTE(BT_UUID_SERVICE_CLASS_AUDIO_SOURCE, 1);
        
        /* Write A2DP UUID */
        *eir_loc++ = GET_BYTE(BT_UUID_SERVICE_CLASS_A2DP, 0);
        *eir_loc++ = GET_BYTE(BT_UUID_SERVICE_CLASS_A2DP, 1);
    }
    if(supported_profiles & ProfileAvrcp)
    {
        /* Write AVRCP Target UUID */
        *eir_loc++ = GET_BYTE(BT_UUID_SERVICE_CLASS_AVRCP_TARGET, 0);
        *eir_loc++ = GET_BYTE(BT_UUID_SERVICE_CLASS_AVRCP_TARGET, 1);
    }
}
Example #2
0
/* Esta funcion convierte un estilo a un caracter */
PRIVATE chtype viewP_style2chtype(Style s)
{
	chtype ch = 0;
	ch |= GET_BYTE(s, 0);
	ch |= vid2attr[GET_BYTE(s, 2) & 0x0F];
	if (colorSupport) ch |= COLOR_PAIR(GET_BYTE(s, 1));
	return ch;
}
void StreamEventDemuxer::parseReferenceNPT( BYTE *section ) {
    BYTE descLen          = GET_SE_LEN(section);
    bool postDiscontinuityIndicator = GET_BYTE(section+2) & 0x80 ? true : false;
    BYTE contentID        = GET_BYTE(section+2) & 0x7F;
	QWORD stcReference    = ((QWORD(GET_BYTE(section+3) & 0x1)) << 32) | (0x00000000FFFFFFFFLLU & (GET_DWORD(section+4)));
    QWORD nptReference    = GET_QWORD(section+8) & 0x00000001FFFFFFFFLLU;
    WORD scaleNumerator   = GET_WORD(section+16);
    WORD scaleDenominator = GET_WORD(section+18);

    printf( "[DSMCCDemuxer] Reference NPT: len=%d, post=%d, contentID=%d, stc=%llx, npt=%llx, nominator=%x, denominator=%x\n",
        descLen, postDiscontinuityIndicator, contentID, stcReference, nptReference, scaleNumerator, scaleDenominator );
}
Example #4
0
File: tiff.c Project: nejmd/JPEG
/* Lit une ligne de l'image TIFF ouverte avec init_tiff_read.
 * Renvoie true si une erreur est survenue, false si pas d'erreur. */
bool read_tiff_line(struct tiff_file_desc *tfd, uint32_t *line_rgb)
{
        size_t ret;
        bool error = false;
        char buf[4];
        uint32_t i = 0;
        uint32_t *cur_line = &tfd->current_line;
        uint32_t *offsets = tfd->strip_offsets;

        memset(buf, 0, sizeof(buf));


        /*
         * If rows_per_strip is zero,
         * there are no multiple strips.
         * Else go to the next strip when required.
         */
        if (tfd->rows_per_strip > 0)
        if (tfd->read_lines >= tfd->rows_per_strip) {

                /* If a next strip exists */
                if (++*cur_line < tfd->nb_strips) {
                        fseek(tfd->file, offsets[*cur_line], SEEK_SET);
                        tfd->read_lines = 0;
                }
        }

        /* Read a whole line */
        for (uint32_t w = 0; w < tfd->width; w++) {

                /* Read each pixel */
                ret = fread(buf, 1, tfd->samples_per_pixels, tfd->file);

                /* Error handling */
                if (ret != tfd->samples_per_pixels) {
                        error = true;
                        break;
                }

                if (tfd->samples_per_pixels == 1)
                        buf[1] = buf[2] = buf[0];

                /* Error handling */
                line_rgb[i++] = GET_BYTE(buf[0]) << 16 | GET_BYTE(buf[1]) << 8 | GET_BYTE(buf[2]);
        }

        /* Increment the line counter */
        tfd->read_lines++;


        return error;
}
Example #5
0
void KeyEventHandler::process( util::Buffer *msg ) {
	if (!_onKeyEvent.empty()) {
		util::BYTE *payload = MSG_PAYLOAD(msg->buffer());
		util::DWORD value   = GET_BE_DWORD( payload );
		util::BYTE isUp     = GET_BYTE(payload+4);
		_onKeyEvent( static_cast<util::key::type>( value ), (isUp == 1) );
	}
}
Example #6
0
uint64_t afk_hash_swizzle(uint64_t a, uint64_t b)
{
    /* This is essentially a CBC mode substitution cipher with a
     * 1 byte block size and the above fixed lookup table.
     * To make sure all blocks affect all other blocks I need
     * two passes
     */
    uint64_t out = a;
    uint8_t lastByte = (GET_BYTE(a, 0) ^ lut[GET_BYTE(b, 0)]);

    for (int i = 0; i < 16; ++i)
    {
        setByte(out, lastByte, i % 8);
        lastByte = (GET_BYTE(a, (i + 1) % 8) ^ lut[lastByte ^ GET_BYTE(b, (i + 1) % 8)]);
    }

    return out;
}
Example #7
0
int
sflash_write(si_t *sih, chipcregs_t *cc, uint offset, uint length, const uchar *buffer)
{
	struct sflash *sfl;
	uint off = offset, len = length;
	const uint8 *buf = buffer;
	uint8 data;
	int ret = 0, ntry = 0;
	bool is4712b0;
	uint32 page, byte, mask;
	osl_t *osh;

	ASSERT(sih);

	osh = si_osh(sih);

	if (!len)
		return 0;

	sfl = &sflash;
	if ((off + len) > sfl->size)
		return -22;

	switch (sfl->type) {
	case SFLASH_ST:
		is4712b0 = (CHIPID(sih->chip) == BCM4712_CHIP_ID) && (CHIPREV(sih->chiprev) == 3);
		/* Enable writes */
retry:		sflash_cmd(osh, cc, SFLASH_ST_WREN);
		off = offset;
		len = length;
		buf = buffer;
		ntry++;
		if (is4712b0) {
			mask = 1 << 14;
			W_REG(osh, &cc->flashaddress, off);
			data = GET_BYTE(buf);
			buf++;
			W_REG(osh, &cc->flashdata, data);
			/* Set chip select */
			OR_REG(osh, &cc->gpioout, mask);
			/* Issue a page program with the first byte */
			sflash_cmd(osh, cc, SFLASH_ST_PP);
			ret = 1;
			off++;
			len--;
			while (len > 0) {
				if ((off & 255) == 0) {
					/* Page boundary, drop cs and return */
					AND_REG(osh, &cc->gpioout, ~mask);
					OSL_DELAY(1);
					if (!sflash_poll(sih, cc, off)) {
						/* Flash rejected command */
						if (ntry <= ST_RETRIES)
							goto retry;
						else
							return -11;
					}
					return ret;
				} else {
					/* Write single byte */
					data = GET_BYTE(buf);
					buf++;
					sflash_cmd(osh, cc, data);
				}
				ret++;
				off++;
				len--;
			}
			/* All done, drop cs */
			AND_REG(osh, &cc->gpioout, ~mask);
			OSL_DELAY(1);
			if (!sflash_poll(sih, cc, off)) {
				/* Flash rejected command */
				if (ntry <= ST_RETRIES)
					goto retry;
				else
					return -12;
			}
		} else if (sih->ccrev >= 20) {
			W_REG(osh, &cc->flashaddress, off);
			data = GET_BYTE(buf);
			buf++;
			W_REG(osh, &cc->flashdata, data);
			/* Issue a page program with CSA bit set */
			sflash_cmd(osh, cc, SFLASH_ST_CSA | SFLASH_ST_PP);
			ret = 1;
			off++;
			len--;
			while (len > 0) {
				if ((off & 255) == 0) {
					/* Page boundary, poll droping cs and return */
					W_REG(NULL, &cc->flashcontrol, 0);
					OSL_DELAY(1);
					if (sflash_poll(sih, cc, off) == 0) {
						/* Flash rejected command */
						SFL_MSG(("sflash: pp rejected, ntry: %d,"
						         " off: %d/%d, len: %d/%d, ret:"
						         "%d\n", ntry, off, offset, len,
						         length, ret));
						if (ntry <= ST_RETRIES)
							goto retry;
						else
							return -11;
					}
					return ret;
				} else {
					/* Write single byte */
					data = GET_BYTE(buf);
					buf++;
					sflash_cmd(osh, cc, SFLASH_ST_CSA | data);
				}
				ret++;
				off++;
				len--;
			}
			/* All done, drop cs & poll */
			W_REG(NULL, &cc->flashcontrol, 0);
			OSL_DELAY(1);
			if (sflash_poll(sih, cc, off) == 0) {
				/* Flash rejected command */
				SFL_MSG(("sflash: pp rejected, ntry: %d, off: %d/%d,"
				         " len: %d/%d, ret: %d\n",
				         ntry, off, offset, len, length, ret));
				if (ntry <= ST_RETRIES)
					goto retry;
				else
					return -12;
			}
		} else {
			ret = 1;
			W_REG(osh, &cc->flashaddress, off);
			data = GET_BYTE(buf);
			buf++;
			W_REG(osh, &cc->flashdata, data);
			/* Page program */
			sflash_cmd(osh, cc, SFLASH_ST_PP);
		}
		break;
	case SFLASH_AT:
		mask = sfl->blocksize - 1;
		page = (off & ~mask) << 1;
		byte = off & mask;
		/* Read main memory page into buffer 1 */
		if (byte || (len < sfl->blocksize)) {
			W_REG(osh, &cc->flashaddress, page);
			sflash_cmd(osh, cc, SFLASH_AT_BUF1_LOAD);
			/* 250 us for AT45DB321B */
			SPINWAIT(sflash_poll(sih, cc, off), 1000);
			ASSERT(!sflash_poll(sih, cc, off));
		}
		/* Write into buffer 1 */
		for (ret = 0; (ret < (int)len) && (byte < sfl->blocksize); ret++) {
			W_REG(osh, &cc->flashaddress, byte++);
			W_REG(osh, &cc->flashdata, *buf++);
			sflash_cmd(osh, cc, SFLASH_AT_BUF1_WRITE);
		}
		/* Write buffer 1 into main memory page */
		W_REG(osh, &cc->flashaddress, page);
		sflash_cmd(osh, cc, SFLASH_AT_BUF1_PROGRAM);
		break;
	}

	return ret;
}
Example #8
0
TEST( Types, basic_byte_get ) {
	util::BYTE result = GET_BYTE(types::values);
	ASSERT_TRUE( result == 0xAA );
}
Example #9
0
/* FIXME: The current implementation of socket_recv_message() is a fast
 * pass-through to nice_socket_recv_message() if the HTTP socket is connected,
 * but is a slow state machine otherwise, using multiple memcpy()s. Spruce it up
 * to better to use the recv_messages to avoid the memcpy()s. */
static gint
socket_recv_messages (NiceSocket *sock,
    NiceInputMessage *recv_messages, guint n_recv_messages)
{
  HttpPriv *priv = sock->priv;
  gint ret = -1;

  /* Socket has been closed: */
  if (sock->priv == NULL)
    return 0;

  if (priv->state == HTTP_STATE_CONNECTED) {
    guint i;

    /* Fast path: pass through to the base socket once we’re connected. */
    if (priv->base_socket) {
      ret = nice_socket_recv_messages (priv->base_socket,
          recv_messages, n_recv_messages);
    }

    if (ret <= 0)
      return ret;

    /* After successfully receiving into at least one NiceInputMessage,
     * update the from address in each valid NiceInputMessage. */
    for (i = 0; i < (guint) ret; i++) {
      if (recv_messages[i].from != NULL)
        *recv_messages[i].from = priv->addr;
    }

    return ret;
  } else {
    /* Slow path: read into a local ring buffer until we’re parsed enough of the
     * headers. Double the buffer in size every time it fills up. */
    gboolean has_wrapped;
    GInputVector local_recv_bufs[2];
    NiceInputMessage local_recv_message = { local_recv_bufs, 2, NULL, 0 };

    /* Has the buffer filled up? Start with an initial buffer of 1KB, which
     * should cover the average size of HTTP response headers. Source:
     * http://dev.chromium.org/spdy/spdy-whitepaper */
    if (priv->recv_buf_fill == priv->recv_buf_length) {
      priv->recv_buf_length = MAX (priv->recv_buf_length * 2, 1024);
      priv->recv_buf = g_realloc (priv->recv_buf, priv->recv_buf_length);
    }

    assert_ring_buffer_valid (priv);

    /* Read some data into the buffer. Use two GInputVectors: one for the tail
     * of the buffer and one for the head. */
    has_wrapped =
        (priv->recv_buf_pos + priv->recv_buf_fill) > priv->recv_buf_length;

    if (has_wrapped) {
      local_recv_bufs[0].buffer =
           priv->recv_buf + (priv->recv_buf_pos + priv->recv_buf_fill) %
           priv->recv_buf_length;
      local_recv_bufs[0].size = priv->recv_buf_length - priv->recv_buf_fill;
      local_recv_bufs[1].buffer = NULL;
      local_recv_bufs[1].size = 0;
    } else {
      local_recv_bufs[0].buffer =
          priv->recv_buf + priv->recv_buf_pos + priv->recv_buf_fill;
      local_recv_bufs[0].size =
          priv->recv_buf_length - (priv->recv_buf_pos + priv->recv_buf_fill);
      local_recv_bufs[1].buffer = priv->recv_buf;
      local_recv_bufs[1].size = priv->recv_buf_pos;
    }

    if (priv->base_socket) {
      ret = nice_socket_recv_messages (priv->base_socket,
          &local_recv_message, 1);
    }

    if (ret <= 0)
      return ret;

    /* Update the buffer’s metadata. */
    priv->recv_buf_fill += local_recv_message.length;
    assert_ring_buffer_valid (priv);

    /* Fall through and try parsing the newly received data. */
  }

#define GET_BYTE(pos) \
  priv->recv_buf[(pos + priv->recv_buf_pos) % priv->recv_buf_length]
#define EAT_WHITESPACE(pos) \
  while (pos < priv->recv_buf_fill && GET_BYTE(pos) == ' ') \
    pos++; \
  if (pos >= priv->recv_buf_fill) \
    goto not_enough_data;

retry:
  nice_debug ("Receiving from HTTP proxy (state %d) : %" G_GSSIZE_FORMAT " \n"
      "'%s'", priv->state, priv->recv_buf_fill,
      priv->recv_buf + priv->recv_buf_pos);

  switch (priv->state) {
    case HTTP_STATE_INIT:
      {
        /* This is a logical position in the recv_buf; add
         * (priv->recv_buf + priv->recv_buf_pos) to get the actual byte in
         * memory. */
        guint pos = 0;

        /* Eat leading whitespace and check we have enough data. */
        EAT_WHITESPACE (pos);

        if (pos + 7 > priv->recv_buf_fill)
          goto not_enough_data;
        if (GET_BYTE (pos + 0) != 'H' ||
            GET_BYTE (pos + 1) != 'T' ||
            GET_BYTE (pos + 2) != 'T' ||
            GET_BYTE (pos + 3) != 'P' ||
            GET_BYTE (pos + 4) != '/' ||
            GET_BYTE (pos + 5) != '1' ||
            GET_BYTE (pos + 6) != '.')
          goto error;
        pos += 7;

        if (pos >= priv->recv_buf_fill)
          goto not_enough_data;
        if (GET_BYTE (pos) != '0' && GET_BYTE (pos) != '1')
          goto error;
        pos++;

        /* Make sure we have a space after the HTTP version */
        if (pos >= priv->recv_buf_fill)
          goto not_enough_data;
        if (GET_BYTE (pos) != ' ')
          goto error;

        EAT_WHITESPACE (pos);

        /* Check for a successful 2xx code */
        if (pos + 3 > priv->recv_buf_fill)
          goto not_enough_data;
        if (GET_BYTE (pos) != '2' ||
            GET_BYTE (pos + 1) < '0' || GET_BYTE (pos + 1) > '9' ||
            GET_BYTE (pos + 2) < '0' || GET_BYTE (pos + 2) > '9')
          goto error;

        /* Clear any trailing chars */
        while (pos + 1 < priv->recv_buf_fill &&
            GET_BYTE (pos) != '\r' && GET_BYTE (pos + 1) != '\n')
          pos++;
        if (pos + 1 >= priv->recv_buf_fill)
          goto not_enough_data;
        pos += 2;

        /* Consume the data we just parsed. */
        priv->recv_buf_pos = (priv->recv_buf_pos + pos) % priv->recv_buf_length;
        priv->recv_buf_fill -= pos;

        priv->content_length = 0;
        priv->state = HTTP_STATE_HEADERS;

        goto retry;
      }
      break;
    case HTTP_STATE_HEADERS:
      {
        guint pos = 0;

        if (pos + 15 < priv->recv_buf_fill &&
            (GET_BYTE (pos +  0) == 'C' || GET_BYTE (pos +  0) == 'c') &&
            (GET_BYTE (pos +  1) == 'o' || GET_BYTE (pos +  1) == 'O') &&
            (GET_BYTE (pos +  2) == 'n' || GET_BYTE (pos +  2) == 'N') &&
            (GET_BYTE (pos +  3) == 't' || GET_BYTE (pos +  3) == 'T') &&
            (GET_BYTE (pos +  4) == 'e' || GET_BYTE (pos +  4) == 'E') &&
            (GET_BYTE (pos +  5) == 'n' || GET_BYTE (pos +  5) == 'N') &&
            (GET_BYTE (pos +  6) == 't' || GET_BYTE (pos +  6) == 'T') &&
             GET_BYTE (pos +  7) == '-' &&
            (GET_BYTE (pos +  8) == 'L' || GET_BYTE (pos +  8) == 'l') &&
            (GET_BYTE (pos +  9) == 'e' || GET_BYTE (pos +  9) == 'E') &&
            (GET_BYTE (pos + 10) == 'n' || GET_BYTE (pos + 10) == 'N') &&
            (GET_BYTE (pos + 11) == 'g' || GET_BYTE (pos + 11) == 'G') &&
            (GET_BYTE (pos + 12) == 't' || GET_BYTE (pos + 12) == 'T') &&
            (GET_BYTE (pos + 13) == 'h' || GET_BYTE (pos + 13) == 'H') &&
             GET_BYTE (pos + 14) == ':') {
          /* Found a Content-Length header. Parse and store the value. Note that
           * the HTTP standard allows for arbitrarily-big content lengths. We
           * limit it to G_MAXSIZE for sanity’s sake.
           *
           * The code below is equivalent to strtoul(input, NULL, 10), but
           * operates on a ring buffer. */
          pos += 15;
          EAT_WHITESPACE (pos);
          priv->content_length = 0;

          while (TRUE) {
            guint8 byte = GET_BYTE (pos);
            gint val = g_ascii_digit_value (byte);

            if (byte == '\r') {
              /* Reached the end of the value; fall out to the code below which
               * will grab the \n. */
              break;
            } else if (val == -1) {
              priv->content_length = 0;
              goto error;
            }

            /* Check for overflow. Don’t flag it as an error; just fall through
             * to the code below which will skip to the \r\n. */
            if (priv->content_length > G_MAXSIZE / 10 ||
                priv->content_length * 10 > G_MAXSIZE - val) {
              priv->content_length = 0;
              break;
            }

            priv->content_length = (priv->content_length * 10) + val;

            if (pos + 1 > priv->recv_buf_fill)
              goto not_enough_data;
            pos++;
          }
        }

        /* Skip over the header. */
        while (pos + 1 < priv->recv_buf_fill &&
            GET_BYTE (pos) != '\r' && GET_BYTE (pos + 1) != '\n')
          pos++;

        nice_debug ("pos = %u, fill = %" G_GSSIZE_FORMAT,
            pos, priv->recv_buf_fill);

        if (pos + 1 >= priv->recv_buf_fill)
          goto not_enough_data;
        pos += 2;

        /* Consume the data we just parsed. */
        priv->recv_buf_pos = (priv->recv_buf_pos + pos) % priv->recv_buf_length;
        priv->recv_buf_fill -= pos;

        if (pos == 2)
          priv->state = HTTP_STATE_BODY;

        goto retry;
      }
      break;
    case HTTP_STATE_BODY:
      {
        gsize consumed;

        if (priv->content_length == 0) {
          priv->state = HTTP_STATE_CONNECTED;
          goto retry;
        }

        if (priv->recv_buf_fill == 0)
          goto not_enough_data;

        consumed = MIN (priv->content_length, priv->recv_buf_fill);

        priv->recv_buf_pos =
            (priv->recv_buf_pos + consumed) % priv->recv_buf_length;
        priv->recv_buf_fill -= consumed;
        priv->content_length -= consumed;

        goto retry;
      }
      break;
    case HTTP_STATE_CONNECTED:
      {
        gsize len;

        len = memcpy_ring_buffer_to_input_messages (priv,
            recv_messages, n_recv_messages);

        /* Send the pending data */
        nice_socket_flush_send_queue (priv->base_socket,
            &priv->send_queue);

        return len;
      }
      break;
    case HTTP_STATE_ERROR:
    default:
      /* Unknown status */
      goto error;
  }

 not_enough_data:
  return 0;

 error:
  nice_debug ("http error");
  if (priv->base_socket)
    nice_socket_free (priv->base_socket);
  priv->base_socket = NULL;
  priv->state = HTTP_STATE_ERROR;

  return -1;
}
Example #10
0
	u8 buf[SPI_TRANSFER_BUF_LEN];

	exide = (frame->can_id & CAN_EFF_FLAG) ? 1 : 0; /* Extended ID Enable */
	if (exide)
		sid = (frame->can_id & CAN_EFF_MASK) >> 18;
	else
		sid = frame->can_id & CAN_SFF_MASK; /* Standard ID */
	eid = frame->can_id & CAN_EFF_MASK; /* Extended ID */
	rtr = (frame->can_id & CAN_RTR_FLAG) ? 1 : 0; /* Remote transmission */

	buf[TXBCTRL_OFF] = INSTRUCTION_LOAD_TXB(tx_buf_idx);
	buf[TXBSIDH_OFF] = sid >> SIDH_SHIFT;
	buf[TXBSIDL_OFF] = ((sid & SIDL_SID_MASK) << SIDL_SID_SHIFT) |
		(exide << SIDL_EXIDE_SHIFT) |
		((eid >> SIDL_EID_SHIFT) & SIDL_EID_MASK);
	buf[TXBEID8_OFF] = GET_BYTE(eid, 1);
	buf[TXBEID0_OFF] = GET_BYTE(eid, 0);
	buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc;
	memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc);
	mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx);
	mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ);
}

static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf,
				int buf_idx)
{
	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
	struct mcp251x_platform_data *pdata = spi->dev.platform_data;

	if (pdata->model == CAN_MCP251X_MCP2510) {
		int i, len;
Example #11
0
void RUN_DASD(int UNIT)
{
 static int flag_reader_open=0;
 static int RDFILE;
 static int RE;
 static unsigned long CAW;
 static char BUFER[8000];
 static unsigned long ar;
 static int i,j;
 static unsigned int CYL,TRK,RR;
 static unsigned long OFFSET_TRK;
 static unsigned long OFFSET_RR;
 static char FF_00[5];
 static char ID_R0[512];
 static char C_ID_R0_KEY[512];
 static int COUNT_CC,count_cc;
 static char KEY[256];
 static char C_KEY[256];
 static int LEN_KEY,LEN_DATA;
 static int KEY_CMP,KEY_FIND,KEY_MT,KEY_READ,KEY_READ_MT,all_read,KEY_READ_R0;
 static char far * AREA_KEY;
 static unsigned int LEN_ALL_DATA;
 static unsigned int COUNT_CC_WRITE;
 static unsigned char BYTE_PR_OUT[10];

/************************************************************************
																											 ТРЕК:
 метка начала оборота                          #####
									 <<<<>>>>
 собственный адрес 0   - байт признаков                0  - БАЙТ ПРИЗНАКОВ
									 1-2 - номер цилиндра                1-2 -ЦИЛИНДР
									 3-4 - номер головки                 3-4 -ГОЛОВКА
									 5-6 - циклическая проверка  #####
									 <<<<>>>>
 R0                                                    0    -ПРИЗНАК
																														 FF-больше нет
		поле счетчика  0   - признаки                      0    -R0 ПРИЗНАКИ
									 1-2 цилиндр                         1-2  -R0 ЦИЛИНДР
									 3-4 головка                         3-4  -R0 ГОЛОВКА
									 5   - номер записи                  5    -R0 RN
									 6   - длина ключа  ==0              6    -R0 ДЛИНА КЛЮЧА
									 7-8 -длина данных  ==8 байт         7-8  -R0 ДЛИНА ДАННЫХ
									 9-10-циклическря проверка   #####
		поле данных    0-7
									 <<<<>>>>

																											 0    -ПРИЗНАК
																														 FF-больше нет
 адресный маркер
									 0-специальный байт          #####
									 1-2 циклическая проверка    #####
 R1
		поле счетчика  0   - признаки                      0    -RX
									 1-2 цилиндр                         1-2  -RX
									 3-4 головка                         3-4  -RX
									 5   - номер записи                  5    -RX
									 6   - длина ключа                   6    -RX
									 7-8 -длина данных                   7-8  -RX
									 9-10-циклическря проверка   #####


		поле ключа
									 X...X-содержимое
									 CC-циклическая проверка     #####


		поле данных
									 X...X-содежание
									 CC-циклическая проверка     #####




*************************************************************************/

 if (IO_STATUS[UNIT][8]==0)
			 {
				IO_STATUS[UNIT][9]=
					open(&NAME_FILE_IO_DEVICE[UNIT][0],O_RDWR|O_BINARY);
				IO_STATUS[UNIT][8]=1;
				IO_STATUS[UNIT][5]=0;
				OFFSET_IO_DEVICE[UNIT]=0l;

			 }

 switch(CSW_COD[UNIT])
	 {
		case 0x07:   /* УСТАНОВКА SEEK  */
				CYL=(GET_BYTE(CSW_ADRESS[UNIT]+2)<<8)+GET_BYTE(CSW_ADRESS[UNIT]+3);
				TRK=(GET_BYTE(CSW_ADRESS[UNIT]+4)<<8)+GET_BYTE(CSW_ADRESS[UNIT]+5);
SEEK_00:
				DASD[UNIT][DASD_CUR_CYL]=CYL;
				//if (CYL>=0xaf) tt(UNIT);
SEEK_01:
				IO_STATUS[UNIT][2]=0;  /* уточнить состояние==0*/
				IO_STATUS[UNIT][3]=0;
				DASD[UNIT][DASD_CUR_TRK]=TRK;
				if (CSW_COUNT[UNIT]>6) {;}
				else if (CSW_COUNT[UNIT]<6) {;}
						 else CSW_COUNT[UNIT]=0;

				DASD[UNIT][DASD_CUR_RR]=0;
				OFFSET_TRK=(long)(
													DASD[UNIT][DASD_CUR_CYL]*
													DASD[UNIT][DASD_TRK]+
													DASD[UNIT][DASD_CUR_TRK]
												 )*(long)(DASD[UNIT][DASD_LEN]);

				OFFSET_IO_DEVICE[UNIT]=OFFSET_TRK;
				lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT]+5l,SEEK_SET);
				//read(IO_STATUS[UNIT][9],ID_R0,5);
				OFFSET_IO_DEVICE[UNIT]+=5l/*=tell(IO_STATUS[UNIT][9])*/;
				IO_STATUS[UNIT][1]=U4|U5;
				OLD_OPERATION[UNIT]=0;
				//tt(UNIT);
				break;


		case 0x0b:    /* УСТАНОВКА ЦИЛИНДРА SEEK CYLINDER */
				CYL=(GET_BYTE(CSW_ADRESS[UNIT]+2)<<8)+GET_BYTE(CSW_ADRESS[UNIT]+3);
				TRK=DASD[UNIT][DASD_CUR_TRK];
				goto SEEK_00;
				break;


		case 0x1b:     /* УСТАНОВКА ГОЛОВКИ SEEK HEAD
									 команды установки передают из основной памяти 6 байт
									 0-1 ячейка (всегда 0)
									 2-3 цилиндр
									 4-5 головка
									 */

				TRK=(GET_BYTE(CSW_ADRESS[UNIT]+4)<<8)+GET_BYTE(CSW_ADRESS[UNIT]+5);
				goto SEEK_01;
				break;



		case 0x39:     /* ПОИСК ПО СОБСТВЕННОМУ АДРЕСУ НА РАВНО
									 */
				OFFSET_TRK=(long)(
													DASD[UNIT][DASD_CUR_CYL]*
													DASD[UNIT][DASD_TRK]+
													DASD[UNIT][DASD_CUR_TRK]
												 )*(long)(DASD[UNIT][DASD_LEN]);

				OFFSET_IO_DEVICE[UNIT]=OFFSET_TRK;
				lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT],SEEK_SET);
				read(IO_STATUS[UNIT][9],ID_R0,5);
				MOVE_360_TO_MEM(CSW_ADRESS[UNIT],C_ID_R0_KEY,CSW_COUNT[UNIT]);
				if (CSW_COUNT[UNIT]<4) {COUNT_CC=CSW_COUNT[UNIT];CSW_COUNT[UNIT]=0;}
				else COUNT_CC=4;
				CSW_COUNT[UNIT]-=4;
				IO_STATUS[UNIT][1]=U4|U5;
				if (memcmp(&ID_R0[1],C_ID_R0_KEY,COUNT_CC)==0)
					 {IO_STATUS[UNIT][1]|=(U1);
																							 /* модификатор состояния
																									устройство кончило
																							 */
						OFFSET_IO_DEVICE[UNIT]=tell(IO_STATUS[UNIT][9]);
						DASD[UNIT][DASD_CUR_RR]=0;
					 }
				else
					{IO_STATUS[UNIT][1]|=U6;
					 IO_STATUS[UNIT][BYTE_IO_U_1]=0x08;
					}

//				tt(UNIT);
				break;

		case 0x31:     /* ПОИСК ПО ИДЕНТИФИКАТОРУ НА РАВНО
									 */
				if (CSW_COUNT[UNIT]<5) COUNT_CC=CSW_COUNT[UNIT];
				else COUNT_CC=5;

				KEY_CMP=CC_EQ;
				KEY_FIND=FIND_ID;
				KEY_MT=NORMAL_FIND;

FIND_00:
				IO_STATUS[UNIT][2]=0;  /* уточнить состояние==0*/
				IO_STATUS[UNIT][3]=0;
				MOVE_360_TO_MEM(CSW_ADRESS[UNIT],C_ID_R0_KEY,COUNT_CC);

FIND_NEXT_RR:
CIKL_DD1:
				if ( OLD_OPERATION[UNIT]==READ_COUNT ||
						(OLD_OPERATION[UNIT]==FIND_ID && KEY_FIND==FIND_KEY) ||
						 OLD_OPERATION[UNIT]==END_OF_CYL
					 )
							lseek(IO_STATUS[UNIT][9],OLD_OFFSET_IO_DEVICE[UNIT],SEEK_SET);
				else
						if ((OLD_OPERATION[UNIT]==WRITE_DATA) /*||
								 (KEY_FIND==FIND_ID)						 /*||
								 (OLD_OPERATION[UNIT]==(READ_COUNT|READ_KEY|READ_DATA))*/
								)
							 {OFFSET_TRK=(long)(
																DASD[UNIT][DASD_CUR_CYL]*
																DASD[UNIT][DASD_TRK]+
																DASD[UNIT][DASD_CUR_TRK]
																)*(long)(DASD[UNIT][DASD_LEN]);

								OFFSET_IO_DEVICE[UNIT]=OFFSET_TRK;
								lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT]+5l,SEEK_SET);
								//read(IO_STATUS[UNIT][9],ID_R0,5);
								OFFSET_IO_DEVICE[UNIT]+=5l/*=tell(IO_STATUS[UNIT][9])*/;
							 }
						 else lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT],SEEK_SET);
NEXT_FND_FND:
				OFFSET_RR=tell(IO_STATUS[UNIT][9]);
				OLD_OFFSET_IO_DEVICE[UNIT]=OFFSET_RR;
				read(IO_STATUS[UNIT][9],FF_00,1);
				if (FF_00[0]==0x11)
					{
					 switch(KEY_FIND)
						 {
							case FIND_ID:read(IO_STATUS[UNIT][9],ID_R0,9);
													 AREA_KEY=&ID_R0[1];
													 count_cc=COUNT_CC;
													 break;
							case FIND_KEY:read(IO_STATUS[UNIT][9],ID_R0,9);
													 LEN_KEY=ID_R0[6];
													 if (LEN_KEY) read(IO_STATUS[UNIT][9],KEY,LEN_KEY);
													 else for(i=LEN_KEY;i<COUNT_CC;i++) KEY[i]=0;
													 lseek(IO_STATUS[UNIT][9],OFFSET_RR+10l,SEEK_SET);
													 AREA_KEY=&KEY[0];
													 count_cc=COUNT_CC;
													 break;
						 }

					 if (

								((KEY_CMP==CC_EQ)&&(memcmp(AREA_KEY,C_ID_R0_KEY,count_cc)==0))||
								((KEY_CMP==CC_GT)&&(memcmp(AREA_KEY,C_ID_R0_KEY,count_cc)> 0))||
								((KEY_CMP==CC_GE)&&(memcmp(AREA_KEY,C_ID_R0_KEY,count_cc)>=0))

							)
						 {IO_STATUS[UNIT][1]=(U1|U4|U5);
																							 /* модификатор состояния
																									устройство кончило
																							 */
							CYL=(ID_R0[1]<<8)+ID_R0[2];
							TRK=(ID_R0[3]<<8)+ID_R0[4];
							RR= ID_R0[5];
							DASD[UNIT][DASD_CUR_CYL]=CYL;
							DASD[UNIT][DASD_CUR_TRK]=TRK;
							DASD[UNIT][DASD_CUR_RR] =RR;
							OFFSET_IO_DEVICE[UNIT]=OFFSET_RR;
							OLD_OPERATION[UNIT]=KEY_FIND;
						 }
					 else
						 {LEN_KEY=ID_R0[6];
							if (LEN_KEY)
								{//read(IO_STATUS[UNIT][9],KEY,LEN_KEY);
								 lseek(IO_STATUS[UNIT][9],(unsigned long)LEN_KEY,SEEK_CUR);
								}
							LEN_DATA=(ID_R0[7]<<8)+ID_R0[8];
							if (LEN_DATA)
								{//read(IO_STATUS[UNIT][9],BUFER,LEN_DATA);
								 lseek(IO_STATUS[UNIT][9],(unsigned long)LEN_DATA,SEEK_CUR);
								}
							OFFSET_RR=tell(IO_STATUS[UNIT][9]);
							//if (KEY_FIND==FIND_ID)
							//	{goto NEXT_FND_FND;
							//	}
							read(IO_STATUS[UNIT][9],FF_00,1);
							if (FF_00[0]==0x11)
								{OFFSET_IO_DEVICE[UNIT]=OFFSET_RR;
								 lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT],SEEK_SET);
								 OLD_OPERATION[UNIT]=KEY_FIND;
								 ;/*normal record*/
								}
							else
							 {OLD_OPERATION[UNIT]=0;
								if (KEY_MT==MT_FIND)
									{if ((DASD_MASK[UNIT] & 0x18)==0x18)
										 {  /*******запрещен преход на следующий TRK******/
											IO_STATUS[UNIT][BYTE_IO_U_1]=0x04;
											IO_STATUS[UNIT][BYTE_IO]=U4|U5|U6;
										 }
									 else
										 {  /*******переход на следующий TRK**************/

											if (++DASD[UNIT][DASD_CUR_TRK] ==DASD[UNIT][DASD_TRK])
												{  /*    END OF CYL */
												 IO_STATUS[UNIT][BYTE_IO_U_1]=0x20;
												 IO_STATUS[UNIT][BYTE_IO]=U4|U5|U6;
												}
											else
												{  /*    NEXT TRK   */
												 OFFSET_TRK=(long)(
																		DASD[UNIT][DASD_CUR_CYL]*
																		DASD[UNIT][DASD_TRK]+
																		DASD[UNIT][DASD_CUR_TRK]
																					)*(long)(DASD[UNIT][DASD_LEN]);

												 OFFSET_IO_DEVICE[UNIT]=OFFSET_TRK;
												 lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT]+5l,SEEK_SET);
												 //read(IO_STATUS[UNIT][9],ID_R0,5);
												 OFFSET_IO_DEVICE[UNIT]+=5l/*=tell(IO_STATUS[UNIT][9])*/;
												}
										 }
									}
								if (KEY_MT==NORMAL_FIND)
									{
									 OLD_OPERATION[UNIT]=END_OF_CYL;
									 OLD_OFFSET_IO_DEVICE[UNIT]=OFFSET_RR;
								//	 IO_STATUS[UNIT][1]=(U4|U5|U6);
								//	 IO_STATUS[UNIT][BYTE_IO_U_1]=0x08;
									}
							 }
						 }
					}
				else
							 {OLD_OPERATION[UNIT]=0;
								if (KEY_MT==MT_FIND)
									{if ((DASD_MASK[UNIT] & 0x18)==0x18)
										 {  /*******запрещен преход на следующий TRK******/
											IO_STATUS[UNIT][BYTE_IO_U_1]=0x04;
											IO_STATUS[UNIT][BYTE_IO]=U4|U5|U6;
										 }
									 else
										 {  /*******переход на следующий TRK**************/

											if (++DASD[UNIT][DASD_CUR_TRK] ==DASD[UNIT][DASD_TRK])
												{  /*    END OF CYL */
												 IO_STATUS[UNIT][BYTE_IO_U_1]=0x20;
												 IO_STATUS[UNIT][BYTE_IO]=U4|U5|U6;
												}
											else
												{  /*    NEXT TRK   */
												 OFFSET_TRK=(long)(
																		DASD[UNIT][DASD_CUR_CYL]*
																		DASD[UNIT][DASD_TRK]+
																		DASD[UNIT][DASD_CUR_TRK]
																					)*(long)(DASD[UNIT][DASD_LEN]);

												 OFFSET_IO_DEVICE[UNIT]=OFFSET_TRK;
												 lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT]+5l,SEEK_SET);
												 //read(IO_STATUS[UNIT][9],ID_R0,5);
												 OFFSET_IO_DEVICE[UNIT]+=5l/*=tell(IO_STATUS[UNIT][9])*/;
												}
										 }
									}
								if (KEY_MT==NORMAL_FIND)
									{
									 IO_STATUS[UNIT][1]=(U4|U5|U6);
									 IO_STATUS[UNIT][BYTE_IO_U_1]=0x08;
									}
							 }


				CSW_COUNT[UNIT]-=COUNT_CC;

				//tt(UNIT);
				break;
		case 0x51:     /* ПОИСК ПО ИДЕНТИФИКАТОРУ НА БОЬШЕ
									 */
				if (CSW_COUNT[UNIT]<5) COUNT_CC=CSW_COUNT[UNIT];
				else COUNT_CC=5;

				KEY_CMP=CC_GT;
				KEY_FIND=FIND_ID;
				KEY_MT=NORMAL_FIND;
				goto FIND_00;
				break;
		case 0x71:     /* ПОИСК ПО ИДЕНТИФИКАТОРУ НА БОЛЬШЕ ИЛИ РАВНО
									 */
				if (CSW_COUNT[UNIT]<5) COUNT_CC=CSW_COUNT[UNIT];
				else COUNT_CC=5;

				KEY_CMP=CC_GE;
				KEY_FIND=FIND_ID;
				KEY_MT=NORMAL_FIND;
				goto FIND_00;
				break;

		case 0x29:     /* ПОИСК ПО КЛЮЧУ НА РАВНО
									 */
				COUNT_CC=CSW_COUNT[UNIT];
				KEY_CMP=CC_EQ;
				KEY_FIND=FIND_KEY;
				KEY_MT=NORMAL_FIND;
				goto FIND_00;
				break;
		case 0x49:     /* ПОИСК ПО КЛЮЧУ НА БОЛЬШЕ
									 */
				COUNT_CC=CSW_COUNT[UNIT];
				KEY_CMP=CC_GT;
				KEY_FIND=FIND_KEY;
				KEY_MT=NORMAL_FIND;
				goto FIND_00;
				break;
		case 0x69:     /* ПОИСК ПО КЛЮЧУ НА БОЛЬШЕ ИЛИ РАВНО
									 */
				COUNT_CC=CSW_COUNT[UNIT];
				KEY_CMP=CC_GE;
				KEY_FIND=FIND_KEY;
				KEY_MT=NORMAL_FIND;
				goto FIND_00;
				break;

		case 0x2d:     /* ПОИСК ПО КЛЮЧУ И ДАННЫМ НА РАВНО
									 */
				tt(UNIT);
				break;
		case 0x4d:     /* ПОИСК ПО КЛЮЧУ И ДАННЫМ НА БОЛЬШЕ
									 */
				tt(UNIT);
				break;
		case 0x6d:     /* ПОИСК ПО КЛЮЧУ И ДАННЫМ НА БОЛЬШЕ ИЛИ РАВНО
									 */
				tt(UNIT);
				break;

		case 0xb9:     /* МТ-ПОИСК ПО СОБСТВЕННОМУ АДРЕСУ НА РАВНО
									 */
				tt(UNIT);
				break;
		case 0xb1:     /* МТ-ПОИСК ПО ИДЕНТИФИКАТОРУ НА РАВНО
									 */
				if (CSW_COUNT[UNIT]<5) COUNT_CC=CSW_COUNT[UNIT];
				else COUNT_CC=5;

				KEY_CMP=CC_EQ;
				KEY_FIND=FIND_ID;
				KEY_MT=MT_FIND;
				goto FIND_00;
				break;
		case 0xd1:     /* МТ-ПОИСК ПО ИДЕНТИФИКАТОРУ НА БОЛЬШЕ
									 */
				if (CSW_COUNT[UNIT]<5) COUNT_CC=CSW_COUNT[UNIT];
				else COUNT_CC=5;

				KEY_CMP=CC_GT;
				KEY_FIND=FIND_ID;
				KEY_MT=MT_FIND;
				goto FIND_00;
				break;
		case 0xf1:     /* МТ-ПОИСК ПО ИДЕНТИФИКАТОРУ НА БОЛЬШЕ ИЛИ РАВНО
									 */

				if (CSW_COUNT[UNIT]<5) COUNT_CC=CSW_COUNT[UNIT];
				else COUNT_CC=5;

				KEY_CMP=CC_GE;
				KEY_FIND=FIND_ID;
				KEY_MT=MT_FIND;
				goto FIND_00;
				break;
		case 0xa9:     /* МТ-ПОИСК ПО КЛЮЧУ НА РАВНО
									 */
				COUNT_CC=CSW_COUNT[UNIT];
				KEY_CMP=CC_EQ;
				KEY_FIND=FIND_KEY;
				KEY_MT=MT_FIND;
				goto FIND_00;
				break;
		case 0xc9:     /* МТ-ПОИСК ПО КЛЮЧУ НА БОЛЬШЕ
									 */
				COUNT_CC=CSW_COUNT[UNIT];
				KEY_CMP=CC_GT;
				KEY_FIND=FIND_KEY;
				KEY_MT=MT_FIND;
				goto FIND_00;
				break;
		case 0xe9:     /* МТ-ПОИСК ПО КЛЮЧУ НА БОЛЬШЕ ИЛИ РАВНО
									 */
				COUNT_CC=CSW_COUNT[UNIT];
				KEY_CMP=CC_GE;
				KEY_FIND=FIND_KEY;
				KEY_MT=MT_FIND;
				goto FIND_00;
				break;
		case 0xad:     /* МТ-ПОИСК ПО КЛЮЧУ И ДАННЫМ НА РАВНО
									 */
				tt(UNIT);
				break;
		case 0xcd:     /* МТ-ПОИСК ПО КДЮЧУ И ДАННЫМ НА БОЛЬШЕ
									 */
				tt(UNIT);
				break;
		case 0xed:     /* МТ-ПОТСК ПО КЛЮЧУ И ДАННЫМ НА БОЛЬШЕ ИЛИ РАВНО
									 */
				tt(UNIT);
				break;

		case 0x12:     /* ЧТЕНИЕ СЧЕТЧИКА
									 */
				KEY_READ_R0=NOT_READ_R0;
				KEY_READ_MT=READ_NORMAL;
				KEY_READ=READ_COUNT;
				COUNT_CC=CSW_COUNT[UNIT];
				goto READ;
				break;
		case 0x92:     /* МТ-ЧТЕНИЕ СЧЕТЧИКА

									 */
				KEY_READ_R0=NOT_READ_R0;
				KEY_READ_MT=READ_MT;
				KEY_READ=READ_COUNT;
				COUNT_CC=CSW_COUNT[UNIT];
				goto READ;
				break;
		case 0x1e:     /* ЧТЕНИЕ СЧЕТЧИКА УЛЮЧА М ДАННЫХ
									 */
				KEY_READ_R0=NOT_READ_R0;
				KEY_READ_MT=READ_NORMAL;
				KEY_READ=READ_COUNT|READ_KEY|READ_DATA;
				COUNT_CC=CSW_COUNT[UNIT];
				goto READ;
				break;
		case 0x9e:     /* МТ-ЧТЕНИЕ СЧЕТЧИКА КЛЮЧА И ДАННЫХ
									 */
				KEY_READ_R0=NOT_READ_R0;
				KEY_READ_MT=READ_MT;
				KEY_READ=READ_COUNT|READ_KEY|READ_DATA;
				COUNT_CC=CSW_COUNT[UNIT];
				goto READ;
				break;
		case 0x0e:     /* ЧТЕНИЕ КЛЮЧА И ДАННЫХ
									 */
				KEY_READ_R0=NOT_READ_R0;
				KEY_READ_MT=READ_NORMAL;
				KEY_READ=READ_DATA|READ_KEY;
				COUNT_CC=CSW_COUNT[UNIT];
				goto READ;
				break;
		case 0x8e:     /* МТ-ЧТЕНИЕ КЛЮЧА И ДАННЫХ
									 */
				KEY_READ_R0=NOT_READ_R0;
				KEY_READ_MT=READ_MT;
				KEY_READ=READ_DATA|READ_KEY;
				COUNT_CC=CSW_COUNT[UNIT];
				goto READ;

				break;
		case 0x06:     /* ЧТЕНИЕ ДАННЫХ
									 */
				KEY_READ_R0=NOT_READ_R0;
				KEY_READ_MT=READ_NORMAL;
				KEY_READ=READ_DATA;
				COUNT_CC=CSW_COUNT[UNIT];

READ:   IO_STATUS[UNIT][2]=0;  /* уточнить состояние==0*/
				IO_STATUS[UNIT][3]=0;
				if (
						((OLD_OPERATION[UNIT]==READ_COUNT)   &&
						 ((KEY_READ==(READ_KEY|READ_DATA))|| (KEY_READ==READ_DATA)
						 )
						)
					 ) lseek(IO_STATUS[UNIT][9],OLD_OFFSET_IO_DEVICE[UNIT],SEEK_SET);
				else lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT],SEEK_SET);
READ0:
				OFFSET_RR=tell(IO_STATUS[UNIT][9]);
				OLD_OFFSET_IO_DEVICE[UNIT]=OFFSET_RR;
				read(IO_STATUS[UNIT][9],FF_00,1);
				if (FF_00[0]==0x11)
					{
					 read(IO_STATUS[UNIT][9],ID_R0,9);
					 LEN_KEY=ID_R0[6];
					 if (LEN_KEY) read(IO_STATUS[UNIT][9],KEY,LEN_KEY);
					 LEN_DATA=(ID_R0[7]<<8)+ID_R0[8];
					 if (LEN_DATA) read(IO_STATUS[UNIT][9],BUFER,LEN_DATA);
					 if (KEY_READ==READ_COUNT && OLD_OPERATION[UNIT]==FIND_ID)
							{OFFSET_IO_DEVICE[UNIT]=tell(IO_STATUS[UNIT][9]);
							 OLD_OPERATION[UNIT]=0;
							 goto READ0;
							}
					 if (KEY_READ==READ_COUNT)
							{if (ID_R0[5]==0) goto READ0;/*    R0  NOT READ */
							 if (COUNT_CC<=8) count_cc=CSW_COUNT[UNIT];
							 else count_cc=8;
							 if ((CSW_MOD[UNIT]&0x10)==0)
								 MOVE_MEM_TO_360(&ID_R0[1],CSW_ADRESS[UNIT],count_cc);
							}
					 if (KEY_READ==(READ_COUNT|READ_KEY|READ_DATA))
							{if (ID_R0[5]==0 && KEY_READ_R0==NOT_READ_R0) goto READ0;/*    R0  NOT READ */
							 if (ID_R0[5]!=0 && KEY_READ_R0==READ_R0) goto READ0;
							 if (COUNT_CC<8) count_cc=COUNT_CC;
							 else count_cc=8;
							 if ((CSW_MOD[UNIT]&0x10)==0)
								MOVE_MEM_TO_360(&ID_R0[1],CSW_ADRESS[UNIT],count_cc);
							 all_read=count_cc;

							 if ((COUNT_CC-all_read)<LEN_KEY) count_cc=COUNT_CC-all_read;
							 else count_cc=LEN_KEY;

							 if ((CSW_MOD[UNIT]&0x10)==0)
								MOVE_MEM_TO_360(KEY,CSW_ADRESS[UNIT]+all_read,count_cc);
							 all_read+=count_cc;
							 if ((COUNT_CC-all_read)<LEN_DATA) count_cc=COUNT_CC-all_read;
							 else count_cc=LEN_DATA;

							 if ((CSW_MOD[UNIT]&0x10)==0)
								MOVE_MEM_TO_360(BUFER,CSW_ADRESS[UNIT]+all_read,count_cc);
							 all_read+=count_cc;
							 count_cc=all_read;
							}
					 if (KEY_READ==(READ_KEY|READ_DATA))
							{if (ID_R0[5]==0) goto READ0;/*    R0  NOT READ */
							 all_read=0;
							 if ((COUNT_CC-all_read)<LEN_KEY) count_cc=COUNT_CC-all_read;
							 else count_cc=LEN_KEY;

							 if ((CSW_MOD[UNIT]&0x10)==0)
								MOVE_MEM_TO_360(KEY,CSW_ADRESS[UNIT],count_cc);
							 all_read+=count_cc;
							 if ((COUNT_CC-all_read)<LEN_DATA) count_cc=COUNT_CC-all_read;
							 else count_cc=LEN_DATA;

							 if ((CSW_MOD[UNIT]&0x10)==0)
								MOVE_MEM_TO_360(BUFER,CSW_ADRESS[UNIT]+all_read,count_cc);
							 all_read+=count_cc;
							 count_cc=all_read;
							}
					 if (KEY_READ==(READ_DATA))
							{
							 if (COUNT_CC<=LEN_DATA) count_cc=COUNT_CC;
							 else count_cc=LEN_DATA;

							 if ((CSW_MOD[UNIT]&0x10)==0)
								MOVE_MEM_TO_360(BUFER,CSW_ADRESS[UNIT],count_cc);
							}
					 CSW_COUNT[UNIT]-=count_cc;
					 IO_STATUS[UNIT][1]=U4|U5;

					 if ((KEY_READ==(READ_DATA)) ||
							 (KEY_READ==(READ_KEY|READ_DATA))
							)
						 {
							if (LEN_DATA==0) IO_STATUS[UNIT][1]|=U7;
						 }
					 //OLD_OFFSET_IO_DEVICE[UNIT]=OFFSET_IO_DEVICE[UNIT];
					 OFFSET_IO_DEVICE[UNIT]=tell(IO_STATUS[UNIT][9]);
					 OLD_OPERATION[UNIT]=KEY_READ;
					 read(IO_STATUS[UNIT][9],FF_00,1);
					 if (FF_00[0]==0x11) DASD[UNIT][DASD_CUR_RR]++;
					}
				else
					{OLD_OPERATION[UNIT]=0;
					 if (KEY_READ_MT==READ_MT)
						 {
							if ((DASD_MASK[UNIT] & 0x18)==0x18)
								{  /*******запрещен преход на следующий TRK******/
								 IO_STATUS[UNIT][BYTE_IO_U_1]=0x04;
								 IO_STATUS[UNIT][BYTE_IO]=U4|U5|U6;
								}
							else
								{  /*******переход на следующий TRK**************/
								 if (++DASD[UNIT][DASD_CUR_TRK] ==DASD[UNIT][DASD_TRK])
									 {  /*    END OF CYL */
										IO_STATUS[UNIT][BYTE_IO_U_1]=0x20;
										IO_STATUS[UNIT][BYTE_IO]=U4|U5|U6;
									 }
								 else
									 {  /*    NEXT TRK   */
										OFFSET_TRK=(long)(
													DASD[UNIT][DASD_CUR_CYL]*
													DASD[UNIT][DASD_TRK]+
													DASD[UNIT][DASD_CUR_TRK]
												 )*(long)(DASD[UNIT][DASD_LEN]);

										lseek(IO_STATUS[UNIT][9],OFFSET_TRK/*+5l*/,SEEK_SET);
										read(IO_STATUS[UNIT][9],ID_R0,5);
										OFFSET_IO_DEVICE[UNIT]=/*OFFSET_TRK+5l*/tell(IO_STATUS[UNIT][9]);
										DASD[UNIT][DASD_CUR_RR]=0;
										goto READ;
									 }
								}
						 }
					 else
						 {IO_STATUS[UNIT][BYTE_IO]=U4|U5|U6;
							IO_STATUS[UNIT][BYTE_IO_U_1]=0x08;
						 }
					}
//				tt(UNIT);
				break;
		case 0x86:     /* МТ-ЧТЕНИЕ ДАННЫХ
									 */
				KEY_READ_R0=NOT_READ_R0;
				KEY_READ_MT=READ_MT;
				KEY_READ=READ_DATA;
				COUNT_CC=CSW_COUNT[UNIT];
				goto READ;
				//tt(UNIT);
				break;
		case 0x16:     /* ЧТЕНИЕ R0
									 */
				OFFSET_TRK=(long)(
													DASD[UNIT][DASD_CUR_CYL]*
													DASD[UNIT][DASD_TRK]+
													DASD[UNIT][DASD_CUR_TRK]
												 )*(long)(DASD[UNIT][DASD_LEN]);

				OFFSET_IO_DEVICE[UNIT]=OFFSET_TRK;
				lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT],SEEK_SET);
				read(IO_STATUS[UNIT][9],ID_R0,5);
				OFFSET_IO_DEVICE[UNIT]=tell(IO_STATUS[UNIT][9]);
				KEY_READ_R0=READ_R0;
				KEY_READ_MT=READ_NORMAL;
				KEY_READ=READ_COUNT|READ_KEY|READ_DATA;
				COUNT_CC=CSW_COUNT[UNIT];
				goto READ;
				break;
		case 0x96:     /* МТ-ЧТЕНИЕ R0
									 */
				OFFSET_TRK=(long)(
													DASD[UNIT][DASD_CUR_CYL]*
													DASD[UNIT][DASD_TRK]+
													DASD[UNIT][DASD_CUR_TRK]
												 )*(long)(DASD[UNIT][DASD_LEN]);

				OFFSET_IO_DEVICE[UNIT]=OFFSET_TRK;
				lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT],SEEK_SET);
				read(IO_STATUS[UNIT][9],ID_R0,5);
				OFFSET_IO_DEVICE[UNIT]=tell(IO_STATUS[UNIT][9]);
				KEY_READ_R0=READ_R0;
				KEY_READ_MT=READ_MT;
				KEY_READ=READ_COUNT|READ_KEY|READ_DATA;
				COUNT_CC=CSW_COUNT[UNIT];
				goto READ;
				break;
		case 0x1a:     /* ЧТЕНИЕ СОБСТВЕННОГО АДРЕСА
									 */
				OFFSET_TRK=(long)(
													DASD[UNIT][DASD_CUR_CYL]*
													DASD[UNIT][DASD_TRK]+
													DASD[UNIT][DASD_CUR_TRK]
												 )*(long)(DASD[UNIT][DASD_LEN]);

				OFFSET_IO_DEVICE[UNIT]=OFFSET_TRK;
				lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT],SEEK_SET);
				read(IO_STATUS[UNIT][9],ID_R0,5);
				if ((CSW_MOD[UNIT]&0x10)==0)
				 MOVE_MEM_TO_360(ID_R0,CSW_ADRESS[UNIT],CSW_COUNT[UNIT]);
				OFFSET_IO_DEVICE[UNIT]=tell(IO_STATUS[UNIT][9]);
				CSW_COUNT[UNIT]=0;
				IO_STATUS[UNIT][1]=U4|U5;
				OLD_OPERATION[UNIT]=0;
				//tt(UNIT);
				break;
		case 0x9a:     /* МТ-ЧТЕНИЕ СОБСТВЕННОГО АДРЕСА
									 */
				tt(UNIT);
				break;
		case 0x02:     /* ЧТЕНИЕ НАЧАЛЬНОЙ ЗАГРУЗКИ ПРОГРАММЫ
									 */
				DASD[UNIT][DASD_CUR_CYL]=0;
				DASD[UNIT][DASD_CUR_TRK]=0;
				DASD[UNIT][DASD_CUR_RR]=0;
				OFFSET_TRK=(long)(
													DASD[UNIT][DASD_CUR_CYL]*
													DASD[UNIT][DASD_TRK]+
													DASD[UNIT][DASD_CUR_TRK]
												 )*(long)(DASD[UNIT][DASD_LEN]);

				OFFSET_IO_DEVICE[UNIT]=OFFSET_TRK;
				lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT],SEEK_SET);
				read(IO_STATUS[UNIT][9],ID_R0,5);

				C_ID_R0_KEY[0]=0;
				C_ID_R0_KEY[1]=0;

				C_ID_R0_KEY[2]=0;
				C_ID_R0_KEY[3]=0;

				C_ID_R0_KEY[4]=1;
				COUNT_CC=5;

				OFFSET_IO_DEVICE[UNIT]=tell(IO_STATUS[UNIT][9]);
CIKL_DD2:OFFSET_RR=tell(IO_STATUS[UNIT][9]);
				read(IO_STATUS[UNIT][9],FF_00,1);
				if (FF_00[0]==0x11)
					{
					 read(IO_STATUS[UNIT][9],ID_R0,9);
					 if (memcmp(&ID_R0[1],C_ID_R0_KEY,COUNT_CC)==0)
						 {IO_STATUS[UNIT][1]=(U1|U4|U5);
																							 /* модификатор состояния
																									устройство кончило
																							 */
							CYL=(ID_R0[1]<<8)+ID_R0[2];
							TRK=(ID_R0[3]<<8)+ID_R0[4];
							RR= ID_R0[5];
							DASD[UNIT][DASD_CUR_CYL]=CYL;
							DASD[UNIT][DASD_CUR_TRK]=TRK;
							DASD[UNIT][DASD_CUR_RR] =RR;
							OFFSET_IO_DEVICE[UNIT]=OFFSET_RR;
							KEY_READ_R0=NOT_READ_R0;
							KEY_READ_MT=READ_NORMAL;
							KEY_READ=READ_DATA;
							COUNT_CC=CSW_COUNT[UNIT];
							goto READ;
						 }
					 else
						 {LEN_KEY=ID_R0[6];
							if (LEN_KEY)
								{read(IO_STATUS[UNIT][9],KEY,LEN_KEY);
								 //lseek(IO_STATUS[UNIT][9],(unsigned long)LEN_KEY,SEEK_CUR);
								}
							LEN_DATA=(ID_R0[7]<<8)+ID_R0[8];
							if (LEN_DATA)
								{read(IO_STATUS[UNIT][9],BUFER,LEN_DATA);
								 //lseek(IO_STATUS[UNIT][9],(unsigned long)LEN_DATA,SEEK_CUR);
								}
							goto CIKL_DD2;
						 }
					}
				else
					{IO_STATUS[UNIT][1]=(U4|U5|U6);
					 IO_STATUS[UNIT][BYTE_IO_U_1]=0x08;
					}

				tt(UNIT);
				break;
		case 0x19:     /* ЗАПИСЬ СОБСТВЕННОГО АДРЕСА
									 */
				tt(UNIT);
				break;
		case 0x15:     /* ЗАПИСЬ R0
									 */
				tt(UNIT);
				break;
		case 0x1d:     /* ЗАПИСЬ СЧЕТЧИКА КЛЮЧА И ДАННЫХ
									 */
				BYTE_PR_OUT[0]=0x11;
WR_C_K_D:
				IO_STATUS[UNIT][2]=0;  /* уточнить состояние==0*/
				IO_STATUS[UNIT][3]=0;
				lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT],SEEK_SET);
				read(IO_STATUS[UNIT][9],FF_00,1);
				if (FF_00[0]==0x11)
					{
					 read(IO_STATUS[UNIT][9],ID_R0,9);
					 LEN_KEY=ID_R0[6];
					 if (LEN_KEY) read(IO_STATUS[UNIT][9],KEY,LEN_KEY);
					 LEN_DATA=(ID_R0[7]<<8)+ID_R0[8];
					 if (LEN_DATA) read(IO_STATUS[UNIT][9],BUFER,LEN_DATA);
					}
				else
					{
					 lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT],SEEK_SET);
					}
				FF_00[0]=0x11;
				OFFSET_IO_DEVICE[UNIT]=tell(IO_STATUS[UNIT][9]);
				write(IO_STATUS[UNIT][9],FF_00,1);
				write(IO_STATUS[UNIT][9],BYTE_PR_OUT,1);
				LEN_ALL_DATA=0;
				for(i=0;i<9;i++) ID_R0[i]=BUFER[i];
				LEN_KEY=ID_R0[6];
				LEN_DATA=(ID_R0[7]<<8)+ID_R0[8];
				COUNT_CC=9+LEN_KEY+LEN_DATA;

WR1D:
				MOVE_360_TO_MEM(CSW_ADRESS[UNIT],BUFER,CSW_COUNT[UNIT]);
				write(IO_STATUS[UNIT][9],BUFER,CSW_COUNT[UNIT]);
				LEN_ALL_DATA+=CSW_COUNT[UNIT];
				if(CSW_MOD[UNIT] & 0x80)      /* цепочка данных */
					{
					 CH_DATA(UNIT);
					 //tt(UNIT);
					 goto WR1D;
					}
				IO_STATUS[UNIT][BYTE_IO]=U4|U5;
				CSW_COUNT[UNIT]=0;
				OLD_OPERATION[UNIT]=WRITE_DATA;

				//tt(UNIT);
				break;
		case 0x01:     /* ЗАПИСЬ СПЕЦИАЛЬНОГО СЧЕТЧИКА КЛЮЧА И ДАННЫХ
									 */
				BYTE_PR_OUT[0]=0x51;
				goto WR_C_K_D;
				//tt(UNIT);
				break;
		case 0x05:     /* ЗАПИСЬ ДАННЫХ
									 */
				IO_STATUS[UNIT][2]=0;  /* уточнить состояние==0*/
				IO_STATUS[UNIT][3]=0;
				lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT],SEEK_SET);
				read(IO_STATUS[UNIT][9],FF_00,1);
				if (FF_00[0]==0x11)
					{
					 read(IO_STATUS[UNIT][9],ID_R0,9);
					 LEN_KEY=ID_R0[6];
					 LEN_DATA=(ID_R0[7]<<8)+ID_R0[8];
					 if (LEN_KEY) read(IO_STATUS[UNIT][9],KEY,LEN_KEY);
					 MOVE_360_TO_MEM(CSW_ADRESS[UNIT],BUFER,CSW_COUNT[UNIT]);
					 if (LEN_DATA>CSW_COUNT[UNIT])
							for(i=CSW_COUNT[UNIT];i<LEN_DATA;i++)
								 BUFER[i]=0;
					 write(IO_STATUS[UNIT][9],BUFER,LEN_DATA);
					 //if(CSW_MOD[UNIT] & 0x80)      /* цепочка данных */
					 //	 {
					 //		CH_DATA(UNIT);
					 //		tt(UNIT);
					 //		goto WR1D;
					 //	 }
					 OFFSET_IO_DEVICE[UNIT]=tell(IO_STATUS[UNIT][9]);
					 IO_STATUS[UNIT][BYTE_IO]=U4|U5;
					 CSW_COUNT[UNIT]=0;

					}
				else
					{
					 IO_STATUS[UNIT][BYTE_IO]=U4|U5|U6;
					 IO_STATUS[UNIT][BYTE_IO_U_1]=0x10;
					}

				OLD_OPERATION[UNIT]=WRITE_DATA;
				//tt(UNIT);
				break;
		case 0x0d:     /* ЗАПИСЬ КЛЮЧА И ДАННЫХ
									 */
				IO_STATUS[UNIT][2]=0;  /* уточнить состояние==0*/
				IO_STATUS[UNIT][3]=0;
				lseek(IO_STATUS[UNIT][9],OFFSET_IO_DEVICE[UNIT],SEEK_SET);
				read(IO_STATUS[UNIT][9],FF_00,1);
				if (FF_00[0]==0x11)
					{
					 read(IO_STATUS[UNIT][9],ID_R0,9);
					 LEN_KEY=ID_R0[6];
					 LEN_DATA=(ID_R0[7]<<8)+ID_R0[8];
					 MOVE_360_TO_MEM(CSW_ADRESS[UNIT],BUFER,CSW_COUNT[UNIT]);
					 if (LEN_KEY+LEN_DATA>CSW_COUNT[UNIT])
							for(i=CSW_COUNT[UNIT];i<LEN_KEY+LEN_DATA;i++)
								 BUFER[i]=0;
					 write(IO_STATUS[UNIT][9],BUFER,LEN_KEY+LEN_DATA);
					 OFFSET_IO_DEVICE[UNIT]=tell(IO_STATUS[UNIT][9]);
					 IO_STATUS[UNIT][BYTE_IO]=U4|U5;
					 CSW_COUNT[UNIT]=0;

					}
				else
					{
					 IO_STATUS[UNIT][BYTE_IO]=U4|U5|U6;
					 IO_STATUS[UNIT][BYTE_IO_U_1]=0x10;
					}

				OLD_OPERATION[UNIT]=WRITE_DATA;
				//tt(UNIT);
				break;
		case 0x11:     /* СТЕРЕТЬ
									 */
				CSW_COUNT[UNIT]=0;
				IO_STATUS[UNIT][BYTE_IO]=U4|U5;
				tt(UNIT);
				break;
		case 0x17:     /*  НОП
									 */
		case 0x03:     /* НОП

									 */
				//CSW_COUNT[UNIT]=0;
				IO_STATUS[UNIT][BYTE_IO]=U4|U5;
				//IO_STATUS[UNIT][0]=S0;
				//tt(UNIT);
				break;
		case 0x1f:     /* УСТАНОВИТЬ МАСКУ ФАЙЛА
									 */
				ar=CSW_ADRESS[UNIT];
				DASD_MASK[UNIT]=GET_BYTE(ar);
				CSW_COUNT[UNIT]=0;
				OLD_OPERATION[UNIT]=0;
				IO_STATUS[UNIT][BYTE_IO]=U4|U5;
//				tt(UNIT);
				break;
		case 0x13:     /* УСТАНОВКА В НАЧАЛЬНОЕ ПОЛОЖЕНИЕ
									 */
				DASD[UNIT][DASD_CUR_CYL]=0;
				DASD[UNIT][DASD_CUR_TRK]=0;
				DASD[UNIT][DASD_CUR_RR]=0;
				OFFSET_IO_DEVICE[UNIT]=0;
				CSW_COUNT[UNIT]=0;
				IO_STATUS[UNIT][BYTE_IO]=U4|U5;
				OLD_OPERATION[UNIT]=0;
				tt(UNIT);
				break;
		case 0x04:     /* УТОЧНИТЬ СОСТОЯНИЕ
									 */


				for(i=0,ar=CSW_ADRESS[UNIT];i<6;i++,ar++)
						{
						 PUT_BYTE(ar,IO_STATUS[UNIT][i+2]);IO_STATUS[UNIT][i+2]=0;
						}
				IO_STATUS[UNIT][1]=U4|U5;
				IO_STATUS[UNIT][2]=0;
				IO_STATUS[UNIT][3]=0;
				CSW_COUNT[UNIT]=0;
				if (RQ_TRACE) printf("\n 04 command ");
				//tt(UNIT);
				break;
		case 0xb4:     /* ЗАРЕЗЕРВИРОВАТЬ УСТРОЙСТВО
									 */
				tt(UNIT);
				break;
		case 0x94:     /* ОСВОБОДИТЬ УСТРОЙСТВО
									 */
				tt(UNIT);
				break;


		default:
				IO_STATUS[UNIT][BYTE_IO_U_0]=0x80; /* недорустимая команда */
				IO_STATUS[UNIT][BYTE_IO_U_1]=0x10;
				IO_STATUS[UNIT][BYTE_IO]=U4|U5|U6;
				tt(UNIT);
				break;
		}

}
Example #12
0
static int
run_vm(ClipMachine * mp, ClipBlock * bp)
{
	char *func = bp->func;
	char *modbeg = func - GETLONG(func);
	char *pp = modbeg + GETLONG(F_OFFS(func, 1, 0, 0));
	char code;
	long len = GETLONG(F_OFFS(func, 2, 0, 0));
	char *beg = pp, *end = pp + len;
	long staticsOffs = GETLONG(modbeg);
	ClipFile *file = bp->file;
	ClipVar *statics = file->statics + staticsOffs;
	int nlocals = GETSHORT(F_OFFS(func, 3, 0, 1));
	int nreflocals = GETSHORT(F_OFFS(func, 3, 1, 1));
	int ret = 0;
	int i;
#if 0
	ClipVar *locals /* = alloca(sizeof(ClipVar) * nlocals) */ ;
#endif
	int maxdeep = GETSHORT(F_OFFS(func, 3, 2, 1));
	ClipVar *stack = alloca(sizeof(ClipVar) * maxdeep);
	char *filename = F_OFFS(modbeg, 6, 6, 0);
	int nprivates = GETSHORT(F_OFFS(func, 3, 3, 1));

	/*int nparams = GETSHORT( F_OFFS(func, 3, 4, 1)); */
	/*long *privates = (long *) F_OFFS(func, 3, 5, 1); */
	/*long *localDefHashs = (long *) F_OFFS(func, 3 + nprivates, 5, 1); */
	int numlocals = nlocals + nreflocals;

	/*ClipVarDef *ldp, *localDefs = alloca(sizeof(ClipVarDef) * (numlocals+1)); */
	/*short *localDefNums = (short *) F_OFFS(func, 3 + nprivates + numlocals, 5, 1); */

	char *procname = F_OFFS(func, 3 + nprivates + numlocals, 5 + numlocals, 1 + 1);
	char *localnames = procname + *(unsigned char *) F_OFFS(func, 3 + nprivates + numlocals, 5 + numlocals, 1) + 1;

	/*ClipVar *params = alloca( nparams*sizeof(ClipVar)); */
	ClipFrame frame =
	{stack, stack, filename, 0, 0, 0, 0 /*localDefs */ , file->staticDefs, 0,
	 file->hash_names, procname, maxdeep, 0};
	unsigned char c, c1;
	short s, s1;
	long l, l1;
	ClipVar *vp;
	ClipBlock bl;
	char *trap_pp = 0;
	int debuglevel = _clip_debuglevel;
	ClipVarFrame *localvars = 0, *reflocals = 0;
	int local_locals = 0;

	if (!nlocals && !nreflocals)
	{
		reflocals = frame.localvars = mp->fp->localvars;
		if (reflocals && reflocals->refcount)
			reflocals->refcount++;
	}
	else if (nreflocals)
	{
		localvars = calloc(1, sizeof(ClipVarFrame) + numlocals * sizeof(ClipVar));
		localvars->vars = (ClipVar *) (localvars + 1);
		localvars->refcount = 1;
		reflocals = frame.localvars = localvars;
		localvars->size = numlocals;
		localvars->names = localnames;
	}
	else
	{
#if 1
		localvars = calloc(1, sizeof(ClipVarFrame) + numlocals * sizeof(ClipVar));
		localvars->vars = (ClipVar *) (localvars + 1);
		localvars->size = numlocals;
		localvars->refcount = 1;
		localvars->names = localnames;
		reflocals = frame.localvars = localvars;
#else
		locals = alloca(sizeof(ClipVar) * numlocals);
		memset(locals, 0, numlocals * sizeof(ClipVar));
		localvars = alloca(sizeof(ClipVarFrame));
		localvars->vars = locals;
		localvars->size = numlocals;
		localvars->refcount = 0;
		localvars->names = localnames;
		reflocals = frame.localvars = localvars;
		local_locals = 1;
#endif
	}

	frame.up = mp->fp;
	mp->fp = &frame;

#if 0
	localDefs[0].name = numlocals;
	for (i = 0, ldp = localDefs + 1; i < numlocals; i++, ldp++, localDefHashs++, localDefNums++)
	{
		/*int no = *localDefNums; */
		long hash = *localDefHashs;

		ldp->name = hash;
		/*
		   if (no < 0)
		   ldp->vp = reflocals - no;
		   else
		 */
		/*ldp->vp = locals + no; */
		ldp->vp = 0;
	}
#endif

	if (_clip_profiler)
		_clip_start_profiler(mp);

	_clip_logg(4, "PCODE call: proc '%s' file '%s' line %d", frame.procname ? frame.procname : "unknown", frame.filename, frame.line);

      cont:
	while (pp >= beg && pp < end)
	{
		if (debuglevel)
			_clip_debug(mp);
		switch ((code = *pp++))
		{
		case CLIP_NOP:
			break;
		case CLIP_POP:
			_clip_pop(mp);
			break;
		case CLIP_LINE:
			frame.line = GET_SHORT(pp);
			if (debuglevel)
				_clip_line(mp);
			break;
		case CLIP_PUSH_NUM:
			{
				int len, dec;
				double d;

				s = GET_SHORT(pp);
				frame.sp->t.memo = 0;
				frame.sp->t.type = NUMERIC_t;
				frame.sp->t.flags = F_NONE;
				get_num(modbeg, s, &d, &len, &dec);
				frame.sp->t.len = len;
				frame.sp->t.dec = dec;
				frame.sp->n.d = d;
				frame.sp->t.memo = 0;
				++frame.sp;
			}
			break;
		case CLIP_PUSH_STR:
#if 0
			s = GET_SHORT(pp);
			frame.sp->t.type = CHARACTER_t;
			frame.sp->t.flags = F_MSTAT;
			frame.sp->t.memo = 0;
			get_str(modbeg, s, &(frame.sp->s.str.buf), &(frame.sp->s.str.len));
			/*
			if ( !(mp->flags1 & NOEXPAND_MACRO_FLAG) )
			{
			*/
				if (strchr(frame.sp->s.str.buf, '&'))
					_clip_expand_var(mp, frame.sp);
			/*}*/
			++frame.sp;
			break;
#endif
		case CLIP_PUSH_STRDUP:
			s = GET_SHORT(pp);
			frame.sp->t.type = CHARACTER_t;
			frame.sp->t.flags = F_NONE;
			frame.sp->t.memo = 0;
			{
				char *str = "";
				int len = 0;

				get_str(modbeg, s, &str, &len);
				frame.sp->s.str.buf = _clip_memdup(str, len);
				frame.sp->s.str.len = len;
			}
			/*
			if ( !(mp->flags1 & NOEXPAND_MACRO_FLAG) )
			{
			*/
				if (strchr(frame.sp->s.str.buf, '&'))
					_clip_expand_var(mp, frame.sp);
			/*}*/
			++frame.sp;
			break;
		case CLIP_PUSH_NIL:
			frame.sp->t.type = UNDEF_t;
			frame.sp->t.flags = F_NONE;
			++frame.sp;
			break;
		case CLIP_PUSH_TRUE:
			frame.sp->t.type = LOGICAL_t;
			frame.sp->t.flags = F_NONE;
			frame.sp->l.val = 1;
			++frame.sp;
			break;
		case CLIP_PUSH_FALSE:
			frame.sp->t.type = LOGICAL_t;
			frame.sp->t.flags = F_NONE;
			frame.sp->l.val = 0;
			++frame.sp;
			break;
		case CLIP_MEMVAR_PUBLIC:
			l = GET_LONG(pp);
			_clip_memvar_public(mp, l);
			break;
		case CLIP_MEMVAR_SPACE:
			l = GET_LONG(pp);
			l1 = GET_LONG(pp);
			_clip_memvar_space(mp, _clip_space(mp, l), l1, 1);
			break;
		case CLIP_MEMVAR_PRIVATE:
			l = GET_LONG(pp);
			_clip_memvar_private(mp, l);
			break;
		case CLIP_MEMVAR_PUBLIC_POP:
			l = _clip_pop_hash(mp);
			_clip_memvar_public(mp, l);
			break;
		case CLIP_MEMVAR_SPACE_POP:
			l = GET_LONG(pp);
			l1 = _clip_pop_hash(mp);
			_clip_memvar_space(mp, _clip_space(mp, l), l1, 1);
			break;
		case CLIP_MEMVAR_PRIVATE_POP:
			l = _clip_pop_hash(mp);
/*_clip_memvar_private(mp, l);*/
			_clip_add_private(mp, l);
			break;
		case CLIP_MEMVAR_PARAM:
			l = GET_LONG(pp);
			c = GET_BYTE(pp);
			_clip_memvar_param(mp, l, c);
			break;
		case CLIP_PUSH_PARAM:
			c = GET_BYTE(pp);
			s = GET_SHORT(pp);
			_clip_param(mp, c, s);
			break;
		case CLIP_PUSH_LOCAL:
			s = GET_SHORT(pp);
			if ((ret = _clip_push_local(mp, s)))
				goto _trap;
			break;
		case CLIP_PUSH_REF_LOCAL:
			s = GET_SHORT(pp);
#if 0
			frame.sp->p.vp = _clip_ref_local(mp, s);
#else
			{
				ClipVar *vp1 = _clip_ref_local(mp, s);
				frame.sp->p.vp = vp1;
			}
#endif
			break;
		case CLIP_PUSH_STATIC:
			s = GET_SHORT(pp);
			get_static(mp, file, statics, modbeg, s, &vp);
			if ((ret = _clip_push_static(mp, vp)))
				goto _trap;
			break;
		case CLIP_PUSH_REF_STATIC:
			s = GET_SHORT(pp);
			get_static(mp, file, statics, modbeg, s, &vp);
			frame.sp->p.vp = vp;
			break;
		case CLIP_PUSH_MEMVAR:
			l = GET_LONG(pp);
			if ((ret = _clip_memvar(mp, l)))
				goto _trap;
			break;
		case CLIP_PUSH_FMEMVAR:
			l = GET_LONG(pp);
			if ((ret = _clip_fmemvar(mp, l)))
				goto _trap;
			break;
		case CLIP_PUSH_MEMVARF:
			l = GET_LONG(pp);
			if ((ret = _clip_memvarf(mp, l)))
				goto _trap;
			break;
		case CLIP_REF_FMEMVAR:
			l = GET_LONG(pp);
			if ((ret = _clip_ref_fmemvar(mp, l)))
				goto _trap;
			break;
		case CLIP_PUSH_REF_MEMVAR:
			l = GET_LONG(pp);
#if 0
			frame.sp->p.vp = _clip_ref_memvar(mp, l);
#else
			{
				ClipVar *vp1 = _clip_ref_memvar(mp, l);
				frame.sp->p.vp = vp1;
			}
#endif
			break;
		case CLIP_PUSH_REF_MEMVAR_NOADD:
			l = GET_LONG(pp);
			{
				ClipVar *vp1 = _clip_ref_memvar_noadd(mp, l);
				frame.sp->p.vp = vp1;
			}
			break;
		case CLIP_PUSH_PUBLIC:
			l = GET_LONG(pp);
			if ((ret = _clip_public(mp, l)))
				goto _trap;
			break;
		case CLIP_PUSH_REF_PUBLIC:
			l = GET_LONG(pp);
#if 0
			frame.sp->p.vp = _clip_ref_public(mp, l);
#else
			{
				ClipVar *vp1 = _clip_ref_public(mp, l);
				frame.sp->p.vp = vp1;
			}
#endif
			break;
		case CLIP_REFMACRO:
			if ((ret = _clip_refmacro(mp)))
				goto _trap;
			break;
		case CLIP_MAKE_REF:
			c = GET_BYTE(pp);
			vp = frame.sp->p.vp;
			if ((ret = _clip_ref(mp, vp, c)))
				goto _trap;
			break;
		case CLIP_UNREF_ARR:
			_clip_unref_arr(mp);
			break;
		case CLIP_FIELD:
			l = GET_LONG(pp);
			l1 = GET_LONG(pp);
			if ((ret = _clip_field(mp, l, l1)))
				goto _trap;
			break;
		case CLIP_FIELD_POP:
			l = GET_LONG(pp);
			l1 = _clip_pop_hash(mp);
			if ((ret = _clip_field(mp, l, l1)))
				goto _trap;
			break;
		case CLIP_FIELD_POP_NAME:
			_clip_pop_fieldhash(mp, &l1, &l);
			if ((ret = _clip_field(mp, l, l1)))
				goto _trap;
			break;
		case CLIP_PUSH_AREA:
			l = GET_LONG(pp);
			if ((ret = _clip_push_area(mp, l)))
				goto _trap;
			break;
		case CLIP_PUSH_AREA_POP:
			l = _clip_pop_hash(mp);
			if ((ret = _clip_push_area(mp, l)))
				goto _trap;
			break;
		case CLIP_POP_AREA:
			if ((ret = _clip_pop_area(mp)))
				goto _trap;
			break;
		case CLIP_FUNC:
			c = GET_BYTE(pp);
			l = GET_LONG(pp);
			if ((ret = _clip_func_hash(mp, l, c, 0, reflocals)))
				goto _trap;
			break;
		case CLIP_FUNCR:
			c = GET_BYTE(pp);
			l = GET_LONG(pp);
			if ((ret = _clip_func_hash(mp, l, c, 1, reflocals)))
				goto _trap;
			break;
		case CLIP_PROC:
			c = GET_BYTE(pp);
			l = GET_LONG(pp);
			if ((ret = _clip_proc_hash(mp, l, c, 0, reflocals)))
				goto _trap;
			break;
		case CLIP_PROCR:
			c = GET_BYTE(pp);
			l = GET_LONG(pp);
			if ((ret = _clip_proc_hash(mp, l, c, 1, reflocals)))
				goto _trap;
			break;
		case CLIP_SFUNC:
			c = GET_BYTE(pp);
			s = GET_SHORT(pp);
			bl.file = file;
			get_func(modbeg, s, &bl.func);
			if ((ret = _clip_code_func(mp, &bl, c, 0, reflocals)))
				goto _trap;
			break;
		case CLIP_SFUNCR:
			c = GET_BYTE(pp);
			s = GET_SHORT(pp);
			bl.file = file;
			get_func(modbeg, s, &bl.func);
			if ((ret = _clip_code_func(mp, &bl, c, 1, reflocals)))
				goto _trap;
			break;
		case CLIP_SPROC:
			c = GET_BYTE(pp);
			s = GET_SHORT(pp);
			bl.file = file;
			get_func(modbeg, s, &bl.func);
			if ((ret = _clip_code_proc(mp, &bl, c, 0, reflocals)))
				goto _trap;
			break;
		case CLIP_SPROCR:
			c = GET_BYTE(pp);
			s = GET_SHORT(pp);
			bl.file = file;
			get_func(modbeg, s, &bl.func);
			if ((ret = _clip_code_proc(mp, &bl, c, 1, reflocals)))
				goto _trap;
			break;
		case CLIP_ASSIGN:
			vp = frame.sp->p.vp;
			if ((ret = _clip_assign(mp, vp)))
				goto _trap;
			break;
		case CLIP_REF_DESTROY:
			vp = frame.sp->p.vp;
			/*if (vp->t.flags != F_MREF)*/
				_clip_destroy(mp, vp);
			/*_clip_destroy(mp, vp);*/
			break;
		case CLIP_MACROASSIGN:
			c = GET_BYTE(pp);
			c1 = GET_BYTE(pp);
			if ((ret = _clip_macroassign(mp, c, c1 & 1, c1 & 2)))
				goto _trap;
			break;
		case CLIP_REFASSIGN:
			c = GET_BYTE(pp);
			vp = frame.sp->p.vp;
			if ((ret = _clip_refassign(mp, vp, c)))
				goto _trap;
			break;
		case CLIP_UNREF:
			vp = frame.sp->p.vp;
			_clip_destroy(mp, vp);
			break;
		case CLIP_IASSIGN:
			vp = frame.sp->p.vp;
			if ((ret = _clip_iassign(mp, vp)))
				goto _trap;
			break;
		case CLIP_OPASSIGN:
			c = GET_BYTE(pp);
			vp = frame.sp->p.vp;
			if ((ret = _clip_opassign(mp, vp, c)))
				goto _trap;
			break;
		case CLIP_OPIASSIGN:
			c = GET_BYTE(pp);
			vp = frame.sp->p.vp;
			if ((ret = _clip_opiassign(mp, vp, c)))
				goto _trap;
			break;
		case CLIP_ASSIGN_FIELD:
			l = GET_LONG(pp);
			l1 = GET_LONG(pp);
			if ((ret = _clip_assign_field(mp, l, l1)))
				goto _trap;
			break;
		case CLIP_IASSIGN_FIELD:
			l = GET_LONG(pp);
			l1 = GET_LONG(pp);
			if ((ret = _clip_iassign_field(mp, l, l1)))
				goto _trap;
			break;
		case CLIP_ASSIGN_FIELD_POP:
			l = GET_LONG(pp);
			l1 = _clip_pop_hash(mp);
			if ((ret = _clip_assign_field(mp, l, l1)))
				goto _trap;
			break;
		case CLIP_IASSIGN_FIELD_POP:
			l = GET_LONG(pp);
			l1 = _clip_pop_hash(mp);
			if ((ret = _clip_iassign_field(mp, l, l1)))
				goto _trap;
			break;
		case CLIP_ASSIGN_PFIELD:
			l = _clip_pop_hash(mp);
			l1 = GET_LONG(pp);
			if ((ret = _clip_assign_field(mp, l, l1)))
				goto _trap;
			break;
		case CLIP_IASSIGN_PFIELD:
			l = _clip_pop_hash(mp);
			l1 = GET_LONG(pp);
			if ((ret = _clip_iassign_field(mp, l, l1)))
				goto _trap;
			break;
		case CLIP_ASSIGN_PFIELD_POP:
			l = _clip_pop_hash(mp);
			l1 = _clip_pop_hash(mp);
			if ((ret = _clip_assign_field(mp, l, l1)))
				goto _trap;
			break;
		case CLIP_IASSIGN_PFIELD_POP:
			l = _clip_pop_hash(mp);
			l1 = _clip_pop_hash(mp);
			if ((ret = _clip_iassign_field(mp, l, l1)))
				goto _trap;
			break;
		case CLIP_FM_ASSIGN:
			l = GET_LONG(pp);
			if ((ret = _clip_fm_assign(mp, l)))
				goto _trap;
			break;
		case CLIP_FM_IASSIGN:
			l = GET_LONG(pp);
			if ((ret = _clip_fm_iassign(mp, l)))
				goto _trap;
			break;
		case CLIP_ARRAY:
			l = GET_LONG(pp);
			_clip_sarray(mp, l);
			break;
		case CLIP_DIMARRAY:
			l = GET_LONG(pp);
			_clip_dimarray(mp, l);
			break;
		case CLIP_NEWARRAY:
			l = GET_LONG(pp);
			_clip_vnewarray(mp, l, (long *) pp);
			pp += l * sizeof(long);

			break;
		case CLIP_GET:
			l = GET_LONG(pp);
			if ((ret = _clip_get(mp, l)))
				goto _trap;
			break;
		case CLIP_SET:
			l = GET_LONG(pp);
			if ((ret = _clip_set(mp, l)))
				goto _trap;
			break;
		case CLIP_RETURN_POP:
			_clip_return(mp);
		case CLIP_RETURN:
			goto _return;
		case CLIP_STORE:
			c1 = GET_BYTE(pp);
			c = GET_BYTE(pp);
			if ((ret = _clip_store(mp, c, c1)))
				goto _trap;
			break;
		case CLIP_ISTORE:
			c1 = GET_BYTE(pp);
			c = GET_BYTE(pp);
			if ((ret = _clip_istore(mp, c, c1)))
				goto _trap;
			break;
		case CLIP_OPSTORE:
			c = GET_BYTE(pp);
			c1 = GET_BYTE(pp);
			if ((ret = _clip_opstore(mp, c1, c)))
				goto _trap;
			break;
		case CLIP_OPISTORE:
			c = GET_BYTE(pp);
			c1 = GET_BYTE(pp);
			if ((ret = _clip_opistore(mp, c1, c)))
				goto _trap;
			break;
		case CLIP_FETCH:
			c = GET_BYTE(pp);
			if ((ret = _clip_fetch(mp, c)))
				goto _trap;
			break;
		case CLIP_FETCHREF:
			c = GET_BYTE(pp);
#if 0
			frame.sp->p.vp = _clip_fetchref(mp, c);
#else
			{
				ClipVar *vp1 = _clip_fetchref(mp, c);
				/*printf("%p\n", vp1);*/
				frame.sp->p.vp = vp1;
			}
#endif
			if (!frame.sp->p.vp)
				goto _trap;
			break;
		case CLIP_IFETCH:
			c = GET_BYTE(pp);
			if ((ret = _clip_ifetch(mp, c)))
				goto _trap;
			break;
		case CLIP_CALL:
			c = GET_BYTE(pp);
			l = GET_LONG(pp);
			if ((ret = _clip_call(mp, c, l)))
				goto _trap;
			break;
		case CLIP_PUSH_CODE:
			s = GET_SHORT(pp);
			c = GET_BYTE(pp);
			c1 = GET_BYTE(pp);

			vp = NEW(ClipVar);
			vp->t.type = PCODE_t;
			vp->t.flags = F_NONE;
			vp->t.count = 1;
			vp->c.u.block = NEW(ClipBlock);

			get_func(modbeg, s, &(vp->c.u.block->func));
			vp->c.u.block->file = file;

			if (c)
			{
				int nlocals = c;
				ClipVarFrame *localvars = calloc(1, sizeof(ClipVarFrame) + nlocals * sizeof(ClipVar));

				localvars->vars = (ClipVar *) (localvars + 1);
				memcpy(localvars->vars, mp->fp->sp - nlocals, nlocals * sizeof(ClipVar));
				localvars->refcount = 1;
				localvars->size = nlocals;
				vp->c.uplocals = localvars;
				mp->fp->sp -= nlocals;
			}
			else if (!c1 && reflocals && reflocals->refcount)
			{
				reflocals->refcount++;
				vp->c.uplocals = reflocals;
			}
			else
				vp->c.uplocals = 0;

			file->refCount++;

			CLEAR_CLIPVAR(frame.sp);
			frame.sp->t.type = PCODE_t;
			frame.sp->t.flags = F_MPTR;
			frame.sp->p.vp = vp;

			frame.sp++;
			CLIP_CHECK_STACK;

			break;
		case CLIP_MACRO:
			if ((ret = _clip_macro(mp)))
				goto _trap;
			break;
		case CLIP_PCOUNT:
			_clip_pcount(mp);
			break;
		case CLIP_PSHIFT:
			_clip_pshift(mp);
			break;
		case CLIP_PARN:
			if ((ret = _clip_parn(mp)))
				goto _trap;
			break;
		case CLIP_FUNC_NAME:
			c = GET_BYTE(pp);
			if ((ret = _clip_func_name(mp, c)))
				goto _trap;
			break;
		case CLIP_INCR:
			vp = frame.sp->p.vp;
			if ((ret = _clip_incr(mp, vp, 1, 0)))
				goto _trap;
			break;
		case CLIP_INCR_POST:
			vp = frame.sp->p.vp;
			if ((ret = _clip_incr(mp, vp, 1, 1)))
				goto _trap;
			break;
		case CLIP_DECR:
			vp = frame.sp->p.vp;
			if ((ret = _clip_incr(mp, vp, 0, 0)))
				goto _trap;
			break;
		case CLIP_DECR_POST:
			vp = frame.sp->p.vp;
			if ((ret = _clip_incr(mp, vp, 0, 1)))
				goto _trap;
			break;
		case CLIP_OP:
			c = GET_BYTE(pp);
			if ((ret = _clip_op(mp, c)))
				goto _trap;
			break;
		case CLIP_NOT:
			if ((ret = _clip_not(mp)))
				goto _trap;
			break;
		case CLIP_COND:
			s = GET_SHORT(pp);
			if ((ret = _clip_cond(mp, &i)))
				goto _trap;
			if (!i)
				pp += s;
			break;
		case CLIP_TCOND:
			s = GET_SHORT(pp);
			if ((ret = _clip_tcond(mp, &i)))
				goto _trap;
			if (!i)
				pp += s;
			break;
		case CLIP_ITCOND:
			s = GET_SHORT(pp);
			if ((ret = _clip_tcond(mp, &i)))
				goto _trap;
			if (i)
				pp += s;
			break;
		case CLIP_GOTO:
			s = GET_SHORT(pp);
			pp += s;
			break;
		case CLIP_FORSTEP:
			s = GET_SHORT(pp);
			if ((ret = _clip_forstep(mp, &i)))
				goto _trap;
			if (!i)
				pp += s;
			break;
		case CLIP_MAP_FIRST:
			c = GET_BYTE(pp);
			s = GET_SHORT(pp);
			if ((ret = _clip_map_first(mp, c, &i)))
				goto _trap;
			if (!i)
				pp += s;
			break;
		case CLIP_MAP_NEXT:
			c = GET_BYTE(pp);
			s = GET_SHORT(pp);
			if ((ret = _clip_map_next(mp, c, &i)))
				goto _trap;
			if (!i)
				pp += s;
			break;
		case CLIP_MINUS:
			if ((ret = _clip_minus(mp)))
				goto _trap;
			break;
		case CLIP_RESETTRAP:
			trap_pp = 0;
			break;
		case CLIP_SETTRAP:
			s = GET_SHORT(pp);
			trap_pp = pp + s;
			break;
		case CLIP_RECOVER:
			while (frame.sp > frame.stack)
				_clip_destroy(mp, --frame.sp);
			ret = 0;
			break;
		case CLIP_USING:
			if (mp->trapVar)
			{
				vp = frame.sp->p.vp;
				*frame.sp = *mp->trapVar;
				++frame.sp;
				free(mp->trapVar);
				mp->trapVar = 0;
				if ((ret = _clip_assign(mp, vp)))
					goto _trap;
			}
			break;
		case CLIP_BREAK:
#if 0
			/*_clip_trap_str(mp, filename, frame.line, "BREAK");*/
#else
			vp = NEW(ClipVar);
			_clip_trap_var(mp, filename, frame.line, vp);
#endif
			ret = -1;
			goto _trap;
		case CLIP_BREAK_EXPR:
			vp = NEW(ClipVar);
			--frame.sp;
			*vp = *frame.sp;
			_clip_trap_var(mp, filename, frame.line, vp);
			ret = -1;
			goto _trap;
		case CLIP_SWAP:
			c = GET_BYTE(pp);
			_clip_swap(mp, c);
			break;
		case CLIP_PUSH_HASH:
			l = GET_LONG(pp);
			frame.sp->t.memo = 0;
			frame.sp->t.type = NUMERIC_t;
			frame.sp->t.flags = F_NONE;
			frame.sp->t.len = 10;
			frame.sp->t.dec = 0;
			frame.sp->n.d = l;
			frame.sp++;
			CLIP_CHECK_STACK;
			break;
		case CLIP_CALC_HASH:
			_clip_calc_hash(mp);
			break;
		case CLIP_CALC_HASH2:
			_clip_calc_hash2(mp, 1);
			break;
		case CLIP_PUSH_LOCALE:
			_clip_push_locale(mp);
			break;
		case CLIP_RDDFIELD:
			s = GET_SHORT(pp);
			s1 = GET_SHORT(pp);
			_clip_rddfield(mp, s, s1);
			break;
		case CLIP_CATSTR:
			s = GET_SHORT(pp);
			_clip_catstr(mp, s);
			break;
		case CLIP_QUOT:
			_clip_quot(mp);
			break;
		case CLIP_SWITCH:
			s = GET_SHORT(pp);	/* label num */
			l = _clip_pop_shash(mp);	/* hash */
			{
				short other = GET_SHORT(pp);
				long *lp = (long *) pp;
				short *jmps = (short *) (pp + s * sizeof(long));
				int n = search_long(lp, s, l);

				if (n < 0)
					pp += other;
				else
					pp += GETSHORT(jmps+n);
			}
			break;
		default:
			_clip_trap_printf(mp, filename, frame.line, "invalid bytecode %d", code);
			_clip_call_errblock(mp, 1);
			ret = 1;
			goto _trap;
		}
	}
	goto _return;
      _trap:
	if (trap_pp /*&& ret > 0 */ )
	{
		pp = trap_pp;
		goto cont;
	}
	_clip_trap(mp, filename, frame.line);
	/*ret = 1; */
      _return:
	if (_clip_profiler)
		_clip_stop_profiler(mp);
	if (local_locals)
		_clip_destroy_locals(mp);
	_clip_resume(mp, nlocals, nreflocals);
#if 0
	_clip_vresume(mp, nlocals, locals);
#endif
#if 0
	_clip_vresume(mp, nparams, params);
#endif
#if 0
	if (nreflocals)
		_clip_vresume(mp, nreflocals, reflocals);
#endif
/*_clip_vremove_privates(mp, nprivates, privates);*/

	dealloca(stack);
	return ret;
}