Beispiel #1
0
unsigned char	__fastcall	MemGet (unsigned int Addr)
{
	static int buf;
	if (PCMCycles)
	{
		int _PCMCycles = PCMCycles;
		PCMCycles = 0;
		if ((Addr == 0x4016) || (Addr == 0x4017))
		{
			// Consecutive controller port reads from this are treated as one
			if (_PCMCycles--)
				MemGet(Addr);
			while (--_PCMCycles)
				RunCycle();
		}
		else
		{
			// but other addresses see multiple reads as expected
			while (--_PCMCycles)
				MemGet(Addr);
		}
		APU::DPCM::Fetch();
	}

	RunCycle();

	if (ReadHandler[(Addr >> 12) & 0xF] == ReadPRG)
	{
		if (Readable[(Addr >> 12) & 0xF])
			buf = PRGPointer[(Addr >> 12) & 0xF][Addr & 0xFFF];
		else	buf = -1;
		if (buf != -1)
			LastRead = (unsigned char)buf;
		return LastRead;
	}
Beispiel #2
0
void * MEM_Get(t_Handle h_Mem)
{
    t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem;
    uint8_t         *p_Block;
    uint32_t        intFlags;
#ifdef DEBUG_MEM_LEAKS
    uintptr_t       callerAddr = 0;

    GET_CALLER_ADDR;
#endif /* DEBUG_MEM_LEAKS */

    ASSERT_COND(h_Mem);

    intFlags = XX_LockIntrSpinlock(p_Mem->h_Spinlock);
    /* check if there is an available block */
    if ((p_Block = (uint8_t *)MemGet(p_Mem)) == NULL)
    {
        XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags);
        return NULL;
    }

#ifdef DEBUG_MEM_LEAKS
    DebugMemGet(p_Mem, p_Block, callerAddr);
#endif /* DEBUG_MEM_LEAKS */
    XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags);

    return (void *)p_Block;
}
Beispiel #3
0
static AppMsgInfo * GetAppMsgInfo (void)

{
	AppMsgInfo *info = (AppMsgInfo*) GetAppProperty(_szPropKey);
	
	if (info == NULL)
	{
		info = (AppMsgInfo*) MemGet(sizeof(struct AppMsgInfo), TRUE);
		if (info == NULL)  AbnormalExit(1);  
			
		info->hookMessage = _DefMessageHook;
		info->hookBeep = _DefBeepHook;
		info->hookMonitor = _DefMonitorHook;
		
		SetAppProperty(_szPropKey,(void*)info);
	}
	return info;
}
Beispiel #4
0
uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[])
{
    t_MemorySegment     *p_Mem = (t_MemorySegment *)h_Mem;
    uint32_t            availableBlocks;
    register uint32_t   i;
    uint32_t            intFlags;
#ifdef DEBUG_MEM_LEAKS
    uintptr_t           callerAddr = 0;

    GET_CALLER_ADDR;
#endif /* DEBUG_MEM_LEAKS */

    ASSERT_COND(h_Mem);

    intFlags = XX_LockIntrSpinlock(p_Mem->h_Spinlock);
    /* check how many blocks are available */
    availableBlocks = (uint32_t)(p_Mem->num - p_Mem->current);
    if (num > availableBlocks)
    {
        num = availableBlocks;
    }

    for (i=0; i < num; i++)
    {
        /* get pointer to block */
        if ((array[i] = MemGet(p_Mem)) == NULL)
        {
            break;
        }

#ifdef DEBUG_MEM_LEAKS
        DebugMemGet(p_Mem, array[i], callerAddr);
#endif /* DEBUG_MEM_LEAKS */
    }
    XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags);

    return (uint16_t)i;
}
Beispiel #5
0
NLM_EXTERN Boolean
LocalBandToEditBlock(LocalBandStructPtr lbsp)
{
  GapXEditBlockPtr edit_block;
  FloatHi score;
  Int4Ptr S;		/* conversion operations */
  Uint1Ptr seq1, seq2;

  if (lbsp == NULL)
	return FALSE;

  S = (Int4Ptr)MemGet((lbsp->seq1_length + lbsp->seq2_length) * sizeof(Int4), MGET_ERRPOST);
	score = BAND_LOCAL_ALIGN(lbsp->seq1-1, lbsp->seq2-1, lbsp->seq1_length, lbsp->seq2_length, lbsp->matrix, lbsp->options, S, &(lbsp->seq1_start), &(lbsp->seq2_start), &(lbsp->seq1_end), &(lbsp->seq2_end), lbsp->search_type);

/* Compensate for one-offset. */
	lbsp->seq1_start--;
	lbsp->seq2_start--;
	lbsp->seq1_end--;
	lbsp->seq2_end--;

  seq1 = lbsp->seq1;
  seq2 = lbsp->seq2;

  seq1 += lbsp->seq1_start;
  seq2 += lbsp->seq2_start;

  if (score > 0)
  	edit_block = TracebackToGapXEditBlock(seq1-1, seq2-1, (lbsp->seq1_length-lbsp->seq1_start), (lbsp->seq2_length-lbsp->seq2_start), S, lbsp->seq1_start, lbsp->seq2_start);

  S = MemFree(S);

  lbsp->edit_block = edit_block;
  lbsp->score = (Int4)score;

  return TRUE;
}
Beispiel #6
0
Int4
BAND_LOCAL_ALIGN(Uint1Ptr A, Uint1Ptr B,
		 Int4 M, Int4 N,
		 Int4Ptr PNTR matrix, PSUGapOptionsPtr options,
		 Int4Ptr S,
		 Int4Ptr psi, Int4Ptr psj,
		 Int4Ptr pei, Int4Ptr pej,
		 Int4 align_type)
{ 
  Int4 band;
  Boolean flag;
  register Int4 i, j, si, ei, ib;
  register Int4 c, d, e, t, m;
  Int4 leftd, rightd, G, H, low, up;
  Int4 best_score, score1;
  Int4 starti = 1, startj = 1, endi = M - 1, endj = N - 1;
  register Int4Ptr wa;
  register Int4 curd;
  register dp_ptr dp;
  Int4 Slen;
  data_t data;
  Int4Ptr PNTR W;

  G = options->gopen;
  H = options->gext;
  m = G + H;
  low = MAX(-M, options->low);
  up = MIN(N, options->up);
  W = matrix;

  if (N <= 0) { 
    *psi = *psj = *pei = *pej;
    return -1;
  }
  if (M <= 0) {
    *psi = *psj = *pei = *pej;
    return -1;
  }
  band = up - low + 1;
  if (band < 1) {
    ErrPostEx(SEV_WARNING, 0, 0, "low > up is unacceptable");
    return -1;
  }
  j = (band+2) * sizeof(dp_node);
  data.CD = (dp_ptr) MemGet(j, MGET_ERRPOST);

  if (low > 0) leftd = 1;
  else if (up < 0) leftd = band;
  else leftd = 1-low;
  rightd = band;
  si = MAX(0, -up);
  ei = MIN(M, N - low);
  data.CD[leftd].CC = 0;
  for (j = leftd+1; j <= rightd; j++) {
    data.CD[j].CC = 0;
    data.CD[j].DD = -m;
  }
  data.CD[rightd+1].CC = MININT;
  data.CD[rightd].DD = MININT;
  best_score = 0;
  endi = si;
  endj = si + low;
  data.CD[leftd-1].CC = MININT;
  data.CD[leftd].DD = -m; c = 0;
  for (i = si+1; i <= ei; i++) {
    score1 = best_score;
    if (i > N-up) rightd--;
    if (leftd > 1) leftd--;
    wa = W[A[i]];
    d = data.CD[leftd].DD;
    if ((ib = leftd + low - 1 + i) > 0) c = data.CD[leftd].CC+wa[B[ib]];
    if (c < 0) c = 0;
    else if (c > best_score) {
      best_score = c;
      endi = i;
      endj = ib;
    }
    e = c-m;
    data.CD[leftd].CC = c;
    for (curd=leftd+1, dp = &data.CD[curd], curd += i+low-1; 
	 curd <= rightd+i+low-1; curd++) {
      c = dp->CC + wa[B[curd]];
      if ((d=dp->DD) > c) c = d;		
      if (e > c) {
	if (e > 0) {
	  dp->CC = e; e-=H;
	  *(((Int4Ptr) (dp++))-1) = d-H;
	} else {
	  dp->CC = *(((Int4Ptr) (dp))-1) = 0;
          dp++;
	}
      } else {
	if (c <= 0) {
	  dp->CC = *(((Int4Ptr) (dp))-1) = 0;
          dp++;
	} else {
	  if (c > best_score) {
	    best_score = c;
	    endj = curd;
	  }
	  dp->CC = c;
	  if ((c -= m) > (e -= H)) e= c; 
	  if (c > (d-=H))  
	    *((Int4Ptr) (dp++)-1) = c;
	  else *((Int4Ptr) (dp++)-1) = d;
	}
      }
    }
    if (score1 < best_score) endi = i;
  }
  leftd = MAX(1, -endi - low + 1);
  rightd = band - (up - (endj - endi));
  data.CD[rightd].CC = 0; data.CD[rightd + 1].DD = -m;
  t = -G;
  for (j = rightd - 1; j >= leftd; j--) {
    data.CD[j].CC = t = t - H;
    data.CD[j + 1].DD = t - m;
  }
  for (j = rightd + 1; j <= band; ++j) data.CD[j].CC = MININT;
  data.CD[leftd - 1].CC = data.CD[leftd].DD = MININT;
  flag = FALSE; 
  for (i = endi; i >= 1; i--) {
    if (i + low <= 0) leftd++;
    if (rightd < band) rightd++;
    wa = W[A[i]];
    d = data.CD[rightd].DD;
    if ((ib = rightd + low - 1 + i) <= N) c = data.CD[rightd].CC + wa[B[ib]];
    else c = MININT;
    if (d > c) c = d;
    e = c - m;
    data.CD[rightd].CC = c;
    if ((d -= H) < e) data.CD[rightd + 1].DD = e;
    else data.CD[rightd + 1].DD = d;
    if (c == best_score) {
      starti = i;
      startj = ib;
      flag = TRUE;
      break;
    }
    for (curd = rightd - 1, dp = &data.CD[curd]; curd >= leftd; curd--) {
      c = dp->CC + wa[B[curd + low + i - 1]];
      if ((d = dp->DD) > c) c = d;
      if (e >= c) {
	dp->CC = e; e -= H;
	(dp-- + 1)->DD = d - H;
	continue;
      } 
      dp->CC = c;
      if (c == best_score) {
	starti = i;
	startj = curd + low + i - 1;
	flag = TRUE;
	break;
      }
      if ((c -= m) > (e -= H)) e = c;
      if (c < (d -= H)) (dp-- + 1)->DD = d; else (dp-- + 1)->DD = c;
    }
    if (flag == TRUE) 
      break;
  }
  MemFree(data.CD);
  if (starti < 0 || starti > M || startj < 0 || startj > N) 
    {
      ErrPostEx(SEV_WARNING, 0, 0, "starti=%d, startj=%d\n", starti, startj);
      *psi = *psj = *pei = *pej;
      return -1;
    }
  *psi = starti;
  *psj = startj;
  *pei = endi;
  *pej = endj;

  options->start_diag = low - (startj - starti);
  options->width = up - (startj - starti) - low + 1;

  switch(align_type) {
      /* XXX Float Score is converted to Int4 --> Round-off Errors */
  case L_BAND_LINEAR:
    return (Int4) (gband_linear(A + starti - 1, B + startj - 1,
			endi - starti + 1, endj - startj + 1,
			matrix, options, S, &Slen) / BND_DIGIT);
  case L_BAND_QUADRATIC:
    return (Int4) ( gband_quadratic(A + starti - 1, B + startj - 1,
			   endi - starti + 1, endj - startj + 1,
			   matrix, options, S, &Slen) / BND_DIGIT); 
  case L_BAND_LGAP:
    return (Int4) ( gband_linear_gap(A + starti - 1, B + startj - 1,
			    endi - starti + 1, endj - startj + 1,
			    matrix, options, S, &Slen) / BND_DIGIT); 
  case L_BAND_QGAP:
    return (Int4) ( gband_linear_qgap(A + starti - 1, B + startj - 1,
			     endi - starti + 1, endj - startj + 1,
			     matrix, options, S, &Slen) / BND_DIGIT); 
  case L_BAND_L3GAP:
    return (Int4) ( gband_l3gap(A + starti - 1, B + startj - 1,
		       endi - starti + 1, endj - startj + 1,
		       matrix, options, S, &Slen) / BND_DIGIT); 
  case L_BAND_Q3GAP:
    return (Int4) ( gband_q3gap(A + starti - 1, B + startj - 1,
		       endi - starti + 1, endj - startj + 1,
		       matrix, options, S, &Slen) / BND_DIGIT); 
  default:
    ErrPostEx(SEV_ERROR, 0, 0, "Unknown method.");
    return -1;
  }

}
Beispiel #7
0
NLM_EXTERN Boolean
GlobalBandToEditBlock(GlobalBandStructPtr gbsp)
{
  GapXEditBlockPtr edit_block;
  FloatHi score;
  Int4 Slen;
  Int4Ptr S;		/* conversion operations */

  if (gbsp == NULL)
	return FALSE;

  S = MemGet((gbsp->seq1_length+gbsp->seq2_length)*sizeof(Int4), MGET_ERRPOST);

  switch(gbsp->search_type)
  {

  case G_BAND_LINEAR:
    score = (FloatHi) gband_linear(gbsp->seq1-1, gbsp->seq2-1,
			     gbsp->seq1_length, gbsp->seq2_length,
			     gbsp->matrix, gbsp->options, S, &Slen)/BND_DIGIT; 
    break;
  case G_BAND_QUADRATIC:
    score = (FloatHi) gband_quadratic(gbsp->seq1-1, gbsp->seq2-1,
                             gbsp->seq1_length, gbsp->seq2_length,
                             gbsp->matrix, gbsp->options, S, &Slen)/BND_DIGIT;
    break;
  case G_BAND_LGAP:
    score = (FloatHi) gband_linear_gap(gbsp->seq1-1, gbsp->seq2-1,
                             gbsp->seq1_length, gbsp->seq2_length,
                             gbsp->matrix, gbsp->options, S, &Slen)/BND_DIGIT;
    break;
  case G_BAND_QGAP:
    score = (FloatHi) gband_linear_qgap(gbsp->seq1-1, gbsp->seq2-1,
                             gbsp->seq1_length, gbsp->seq2_length,
                             gbsp->matrix, gbsp->options, S, &Slen)/BND_DIGIT;
    break;
  case G_BAND_L3GAP:
    score = (FloatHi) gband_l3gap(gbsp->seq1-1, gbsp->seq2-1,
                             gbsp->seq1_length, gbsp->seq2_length,
                             gbsp->matrix, gbsp->options, S, &Slen)/BND_DIGIT;
    break;
  case G_BAND_Q3GAP:
    score = (FloatHi) gband_q3gap(gbsp->seq1-1, gbsp->seq2-1,
                             gbsp->seq1_length, gbsp->seq2_length,
                             gbsp->matrix, gbsp->options, S, &Slen)/BND_DIGIT;
    break;
  default:
    score = 0;
    ErrPostEx(SEV_ERROR, 0, 0, "Unknown method.");
    return FALSE;
  }
  if (score == 0) {
	return FALSE;
  }
  edit_block = TracebackToGapXEditBlock(gbsp->seq1-1, gbsp->seq2-1, gbsp->seq1_length, gbsp->seq2_length, S, 0, 0);

  S = MemFree(S);

  gbsp->edit_block = edit_block;
  gbsp->score = (Int4) score;
  gbsp->alignment_length = Slen;

  return TRUE;
}
Beispiel #8
0
static bool __qifainit(QIFA_SYS *qifasys, TCHAR *path) {
    static wchar __qifaname[20000];
    static QIFA __QiFa_Reg[160];
    for (int i = 0; i < lenthof(__QiFa_Reg); i++) {
        __QiFa_Reg[i].flag = 0;
    }
    MEM_ERR mem_err;
    if (!(qifasys->flag & 0x01)) {
        MemCreate(&qifamem, "qifa mem pool", __QiFa_Reg,
                  lenthof(__QiFa_Reg), sizeof(QIFA), &mem_err);
        ASSERT(mem_err == MEM_ERR_NONE);
        qifasys->flag |= 0x01;
    } else {
        for (int i = 0; i < lenthof(qifasys->QiFa_Reg); i++) {
            if (qifasys->QiFa_Reg[i] != NULL) {
                uint32 iboard = qifasys->QiFa_Reg[i]->board_id;
                uint32 iqf = qifasys->QiFa_Reg[i]->xuhao;
                qifasys->QiFa_Reg_Table[iboard][iqf] = NULL;
                memset(qifasys->QiFa_Reg[i], 0, sizeof(QIFA));
                MemPut(&qifamem, qifasys->QiFa_Reg[i], &mem_err);
                ASSERT(mem_err == MEM_ERR_NONE);
                qifasys->QiFa_Reg[i] = NULL;
            }
        }
    }

    FIL file;
    uint32 rb;
    //int nameoffset;
    MD5_CTX md5;
    MACHI_CFG_FILE_HEAD *filehead;
    QIFA_INFO *info;
    QF_PACKED *qifapack;
    unsigned char *p, *data = NULL;
    unsigned char md5hash[16];
    if (f_open(&file, path, FA_READ) != FR_OK) {
        return false;
    }
    unsigned int filesize = f_size(&file);
    data = (unsigned char *)malloc(filesize);
    if (data == NULL) {
        goto ERROR;
    }
    if (f_read(&file, data, filesize, &rb) != FR_OK || rb != filesize) {
        goto ERROR;
    }
    filehead = (MACHI_CFG_FILE_HEAD *)data;
    if (strcmp(filehead->cfghead, "swjcfg") != 0) goto ERROR;

    MD5Init(&md5);
    MD5Update(&md5, data + 24, filesize - 24);
    MD5Final(&md5, md5hash);
    if (memcmp(&md5hash, filehead->md5, 16) != 0) goto ERROR;

    p = data + filehead->sec[0].offset;

    info = (QIFA_INFO *)p;
    if (sizeof *qifapack != info->sizeofQifa) {
        goto ERROR;
    }
    qifasys->numofboard = info->numofQfBoard;
    qifasys->numperboard = info->numperQfBoard;
    qifasys->numofqifa = info->numofQifa;
    ASSERT(qifasys->numofboard <= lenthof(qifasys->QiFa_Reg_Table));
    ASSERT(qifasys->numperboard <= lenthof(qifasys->QiFa_Reg_Table[0]));

    p += info->qifanameOffset;
    memcpy(__qifaname, p, info->qifanamesize);
    p = data + filehead->sec[0].offset + info->qifaOffset;

    for (int i = 0; i < qifasys->numofqifa; i++) {
        qifapack = (QF_PACKED *)p;
        p += sizeof(QF_PACKED);
        if (qifapack->flag != QIFA_FLAG_EN && qifapack->flag != QIFA_FLAG_DIS) {
            goto ERROR;
        }
        if (qifapack->flag == QIFA_FLAG_DIS) {
            continue;
        }
        QIFA *qifa = MemGet(&qifamem, &mem_err);
        ASSERT(mem_err == MEM_ERR_NONE);
        uint16 qfid = qifapack->qfId;
        qifa->board_id = qifapack->board_id;
        qifa->xuhao = qifapack->xuhao;
        qifa->nc_no = qifapack->default_nc_no;
        qifa->default_nc_no = qifapack->default_nc_no;
        qifa->nc_no_changeable = qifapack->nc_no_changeable;
        qifa->nc_no_display = qifapack->nc_no_dis;
        qifa->cam_en = qifapack->iscam;
        qifa->flag = QIFA_FLAG;
        qifa->qfid = qfid;
        for (int j = 0; j < 13; j++) {
            if (qifapack->qifa_name_offset[j] != -1UL) {
                qifa->name[j] = &__qifaname[qifapack->qifa_name_offset[j] / 2];
            } else {
                qifa->name[j] = &__qifaname[qifapack->qifa_name_offset[0] / 2];
            }
        }
        char nicknamebuf[100];
        wtrToStr(nicknamebuf, qifa->name[0]);
        strtok(nicknamebuf, "[");
        char *p = strtok(nicknamebuf, "]");
        strcpy(qifa->nickname, p + 1);
        qifasys->QiFa_Reg[qfid] = qifa;
    }
    f_close(&file);
    if (data != NULL) {
        free(data);
    }
    return true;
    ERROR:
    f_close(&file);
    if (data != NULL) {
        free(data);
    }
    return false;
}
Beispiel #9
0
Int4 LIBCALL gband_linear_qgap(Uint1Ptr A, Uint1Ptr B,
			       Int4 M, Int4 N,
			       Int4Ptr PNTR matrix,
			       PSUGapOptionsPtr option,
			       Int4Ptr S, Int4Ptr Slen)
{ 
  data_t data;
  Int4 c, i, j;
  Int4 low, up;
  Int4 band;
  Int4 score;

  /* Setup global parameters */
  data.g = option->gopen;
  data.zzh = option->gext;
  data.w = matrix;
  data.m = data.g + data.zzh;

  data.sapp = S;
  data.last = 0;
  *Slen = 0;

  low = option->start_diag;
  band = option->width;
  up = band + low - 1;

  low = MIN(MAX(-M, low),MIN(N-M,0));
  up = MAX(MIN(N, up),MAX(N-M,0));

  if(up < 0 || low > 0) {
    ErrPostEx(SEV_WARNING, 0, 0,
	      "The band does not include (0,0) grid point");
    return 0;
  } 
  if(up+M < N || low+M > N) {
    ErrPostEx(SEV_WARNING, 0, 0,
	      "The band does not include lower corner");
    return 0;
  }
  
  if(N <= 0) { 
    if(M > 0) DEL_(M);
    return -gap_(M);
  }
  if(M <= 0) {
    INS_(N);
    return -gap_(N);
  }
  if((band = up - low + 1) <= 1) {
    c = 0;
    for(i = 1; i <= M; i++) {
      REP_;
      c += data.w[A[i]][B[i]];
    }
    return c;
  }

  j = (band+2) * sizeof(Int4);
  data.leggA = data.leggB = data.reggA = data.reggB = data.leghA =
    data.leghB = data.reghA = data.reghB = 0;

  data.CD = (dp_ptr)MemGet(sizeof(dp_node) * (band + 2), MGET_ERRPOST);

  /* if((c = g_band3_align(A,B,M,N,low,up,0,0)) != (score = g_band3_CHECK_SCORE(A,B,M,N,S))) */
  c = g_band3_align(A, B, M, N, low, up, &data);
  score = g_band3_CHECK_SCORE(A, B, M, N, S, &data);
  if(c != score) { 
    ErrPostEx(SEV_WARNING, 0, 0, "Check_Score = %ld align_score = %ld ", 
	      (long) score, (long) c);
	return 0;
  }
  MemFree(data.CD);

  *Slen = data.sapp - S;

  return c;
}
Beispiel #10
0
/* g_band3_align(A, B, M, N, up, low, tb, te, data) returns the cost
   of an optimum conversion between
   A[1..M] and B[1..N] and appends such a conversion to the current script.
   tb(te)= 1  no gap-open penalty if the conversion begins(ends) with a delete.
   tb(te)= 2  no gap-open penalty if the conversion begins(ends) with an insert.
*/
static Int4 g_band3_align(Uint1Ptr A, Uint1Ptr B,
			  Int4 M, Int4 N,
			  Int4 low, Int4 up, data_t *data)
{
  Int4 k, v;
  Int4 band, j;
  Int4 leftd, rightd;	/* for CC, DD, CP and DP */
  register Int4 curd;	/* current index for CC, DD CP and DP */
  register Int4 i;
  register Int4 c, d, e, x;
  register dp_ptr ap;
  Int4 t;
  Int4Ptr wa;
  Int1Ptr PNTR state, st, tmp;
  Int4 ib, best=MININT, X, Y;


  /* Boundary cases: M <= 0 , N <= 0, or up-low <= 0 */
  band = up - low + 1;
  state = (Int1Ptr PNTR) MemGet(sizeof(Int1Ptr)*(M+1), MGET_ERRPOST);
  state[0] = (Int1Ptr) MemGet((M+1)*(band+2), MGET_ERRPOST);
  for (i = 1; i <= M; i++) state[i] = state[i-1]+band+2;

  /* Initialization */
  leftd = 1-low;
  rightd = up-low+1;

  data->CD[leftd].CC = 0; state[0][leftd] = -1;

  t = -data->leggB;
  for(j = leftd + 1; j <= rightd; j++) {
    data->CD[j].CC = t = t - data->leghB;
    data->CD[j-1].DD = t - data->m;
    state[0][j] = 1;
  }
  data->CD[rightd+1].CC = MININT;
  data->CD[rightd].DD = MININT;
  data->CD[leftd-1].DD = -data->leggA;
  data->CD[leftd-1].CC = MININT;
  for (i = 1; i <= M; i++) {
    if (i > N-up) rightd--;
    if (leftd > 1) leftd--;
    wa = data->w[A[i]];
    d = data->CD[leftd].DD;
    k = 0;
    if ((ib = leftd+low-1+i) > 0) c = data->CD[leftd].CC+wa[B[ib]];
    if (d > c || ib <= 0) {
      c = d;
      k = 2;
    }
    e = c - data->m;
    if(ib <= 0) {
      data->CD[leftd - 1].DD = d - data->leghA;
      k += 20;
    }
    st = &state[i][leftd];
    *st++ = (Int1) k;
    data->CD[leftd].CC = c;
    for(curd = leftd + 1, ap = &data->CD[curd]; curd <= rightd; curd++) {
      c = ap->CC + wa[B[curd + low - 1 + i]];
      if((d = ap->DD) > c) {
	if(d > e) {
	  ap->CC = d;
	  *st++ =32;
	}
	else {
	  ap->CC = e;
	  *st++=31;
	}
	e -= data->zzh;
	(ap++ - 1)->DD = d - data->zzh;
      }
      else if (e > c) { 	       
	ap->CC = e;
	e -= data->zzh;
	(ap++ - 1)->DD = d - data->zzh;
	*st++ = 31;
      }
      else {
	ap->CC = c;
	if((c -= data->m) > (e -= data->zzh)) {
	  if(c > (d -= data->zzh)) {
	    (ap++ - 1)->DD = e = c;
	    *st++ = 0;
	  }
	  else {
	    e = c;
	    (ap++ - 1)->DD = d;
	    *st++ = 20;
	  } 
	}
	else {
	  if(c > (d -= data->zzh)) {
	    (ap++ - 1)->DD = c;
	    *st++ = 10;
	  }
	  else {
	    (ap++ - 1)->DD = d;
	    *st++ = 30;
	  }
	}
      }
    }
    if(i > N-up &&
       best < (j = (ap - 1)->CC - data->reggA - (N - i) * data->reghA)) {
      best = j; X = i; Y = rightd;
    }
  }
  for(ap = &data->CD[leftd]; ap <= &data->CD[rightd]; ap++) {
    if((j = ap->CC - data->reggB - data->reghB *
	(x = (&data->CD[rightd] - ap)))
       > best) {
      X = M;
      best = j;
      Y = rightd - x;
    }
  }
  if (data->CD[rightd].CC > best) {X=M; Y= N; best = data->CD[rightd].CC;}
  v= best;
  tmp = MemGet(M+N, MGET_ERRPOST);
  for (i = X, j = Y, e=0, c = 0; i>=0; i--, c++) {
    k  = (t=state[i][j]) %10;
    if (t == -1) break;
    if (e == 1 && (t/10)%2 == 1) k = 1;
    if (e == 2 && (t/20)== 1) k = 2;
    if (k == 1) { j--; i++;}
    else if (k == 2) j++;
    e = k;
    tmp[c] = (Int1) e;
  }
  for (i = c-1; i >= 0; i--) 
    switch(tmp[i]) {
    case 0: 
      _REP;
      break;
    case 1:
      _INS(1);
      break;
    case 2:
      _DEL(1);
      break;
    }
  if(X != M) _DEL(M - X)
	       else if(Y != rightd) _INS(rightd-Y)
  
				      MemFree(state[0]);
  MemFree(state);
  MemFree(tmp);
  return(v);
}