예제 #1
0
int DoTest(int N, TYPE *alpha0, int incX, int incY)
{
   int iret;
   const int npad=Mmax(4*Mabs(incY), 16);
   const TYPE padval=(-2271.0);
   TYPE *Yg, *Yt, *X, *x, *y;
   #ifdef TREAL
      TYPE alpha = *alpha0;
   #else
      TYPE *alpha = alpha0;
   #endif

   Yg = getvec(npad, padval, N, incY);
   Yt = dupvec(npad, N, Yg, incY);
   X  = getvec(0, padval, N, incX);  /* no padding for read-only X */

   x = X;
   y = Yg + (npad SHIFT);
   if (incX < 1) x -= ((N-1)SHIFT) * incX;
   if (incY < 1) y -= ((N-1)SHIFT) * incY;
   good_axpy(N, alpha, x, incX, y, incY);
   y = Yt + (npad SHIFT);
   if (incY < 1) y -= ((N-1)SHIFT) * incY;
   TEST_AXPY(N, alpha, x, incX, y, incY);
   iret = CheckY(npad, padval, N, Yg, incY, Yt, incY);
   free(X);
   free(Yg);
   free(Yt);
   return(iret);
}
예제 #2
0
파일: easytest.c 프로젝트: TheChetan/ECGCS
int  NextSample(int *vout,int nosig,int ifreq,
						int ofreq,int init)
	{
	int i ;
	static int m, n, mn, ot, it, vv[WFDB_MAXSIG], v[WFDB_MAXSIG], rval ;

	if(init)
		{
		i = gcd(ifreq, ofreq);
		m = ifreq/i;
		n = ofreq/i;
		mn = m*n;
		ot = it = 0 ;
		getvec(vv) ;
		rval = getvec(v) ;
		}

	else
		{
		while(ot > it)
			{
	    	for(i = 0; i < nosig; ++i)
	    		vv[i] = v[i] ;
			rval = getvec(v) ;
		    if (it > mn) { it -= mn; ot -= mn; }
		    it += n;
		    }		
	    for(i = 0; i < nosig; ++i)
	    	vout[i] = vv[i] + (ot%n)*(v[i]-vv[i])/n;
		ot += m;
		}

	return(rval) ;
	}
예제 #3
0
파일: wfdbf.c 프로젝트: cardionetics/wfdb
INTEGER getvec_(INTEGER *long_vector)
{
    if (sizeof(WFDB_Sample) == sizeof(INTEGER)) {
	return (getvec((WFDB_Sample *)long_vector));
    }
    else {
	WFDB_Sample v[WFDB_MAXSIG];
	int i, j;

	i = getvec(v);
	for (j = 0; j < i; j++)
	    long_vector[i] = v[i];
	return (i);
    }
}
예제 #4
0
int DoTest(int N, int incX)
{
   int iret=0;
   const TYPE padval=(-2271.0);
   TYPE *X, *x, eps, diff, maxdiff;
   TYPE ansG, ansT;
   TYPE Mjoin(PATL, epsilon)(void);
   eps = Mjoin(PATL,epsilon)();
   maxdiff = (2 SHIFT)*N*eps;

   x = X = getvec(0, padval, N, incX);
   if (incX < 0) x -= ((N-1)SHIFT) * incX;

   ansG = good_asum(N, x, incX);
   ansT = TEST_ASUM(N, x, incX);
   maxdiff *= 0.5 * ansG;
   diff = ansG - ansT;
   diff = Mabs(diff);
   if (diff > maxdiff)
   {
      fprintf(stderr,
              "   asum ERROR: N=%d, correct=%e, computed=%e, diff=%e!!\n",
              N, ansG, ansT, diff);
      iret = 1;
   }

   free(X);
   return(iret);
}
예제 #5
0
int DoTest(int N, TYPE *alpha0, int incY)
{
   int iret;
   const int npad=Mmax(4*Mabs(incY), 16);
   const TYPE padval=(-2271.0);
   TYPE *Yg, *Yt, *y;
   #ifdef TREAL
      TYPE alpha = *alpha0;
   #else
      TYPE *alpha = alpha0;
   #endif

   Yg = getvec(npad, padval, N, incY);
   Yt = dupvec(npad, N, Yg, incY);

   y = Yg + (npad SHIFT);
   if (incY < 1) y -= ((N-1)SHIFT) * incY;
   good_set(N, alpha, y, incY);
   y = Yt + (npad SHIFT);
   if (incY < 1) y -= ((N-1)SHIFT) * incY;
   TEST_SET(N, alpha, Yt+(npad SHIFT), incY);
   iret = CheckY(npad, padval, N, Yg, incY, Yt, incY);
   free(Yg);
   free(Yt);
   return(iret);
}
예제 #6
0
static TYPE *gen_dupvec(int N, TYPE padval, int npadX, TYPE *X, int incX,
                        int npadY, int incY)
{
   int i, n;
   TYPE *y, *yy, *xx=X+(npadX SHIFT);

   y = getvec(npadY, padval, N, incY);
   yy = y + (npadY SHIFT);
   if (incY < 1) yy -= ((N-1)SHIFT) * incY;
   if (incX < 1) xx -= ((N-1)SHIFT) * incX;
   copyvec(N, xx, incX, yy, incY);
   return(y);
}
예제 #7
0
int main(int argc, char **argv)
{
    int c;
    int inflag = 0;
    int dbg = 0;
    int sr_ds = 200;
    char * rec_name = "vfdb/427";
    char * db_path = "/opt/physiobank/database";
    size_t win_sec = 8;
    /* r stands for record with folder
     * p for path
     * i for information of record
     * s downsample sr
     * w window length default:8
     * d debug
     */
    while ((c = getopt(argc, argv, "idr:p:s:w:")) != -1)
        switch (c){
            case 'i':
                inflag = 1; 
                break;
            case 'r':
                rec_name = optarg;
                break;
            case 'p':
                db_path = optarg;
                break;
            case 's':
                sr_ds= atoi(optarg);
                break;
            case'w':
                win_sec = atoi(optarg);
                break;
            case'd':
                dbg = 1;
                break;
            default:
                abort();
        }            
    int i, j, nsig;
    WFDB_Sample *v;
    WFDB_Siginfo *s;
    WFDB_Anninfo a;
    setwfdb(db_path);
    
    nsig = isigopen(rec_name, NULL, 0);
    if (nsig < 1){
        printf("nsig:%d\n",nsig);
        exit(1);
    }
    s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo));
    if (isigopen(rec_name, s, nsig) != nsig)
        exit(1);
    v = (WFDB_Sample *)malloc(nsig * sizeof(WFDB_Sample));

    int orig_sr = sampfreq(rec_name);
    a.name = "atr"; a.stat = WFDB_READ;
    if (wfdbinit(rec_name, &a, 1, s, nsig) != nsig) exit(3);
    if(1 == inflag ){
        printf("sr:%d\n",orig_sr);
        printf("%d signals\n", nsig);
        for (i = 0; i < nsig; i++) {
            printf("Group %d, Signal %d:\n", s[i].group, i); 
            printf("File: %s\n", s[i].fname);
            printf("Description: %s\n", s[i].desc);
            printf("Gain: ");
            if (s[i].gain == 0.) 
                printf("uncalibrated; assume %g", WFDB_DEFGAIN);
            else printf("%g", s[i].gain);
            printf(" adu/%s\n", s[i].units ? s[i].units : "mV");
            printf(" Initial value: %d\n", s[i].initval);
            printf(" Storage format: %d\n", s[i].fmt);
            printf(" I/O: ");
            if (s[i].bsize == 0) printf("can be unbuffered\n");
            else printf("%d-byte blocks\n", s[i].bsize);
            printf(" ADC resolution: %d bits\n", s[i].adcres);
            printf(" ADC zero: %d\n", s[i].adczero);
            if (s[i].nsamp > 0L) {
                printf(" Length: %s (%ld sample intervals)\n",
                       timstr(s[i].nsamp), s[i].nsamp);
                printf(" Checksum: %d\n", s[i].cksum);
            }
            else printf(" Length undefined\n");
        }
    }

    fifo_t fifo_ecg;
    int fifo_ecg_buf[FIFO_SIZE];
    fifo_init(&fifo_ecg, fifo_ecg_buf, FIFO_SIZE);

    fifo_t fifo_bt;
    int fifo_bt_buf[FIFO_SIZE];
    fifo_init(&fifo_bt, fifo_bt_buf, FIFO_SIZE);

    int tmp = 0;
    int sr = 200;
    WFDB_Time begin_samp = 0;
    WFDB_Time end_samp = orig_sr*win_sec;
    WFDB_Annotation begin_ann;
    WFDB_Annotation end_ann;
    getann(0, &begin_ann);
    while(0 == getann(0, &end_ann))
         if ((end_ann.aux != NULL && *end_ann.aux > 0)
                    ||0 == strcmp(annstr(end_ann.anntyp), "[")
                    ||0 == strcmp(annstr(end_ann.anntyp), "]")
                    ||0 == strcmp(annstr(end_ann.anntyp), "~")
                ){
            break;
        }
    
    int * pBt_len = (int*)calloc(win_sec,sizeof(int));
    ResetBDAC();
    for (; ;) {
        if (getvec(v) < 0)
            break;
//        for (j = 0; j < nsig; j++){
//        }
        tmp = v[nsig-1];
        tmp = v[0];
        int vout1 = 0;
        static int bt_i = 0;
        static unsigned int samplecnt = 0;
        int idx = 0;
        if(down_sample(tmp, &vout1, orig_sr, sr)) {
                samplecnt ++;
                fifo_write(&fifo_ecg, &vout1, 1*sizeof(int));
                int beatType, beatMatch;
                long ltmp = vout1-s[0].adczero;
                ltmp *= 200; ltmp /= s[0].gain;
                int bdac_dly = BeatDetectAndClassify(ltmp, &beatType, &beatMatch);
                idx = bt_i/sr;
                if (0 != bdac_dly ) {
                    pBt_len[idx]++;
                    fifo_write(&fifo_bt, &beatType, sizeof(int));
                }
                bt_i = ++bt_i%(win_sec*sr);
        }

        double cm = 0.0;

        int size = win_sec*sr;
        if(fifo_len(&fifo_ecg)/sizeof(int) >= sr*win_sec){
            int * win_data = (int*)malloc(win_sec*sr*sizeof(int));
            int * ds_data = (int*)malloc(win_sec*sr_ds*sizeof(int));
            
            int len = fifo_len(&fifo_bt)/sizeof(int);
            int * p = (int*)calloc(len, sizeof(int));
           
            if (0 != len){
               //printf("bt_i:%d\n", bt_i);
                fifo_read_steps(&fifo_bt, p, len*sizeof(int), pBt_len[bt_i/sr]*sizeof(int));
                //for (i = 0;i< len;i++) printf("%d ", p[i]);
                //printf("\n");

            }
            pBt_len[bt_i/sr] = 0;
            
            fifo_read_steps(&fifo_ecg, win_data, size*sizeof(int), sr*sizeof(int));
            filtering(win_data, size, sr);
            int i = 0;
            int ds_size = 0;
            int vout;
            for(i = 0;i < size;i++){
               // if(down_sample(win_data[i], &vout, sr, sr_ds)) ds_data[ds_size++] = vout;
            }
            double dven = 0.0;

            if (0 != len){
                int tmp_cnt = 0;
                for(i = 0; i < len ; i++){
                    if(5 == p[i]) dven ++;
                }
                //printf("div:%d %d\n", tmp_cnt, len);
                dven /= len; 
            }
                         
            //cm = ecg_complexity_measure(win_data, size);
            //cm = ecg_complexity_measure(ds_data, ds_size);
            //cm = cpsd(ds_data, ds_size, 0.5*sr_ds);
            //cm = calc_grid(ds_data, ds_size, 0.5*sr_ds);
            cm = calc_grid(win_data, size, 0.5*sr);


        
            if (-1 == cm ) continue;
            //VT print 1;
            //VF print 2;
            
            int hr =  (int)((double)(len*60)/win_sec+0.5);
            int ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(VT");
            if (1 == ret){
                printf("%d %lf %lf %d\n", 1, cm, dven, hr);
            } else if (0 == ret) {
                ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(VFL");
                int ret2 = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "[");
                if (1 == ret || 1 == ret2){
                    printf("%d %lf %lf %d\n", 2, cm, dven, hr);
                } else if (0 == ret){
//                    ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(N");
//                    int ret3 = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "N");
//                    if ((1 == ret  || 1 == ret3) && -1 != begin_ann.subtyp) printf ("%d %lf %lf %d\n", 0, cm, dven, hr); 

                    if (1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(AFIB") 
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(AFL")
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(IVR")
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(SVTA")
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(SBR")
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(BII")
                       ) printf ("%d %lf %lf %d\n", 0, cm, dven, hr); 
                    
                   // int ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(SVTA");
                   // if (1 == ret)  printf ("%d %lf\n", 0, cm); 
                }
            }
            //iannsettime(begin_samp);
            begin_samp += orig_sr;
            end_samp += orig_sr;
            if(end_ann.time < begin_samp){
                begin_ann = end_ann;
                
                while(1)
                    if (0 != getann(0, &end_ann)){
                        end_ann = begin_ann;
                        /*the last sample of the signal*/
                        end_ann.time = s[nsig-1].nsamp;
                        break;
                    }else if ((end_ann.aux != NULL && *end_ann.aux > 0)
                                ||0 == strcmp(annstr(end_ann.anntyp), "[")
                                ||0 == strcmp(annstr(end_ann.anntyp), "]")
                                ||0 == strcmp(annstr(end_ann.anntyp), "~")
                            ){
                        break;
                    }
                if(dbg){
                    printf("begin tm:%s type:%s ", mstimstr(begin_ann.time), annstr(begin_ann.anntyp));
                    if(begin_ann.aux != NULL)
                        printf("begin aux:%s", begin_ann.aux+1);
                    printf("\n");
                    printf("end tm:%s type:%s ", mstimstr(end_ann.time), annstr(end_ann.anntyp));
                    if (end_ann.aux != NULL)
                        printf("end aux:%s", end_ann.aux+1);
                    printf("\n");

                    printf("begin sample:%s\n", mstimstr(begin_samp));
                    printf("ann diff:%s\n", mstimstr(end_ann.time-begin_ann.time));
                }
            }
            free(p);
            free(ds_data);
            free(win_data);
        }

    }
    free(pBt_len);
    wfdbquit();
    return 0;
}
예제 #8
0
파일: rc2.c 프로젝트: germolinal/Schedules
/* Recover output if possible */
void
recover_output()
{
	off_t		lastout = -1;
	int		outvsiz, recsiz;
	char		*outvfmt;
	int		i, j;
	MODCONT		*mp;
	int		ofl;
	char		oname[1024];
	LUENT		*oent;
	STREAMOUT	sout;
	off_t		nvals;
	int		xr, yr;

	switch (outfmt) {
	case 'a':
		error(USER, "cannot recover ASCII output");
		return;
	case 'f':
		outvsiz = sizeof(float)*3;
		break;
	case 'd':
		outvsiz = sizeof(double)*3;
		break;
	case 'c':
		outvsiz = sizeof(COLR);
		break;
	default:
		error(INTERNAL, "botched output format");
		return;
	}
	outvfmt = formstr(outfmt);
						/* check modifier outputs */
	for (i = 0; i < nmods; i++) {
		mp = (MODCONT *)lu_find(&modconttab,modname[i])->data;
		if (mp->outspec == NULL)
			error(USER, "cannot recover from stdout");
		if (mp->outspec[0] == '!')
			error(USER, "cannot recover from command");
		for (j = 0; ; j++) {		/* check each bin's file */
			ofl = ofname(oname, mp->outspec, mp->modname, j);
			if (ofl < 0)
				error(USER, "bad output file specification");
			oent = lu_find(&ofiletab, oname);
			if (oent->data != NULL) {
				sout = *(STREAMOUT *)oent->data;
			} else {
				sout.reclen = 0;
				sout.outpipe = 0;
				sout.ofp = NULL;
			}
			if (sout.ofp != NULL) {	/* already open? */
				if (ofl & OF_BIN)
					continue;
				break;
			}
						/* open output */
			sout.ofp = fopen(oname, "rb+");
			if (sout.ofp == NULL) {
				if (j == mp->nbins)
					break;	/* assume end of modifier */
				sprintf(errmsg, "missing recover file '%s'",
						oname);
				error(WARNING, errmsg);
				break;
			}
			nvals = lseek(fileno(sout.ofp), 0, SEEK_END);
			if (nvals <= 0) {
				lastout = 0;	/* empty output, quit here */
				fclose(sout.ofp);
				break;
			}
			if (!sout.reclen) {
				if (!(ofl & OF_BIN)) {
					sprintf(errmsg,
						"need -bn to recover file '%s'",
							oname);
					error(USER, errmsg);
				}
				recsiz = outvsiz;
			} else
				recsiz = outvsiz * sout.reclen;

			lseek(fileno(sout.ofp), 0, SEEK_SET);
			if (header && checkheader(sout.ofp, outvfmt, NULL) != 1) {
				sprintf(errmsg, "format mismatch for '%s'",
						oname);
				error(USER, errmsg);
			}
			sout.xr = xres; sout.yr = yres;
			if ((sout.xr > 0) & (sout.yr > 0) &&
					(!fscnresolu(&xr, &yr, sout.ofp) ||
						(xr != sout.xr) |
						(yr != sout.yr))) {
				sprintf(errmsg, "resolution mismatch for '%s'",
						oname);
				error(USER, errmsg);
			}
			nvals = (nvals - (off_t)ftell(sout.ofp)) / recsiz;
			if ((lastout < 0) | (nvals < lastout))
				lastout = nvals;
			if (oent->key == NULL)	/* new entry */
				oent->key = strcpy((char *)
						malloc(strlen(oname)+1), oname);
			if (oent->data == NULL)
				oent->data = (char *)malloc(sizeof(STREAMOUT));
			*(STREAMOUT *)oent->data = sout;
			if (!(ofl & OF_BIN))
				break;		/* no bin separation */
		}
		if (!lastout) {			/* empty output */
			error(WARNING, "no previous data to recover");
			lu_done(&ofiletab);	/* reclose all outputs */
			return;
		}
		if (j > mp->nbins) {		/* check modifier size */
			sprintf(errmsg,
				"mismatched -bn setting for recovering '%s'",
					modname[i]);
			error(USER, errmsg);
		}
	}
	if (lastout < 0) {
		error(WARNING, "no output files to recover");
		return;
	}
	if (raysleft && lastout >= raysleft/accumulate) {
		error(WARNING, "output appears to be complete");
		/* XXX should read & discard input? */
		quit(0);
	}
						/* seek on all files */
	nvals = lastout * outvsiz;
	lu_doall(&ofiletab, &myseeko, &nvals);
						/* skip repeated input */
	lastout *= accumulate;
	for (nvals = 0; nvals < lastout; nvals++) {
		FVECT	vdummy;
		if (getvec(vdummy) < 0 || getvec(vdummy) < 0)
			error(USER, "unexpected EOF on input");
	}
	lastray = lastdone = (RNUMBER)lastout;
	if (raysleft)
		raysleft -= lastray;
}
예제 #9
0
파일: dsk.c 프로젝트: TijmenW/FreeDOS
STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer,
                 ULONG LBA_address, unsigned totaltodo,
                 UWORD * transferred)
{
  static struct _bios_LBA_address_packet dap = {
    16, 0, 0, 0, 0, 0, 0
  };

  unsigned count;
  unsigned error_code = 0;
  struct CHS chs;
  void FAR *transfer_address;
  unsigned char driveno = pddt->ddt_driveno;

  int num_retries;

	UWORD bytes_sector = pddt->ddt_bpb.bpb_nbyte;   /* bytes per sector, usually 512 */
  *transferred = 0;
  
  /* only low-level format floppies for now ! */
  if (mode == LBA_FORMAT && hd(pddt->ddt_descflags))
    return 0;

  /* optionally change from A: to B: or back */
  play_dj(pddt);

  if (!hd(pddt->ddt_descflags))
  {
    UBYTE FAR  *int1e_ptr = (UBYTE FAR *)getvec(0x1e);
    unsigned char nsecs = (unsigned char)(pddt->ddt_bpb.bpb_nsecs);

    if (int1e_ptr[4] != nsecs)
    {
      int1e_ptr[4] = nsecs;
      fl_reset(driveno);
    }
  }
        
/*    
    if (LBA_address+totaltodo > pddt->total_sectors)
        {
        printf("LBA-Transfer error : address overflow = %lu > %lu max\n",LBA_address+totaltodo,driveParam->total_sectors);
        return 1;
        }
*/

  buffer = adjust_far(buffer);
  for (; totaltodo != 0;)
  {
    /* avoid overflowing 64K DMA boundary */
    count = DMA_max_transfer(buffer, totaltodo);

    if (FP_SEG(buffer) >= 0xa000 || count == 0)
    {
      transfer_address = DiskTransferBuffer;
      count = 1;

      if ((mode & 0xff00) == (LBA_WRITE & 0xff00))
      {
        fmemcpy(DiskTransferBuffer, buffer, bytes_sector);
      }
    }
    else
    {
      transfer_address = buffer;
    }

    for (num_retries = 0; num_retries < N_RETRY; num_retries++)
    {
      if ((pddt->ddt_descflags & DF_LBA) && mode != LBA_FORMAT)
      {
        dap.number_of_blocks = count;

        dap.buffer_address = transfer_address;

        dap.block_address_high = 0;     /* clear high part */
        dap.block_address = LBA_address;        /* clear high part */

        /* Load the registers and call the interrupt. */

        if ((pddt->ddt_descflags & DF_WRTVERIFY) || mode != LBA_WRITE_VERIFY)
        {
          error_code = fl_lba_ReadWrite(driveno, mode, &dap);
        }
        else
        {
          /* verify requested, but not supported */
          error_code =
              fl_lba_ReadWrite(driveno, LBA_WRITE, &dap);

          if (error_code == 0)
          {
            error_code =
                fl_lba_ReadWrite(driveno, LBA_VERIFY, &dap);
          }
        }
      }
      else
      {                         /* transfer data, using old bios functions */

        if (LBA_to_CHS(LBA_address, &chs, pddt))
          return 1;

        /* avoid overflow at end of track */

        if (chs.Sector + count > (unsigned)pddt->ddt_bpb.bpb_nsecs + 1)
        {
          count = pddt->ddt_bpb.bpb_nsecs + 1 - chs.Sector;
        }

        error_code = (mode == LBA_READ ? fl_read :
                      mode == LBA_VERIFY ? fl_verify :
                      mode ==
                      LBA_FORMAT ? fl_format : fl_write) (driveno,
                                                          chs.Head,
                                                          chs.Cylinder,
                                                          chs.Sector,
                                                          count,
                                                          transfer_address);

        if (error_code == 0 && mode == LBA_WRITE_VERIFY)
        {
          error_code = fl_verify(driveno, chs.Head, chs.Cylinder,
                                 chs.Sector, count, transfer_address);
        }
      }
      if (error_code == 0)
        break;

      fl_reset(driveno);

    }                           /* end of retries */

    if (error_code)
    {
      return error_code;
    }

    /* copy to user buffer if nesessary */
    if (transfer_address == DiskTransferBuffer &&
        (mode & 0xff00) == (LBA_READ & 0xff00))
    {
      fmemcpy(buffer, DiskTransferBuffer, bytes_sector);
    }

    *transferred += count;
    LBA_address += count;
    totaltodo -= count;

    buffer = adjust_far((char FAR *)buffer + count * bytes_sector);
  }

  return (error_code);
}
예제 #10
0
파일: task.c 프로젝트: TijmenW/FreeDOS
/* The following code is 8086 dependant                         */
VOID new_psp(psp FAR * p, int psize)
{
  REG COUNT i;
  psp FAR *q = MK_FP(cu_psp, 0);

  /* Clear out new psp first                              */
  fmemset(p, 0, sizeof(psp));

  /* initialize all entries and exits                     */
  /* CP/M-like exit point                                 */
  p->ps_exit = 0x20cd;

  /* CP/M-like entry point - jump to special entry        */
  p->ps_farcall = 0xea;
  p->ps_reentry = (VOID(FAR *) ())cpm_entry;
  /* unix style call - 0xcd 0x21 0xcb (int 21, retf)      */
  p->ps_unix[0] = 0xcd;
  p->ps_unix[1] = 0x21;
  p->ps_unix[2] = 0xcb;

  /* Now for parent-child relationships                   */
  /* parent psp segment                                   */
  p->ps_parent = cu_psp;
  /* previous psp pointer                                 */
  p->ps_prevpsp = q;

  /* Environment and memory useage parameters             */
  /* memory size in paragraphs                            */
  p->ps_size = psize;
  /* environment paragraph                                */
  p->ps_environ = 0;
  /* process dta                                          */
  p->ps_dta = (BYTE FAR *) (&p->ps_cmd_count);

  /* terminate address                                    */
  p->ps_isv22 = (VOID(INRPT FAR *) (void))getvec(0x22);
  /* break address                                        */
  p->ps_isv23 = (VOID(INRPT FAR *) (void))getvec(0x23);
  /* critical error address                               */
  p->ps_isv24 = (VOID(INRPT FAR *) (void))getvec(0x24);

  /* File System parameters                               */
  /* user stack pointer - int 21                          */
  p->ps_stack = q->ps_stack;
  /* file table - 0xff is unused                          */
  for (i = 0; i < 20; i++)
    p->ps_files[i] = 0xff;

  /* maximum open files                                   */
  p->ps_maxfiles = 20;
  /* open file table pointer                              */
  p->ps_filetab = p->ps_files;

  /* clone the file table                                 */
  if (p!=q)
  {
    REG COUNT i;

    for (i = 0; i < 20; i++)
    {
      if (q->ps_filetab[i] != 0xff && CloneHandle(i) >= 0)
        p->ps_filetab[i] = q->ps_filetab[i];
      else
        p->ps_filetab[i] = 0xff;
    }
  }

  /* first command line argument                          */
  p->ps_fcb1.fcb_drive = 0;
  /* second command line argument                         */
  p->ps_fcb2.fcb_drive = 0;

  /* local command line                                   */
  p->ps_cmd_count = 0;          /* command tail                 */
  p->ps_cmd[0] = 0;             /* command tail                 */
  if (RootPsp == (seg) ~ 0)
    RootPsp = FP_SEG(p);
}
/* ------------------------------------------------------------------------------------ */
Procedural* Particles_Create(char *TextureName, geWorld *World, const char *InputParams)
{
    Procedural *Proc;
    int i;
    char ParamWork[8192],*pstr;
    geBitmap	*ppBitmap;

	Proc = GE_RAM_ALLOCATE_STRUCT(Procedural);

	if(!Proc)
		return (Procedural*)NULL;

	memset(Proc, 0, sizeof(Procedural));

	ppBitmap = geWorld_GetBitmapByName(World, TextureName);

	/**** read Params *****/

// changed RF064 by QD
	if(!strcmp(InputParams, "Params_Oil"))
	{
		strcpy(ParamWork, Params_Oil);
	}
	else if(!strcmp(InputParams, "Params_Jet"))
	{
		strcpy(ParamWork,Params_Jet);
	}
	else if(!strcmp(InputParams, "Params_Steam"))
	{
		strcpy(ParamWork,Params_Steam);
	}
	else if(!strcmp(InputParams, "Params_Explosion") || strlen(InputParams) < 20 )
	{
		strcpy(ParamWork,DefaultParams);
	}
// end change RF064 by QD
	else
	{
		strcpy(ParamWork,InputParams);
	}

	pstr = strtok(ParamWork,strbreakers);

	Proc->NumParticles = getint(pstr);
	Proc->NumSources = getint(pstr);

	/**** make Bitmap *****/

	if(!Particles_InitBitmap(ppBitmap))
		goto fail;

	Proc->Bitmap = ppBitmap;

	Proc->SizeX  = geBitmap_Width(Proc->Bitmap);
	Proc->SizeY = geBitmap_Height(Proc->Bitmap);
	geBitmap_GetInfo(Proc->Bitmap, &(Proc->BmInfo), (geBitmap_Info*)NULL);
	Proc->SizeZ = min(Proc->SizeX, Proc->SizeY);

	/**** make Particles *****/

	Proc->Particles = (Particle*)geRam_AllocateClear(Proc->NumParticles * sizeof(Particle));

	if(!(Proc->Particles))
		goto fail;

	for(i=0; i<Proc->NumParticles; i++)
	{
		Proc->Particles[i].shade = -1;
	}

	Proc->NumActiveParticles = 0;

	/**** make Sources *****/

	Proc->Sources = (ParticleSource*)geRam_AllocateClear(Proc->NumSources * sizeof(ParticleSource));

	if(!(Proc->Sources))
		goto fail;

	/**** More Params *****/

	// <> for stock schemes, take a few colors as parameters

	if(matchstr(pstr, "oil"))
	{
		nextparam(pstr);
		Proc->NumColors = Proc->NumShades = 16;
		Proc->PixelRGBA = PixelRGBA_OilColor;
	}
	else if(matchstr(pstr, "fire"))
	{
		nextparam(pstr);
		Proc->NumColors = 1;
		Proc->NumShades = 256;
		Proc->PixelRGBA = PixelRGBA_FireColor;
	}
	else if(matchstr(pstr, "opaquefire"))
	{
		nextparam(pstr);
		Proc->NumColors = 1;
		Proc->NumShades = 256;
		Proc->PixelRGBA = PixelRGBA_OpaqueFireColor;
	}
	else if(matchstr(pstr, "steam"))
	{
		nextparam(pstr);
		Proc->NumColors = 1;
		Proc->NumShades = 256;
		Proc->PixelRGBA = PixelRGBA_SteamColor;
	}
	else
	{
		Proc->NumColors = getint(pstr);
		Proc->NumShades = getint(pstr);
		Proc->PixelRGBA = PixelRGBA_OilColor;
		// <>
		// way to read in general spline of colors ?
	}

	if((Proc->NumColors * Proc->NumShades) < 256)
	{
		Proc->NumColors = min(Proc->NumColors, 256);
		Proc->NumShades = 256 / Proc->NumColors;
	}

	Proc->NumSmoothes	= getint(pstr);
	Proc->SmoothRadius	= getint(pstr);

	if(matchstr(pstr, "bounce"))
	{
		Proc->Capper = Capper_Bounce;
		Proc->SmoothWrap = GE_FALSE;
	}
	else if(matchstr(pstr,"wrap"))
	{
		Proc->Capper = Capper_Wrap;
		Proc->SmoothWrap = GE_TRUE;
	}
	else if(matchstr(pstr,"hard"))
	{
		Proc->Capper = Capper_Hard;
		Proc->SmoothWrap = GE_FALSE;
	}
	else
	{
		goto fail;
	}

	nextparam(pstr);

	Proc->DoMagnetic = getbool(pstr);

	if(Proc->DoMagnetic)
	{
		getvec(pstr, &(Proc->MagneticField));
	}

	Proc->DoAttractor = getbool(pstr);

	if(Proc->DoAttractor)
	{
		Proc->AttractorStrength = getfloat(pstr); // negative for repulsive
		Proc->AttractorIsAxis = getbool(pstr);

		if(Proc->AttractorIsAxis)
		{
			getvec(pstr, &(Proc->AttractorAxis));
			geVec3d_Normalize(&(Proc->AttractorAxis));
		}

		getvec(pstr, &(Proc->AttractorPos));
		scalevec(&(Proc->AttractorPos));
	}

	/**** LUT's *****/

	if(!Particles_InitPalette(Proc))
		goto fail;

	for(i=0; i<Proc->NumSources; i++)
	{
		ParticleSource *pSource;
		Particle *pParticle;

		pSource = Proc->Sources + i;

		// base
		pParticle = &(pSource->Base);

		getvec(pstr, pParticle->p);
		getvec(pstr, pParticle->v);

		scalevec(pParticle->p);
		scalevec(pParticle->v);

		pParticle->DeathTime = getfloat(pstr);
		pParticle->color = getint(pstr);
		pParticle->shade = Proc->NumShades - 1;
		pParticle->CurDeathTime = 0.0f;

		// random
		pParticle = &(pSource->Random);

		getvec(pstr,pParticle->p);
		getvec(pstr,pParticle->v);

		scalevec(pParticle->p);
		scalevec(pParticle->v);

		absvec(pParticle->p);
		absvec(pParticle->v);

		pParticle->DeathTime = getfloat(pstr);
		pParticle->color = getint(pstr);
		pParticle->shade = getint(pstr);
		pParticle->CurDeathTime = 0.0f;

		pSource->RandomVMagnitude = geVec3d_Normalize((geVec3d*)(pParticle->v));

		pSource->Delay = getfloat(pstr); // seconds
		pSource->Base.Drag = getfloat(pstr);
		pSource->CurTime = pSource->Delay;
	}

	return Proc;

fail:

	Particles_Destroy(Proc);
	return (Procedural*)NULL;
}
예제 #12
0
파일: inthndlr.c 프로젝트: TijmenW/FreeDOS
VOID int21_service(iregs FAR * r)
{
  COUNT rc = 0,
	  rc1;
  psp FAR *p = MK_FP(cu_psp, 0);
  void FAR *FP_DS_DX = MK_FP(r->DS, r->DX); /* this is saved so often,
                                               that this saves ~100 bytes */

    
#define CLEAR_CARRY_FLAG()  r->FLAGS &= ~FLG_CARRY
#define SET_CARRY_FLAG()    r->FLAGS |= FLG_CARRY

  p->ps_stack = (BYTE FAR *) r;

#ifdef DEBUG 
  if (bDumpRegs)
  {
    fbcopy((VOID FAR *) user_r, (VOID FAR *) & error_regs, sizeof(iregs));
    printf("System call (21h): %02x\n", user_r->AX);
    dump_regs = TRUE;
    dump();
  }
#endif

  if(r->AH >=0x38 && r->AH <= 0x4F)
      CLEAR_CARRY_FLAG();
      /* Clear carry by default for these functions */

dispatch:

  /* Check for Ctrl-Break */
  switch (r->AH)
  {
    default:
      if (!break_ena)
        break;
    case 0x01:
    case 0x02:
    case 0x03:
    case 0x04:
    case 0x05:
    case 0x08:
    case 0x09:
    case 0x0a:
    case 0x0b:
      if (control_break())
        handle_break();
  }

  /* The dispatch handler                                         */
  switch (r->AH)
  {
      /* int 21h common error handler                                 */
    case 0x64:
    error_invalid:
      r->AX = -DE_INVLDFUNC;
      goto error_out;
    error_exit:
      r->AX = -rc;
    error_out:
      CritErrCode = r->AX;  /* Maybe set */
      SET_CARRY_FLAG();
      break;

       /* case 0x00:   --> Simulate a DOS-4C-00 */

      /* Read Keyboard with Echo                      */
    case 0x01:
      r->AL = _sti(TRUE);
      sto(r->AL);
      break;

      /* Display Character                                            */
    case 0x02:
      sto(r->DL);
      break;

      /* Auxiliary Input                                                      */
    case 0x03:
     {
      COUNT scratch;
      GenericRead(STDAUX, 1, (BYTE FAR *) & r->AL, (COUNT FAR *) & scratch, TRUE);
      break;
     }

      /* Auxiliary Output                                                     */
    case 0x04:
     {
      COUNT scratch;
      DosWrite(STDAUX, 1, (BYTE FAR *) & r->DL, (COUNT FAR *) &scratch);
      break;
     }
      /* Print Character                                                      */
    case 0x05:
     {       
      COUNT scratch;       
      DosWrite(STDPRN, 1, (BYTE FAR *) & r->DL, (COUNT FAR *) &scratch);
      break;      
     }

      /* Direct Console I/O                                            */
    case 0x06:
      if (r->DL != 0xff)
        sto(r->DL);
      else if (StdinBusy())
      {
        r->AL = 0x00;
        r->FLAGS |= FLG_ZERO;
      }
      else
      {
        r->FLAGS &= ~FLG_ZERO;
        r->AL = _sti(FALSE);
      }
      break;

      /* Direct Console Input                                         */
    case 0x07:
      r->AL = _sti(FALSE);
      break;

      /* Read Keyboard Without Echo                                   */
    case 0x08:
      r->AL = _sti(TRUE);
      break;

      /* Display String                                               */
    case 0x09:
      {
        BYTE FAR * q;
        q = FP_DS_DX;
        while (*q != '$')
          ++q;
        DosWrite(STDOUT, FP_OFF(q) - FP_OFF(FP_DS_DX), FP_DS_DX, (COUNT FAR *) & UnusedRetVal);
      }
      r->AL = '$';
      break;

      /* Buffered Keyboard Input                                      */
    case 0x0a:
      sti_0a((keyboard FAR *) FP_DS_DX);
      break;

      /* Check Stdin Status                                           */
    case 0x0b:
      if (StdinBusy())
        r->AL = 0x00;
      else
        r->AL = 0xFF;
      break;

      /* Flush Buffer, Read Keayboard                                 */
    case 0x0c:
      KbdFlush();
      switch (r->AL)
      {
        case 0x01:
        case 0x06:
        case 0x07:
        case 0x08:
        case 0x0a:
          r->AH = r->AL;
          goto dispatch;

        default:
          r->AL = 0x00;
          break;
      }
      break;

      /* Reset Drive                                                  */
    case 0x0d:
      flush();
      break;

      /* Set Default Drive                                            */
    case 0x0e:
      r->AL = DosSelectDrv(r->DL);
      break;

    case 0x0f:
      if (FcbOpen(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x10:
      if (FcbClose(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x11:
      if (FcbFindFirst(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x12:
      if (FcbFindNext(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x13:
      if (FcbDelete(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x14:
      {
        if (FcbRead(FP_DS_DX, &CritErrCode))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

    case 0x15:
      {
        if (FcbWrite(FP_DS_DX, &CritErrCode))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

    case 0x16:
      if (FcbCreate(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x17:
      if (FcbRename(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    default:
#ifdef DEBUG
       printf("Unsupported INT21 AH = 0x%x, AL = 0x%x.\n", r->AH, r->AL);
#endif
      /* Fall through. */

    /* CP/M compatibility functions                                 */
    case 0x18:
    case 0x1d:
    case 0x1e:
    case 0x20:
#ifndef TSC
    case 0x61:
#endif
    case 0x6b:
      r->AL = 0;
      break;

      /* Get Default Drive                                            */
    case 0x19:
      r->AL = default_drive;
      break;

      /* Set DTA                                                      */
    case 0x1a:
      {
        psp FAR *p = MK_FP(cu_psp, 0);

        p->ps_dta = FP_DS_DX;
        dos_setdta(p->ps_dta);
      }
      break;

      /* Get Default Drive Data                                       */
    case 0x1b:
      {
        BYTE FAR *p;

        FatGetDrvData(0,
                      (COUNT FAR *) & r->AX,
                      (COUNT FAR *) & r->CX,
                      (COUNT FAR *) & r->DX,
                      (BYTE FAR **) & p);
        r->DS = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get Drive Data                                               */
    case 0x1c:
      {
        BYTE FAR *p;

        FatGetDrvData(r->DL,
                      (COUNT FAR *) & r->AX,
                      (COUNT FAR *) & r->CX,
                      (COUNT FAR *) & r->DX,
                      (BYTE FAR **) & p);
        r->DS = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get default DPB                                              */
      /* case 0x1f: see case 0x32 */

      /* Random read using FCB */
    case 0x21:
      {
        if (FcbRandomIO(FP_DS_DX, &CritErrCode, FcbRead))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

      /* Random write using FCB */
    case 0x22:
      {
        if (FcbRandomIO(FP_DS_DX, &CritErrCode, FcbWrite))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

      /* Get file size in records using FCB */
    case 0x23:
      if (FcbGetFileSize(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

      /* Set random record field in FCB */
    case 0x24:
      FcbSetRandom(FP_DS_DX);
      break;

      /* Set Interrupt Vector                                         */
    case 0x25:
      {
        VOID(INRPT FAR * p) () = FP_DS_DX;

        setvec(r->AL, p);
      }
      break;

      /* Dos Create New Psp                                           */
    case 0x26:
      {
        psp FAR *p = MK_FP(cu_psp, 0);

        new_psp((psp FAR *) MK_FP(r->DX, 0), p->ps_size);
      }
      break;

      /* Read random record(s) using FCB */
    case 0x27:
      {
        if (FcbRandomBlockRead(FP_DS_DX, r->CX, &CritErrCode))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

      /* Write random record(s) using FCB */
    case 0x28:
      {
        if (FcbRandomBlockWrite(FP_DS_DX, r->CX, &CritErrCode))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

      /* Parse File Name                                              */
    case 0x29:
      {
        BYTE FAR *lpFileName;

        lpFileName = MK_FP(r->DS, r->SI);
        r->AL = FcbParseFname(r->AL,
                              &lpFileName,
                              MK_FP(r->ES, r->DI));
        r->DS = FP_SEG(lpFileName);
        r->SI = FP_OFF(lpFileName);
      }
      break;

      /* Get Date                                                     */
    case 0x2a:
      DosGetDate(
                  (BYTE FAR *) & (r->AL),	/* WeekDay              */
                  (BYTE FAR *) & (r->DH),	/* Month                */
                  (BYTE FAR *) & (r->DL),	/* MonthDay             */
                  (COUNT FAR *) & (r->CX));	/* Year                 */
      break;

      /* Set Date                                                     */
    case 0x2b:
      rc = DosSetDate(
                       (BYTE FAR *) & (r->DH),	/* Month                */
                       (BYTE FAR *) & (r->DL),	/* MonthDay             */
                       (COUNT FAR *) & (r->CX));	/* Year                 */
      if (rc != SUCCESS)
        r->AL = 0xff;
      else
        r->AL = 0;
      break;

      /* Get Time                                                     */
    case 0x2c:
      DosGetTime(
                  (BYTE FAR *) & (r->CH),	/* Hour                 */
                  (BYTE FAR *) & (r->CL),	/* Minutes              */
                  (BYTE FAR *) & (r->DH),	/* Seconds              */
                  (BYTE FAR *) & (r->DL));	/* Hundredths           */
      break;

      /* Set Date                                                     */
    case 0x2d:
      rc = DosSetTime(
                       (BYTE FAR *) & (r->CH),	/* Hour                 */
                       (BYTE FAR *) & (r->CL),	/* Minutes              */
                       (BYTE FAR *) & (r->DH),	/* Seconds              */
                       (BYTE FAR *) & (r->DL));	/* Hundredths           */
      if (rc != SUCCESS)
        r->AL = 0xff;
      else
        r->AL = 0;
      break;

      /* Set verify flag                                              */
    case 0x2e:
      verify_ena = (r->AL ? TRUE : FALSE);
      break;

      /* Get DTA                                                      */
    case 0x2f:
      r->ES = FP_SEG(dta);
      r->BX = FP_OFF(dta);
      break;

      /* Get DOS Version                                              */
    case 0x30:
      r->AL = os_major;
      r->AH = os_minor;
      r->BH = OEM_ID;
      r->CH = REVISION_MAJOR;   /* JPP */
      r->CL = REVISION_MINOR;
      r->BL = REVISION_SEQ;
      
      if (ReturnAnyDosVersionExpected)  
      {
                            /* TE for testing purpose only and NOT 
                               to be documented:
                               return programs, who ask for version == XX.YY
                               exactly this XX.YY. 
                               this makes most MS programs more happy.
                            */
        UBYTE FAR *retp = MK_FP(r->cs, r->ip);
        
        if (     retp[0] == 0x3d  &&     /* cmp ax, xxyy */
                (retp[3] == 0x75 || retp[3] == 0x74)) /* je/jne error    */
        {
            r->AL = retp[1];
            r->AH = retp[2];
        }
        else if(retp[0] == 0x86 &&      /* xchg al,ah   */
                retp[1] == 0xc4 &&
                retp[2] == 0x3d &&      /* cmp ax, xxyy */
               (retp[5] == 0x75 || retp[5] == 0x74)) /* je/jne error    */                               
        {
            r->AL = retp[4];
            r->AH = retp[3];
        }                
            
      }
      
      break;

      /* Keep Program (Terminate and stay resident) */
    case 0x31:
      DosMemChange(cu_psp, r->DX < 6 ? 6 : r->DX, 0);
      return_mode = 3;
      return_code = r->AL;
      tsr = TRUE;
      return_user();
      break;

      /* Get default BPB */
    case 0x1f:
      /* Get DPB                                                      */
    case 0x32:
      /* r->DL is NOT changed by MS 6.22 */
      /* INT21/32 is documented to reread the DPB */
      {
      struct dpb FAR *dpb;  
      UCOUNT drv = r->DL;
      
      if (drv == 0 || r->AH == 0x1f) drv = default_drive;
      else          drv--;

      if (drv >= lastdrive)
      {
        r->AL = 0xFF;
        CritErrCode = 0x0f;
        break;
      }  
        
      dpb = CDSp->cds_table[drv].cdsDpb;
      if (dpb == 0 ||
          CDSp->cds_table[drv].cdsFlags & CDSNETWDRV)
      {
        r->AL = 0xFF;
        CritErrCode = 0x0f;
        break;
      }  
      dpb->dpb_flags = M_CHANGED;       /* force reread of drive BPB/DPB */
          
      if (media_check(dpb) < 0)
      {
          r->AL = 0xff;
          CritErrCode = 0x0f;
          break;
      }
      r->DS = FP_SEG(dpb);
      r->BX = FP_OFF(dpb);
      r->AL = 0;
      }

      break;
/*
    case 0x33:  
    see int21_syscall
*/
      /* Get InDOS flag                                               */
    case 0x34:
      {
        BYTE FAR *p;

        p = (BYTE FAR *) ((BYTE *) & InDOS);
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get Interrupt Vector                                         */
    case 0x35:
      {
        BYTE FAR *p;

        p = getvec((COUNT) r->AL);
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Dos Get Disk Free Space                                      */
    case 0x36:
      DosGetFree(
                  r->DL,
                  (COUNT FAR *) & r->AX,
                  (COUNT FAR *) & r->BX,
                  (COUNT FAR *) & r->CX,
                  (COUNT FAR *) & r->DX);
      break;

      /* Undocumented Get/Set Switchar                                */
    case 0x37:
      switch (r->AL)
      {
          /* Get switch character */
        case 0x00:
          r->DL = switchar;
          r->AL = 0x00;
          break;

          /* Set switch character */
        case 0x01:
          switchar = r->DL;
          r->AL = 0x00;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Get/Set Country Info                                         */
    case 0x38:
      {
      	UWORD cntry = r->AL;

      	if(cntry == 0)
      		cntry = (UWORD)-1;
      	else if(cntry == 0xff)
      		cntry = r->BX;

        if (0xffff == r->DX) {
        	/* Set Country Code */
            if((rc = DosSetCountry(cntry)) < 0)
        		goto error_invalid;
        } else {
        	/* Get Country Information */
            if((rc = DosGetCountryInformation(cntry, FP_DS_DX)) < 0)
        		goto error_invalid;
            /* HACK FIXME */
	    if(cntry == (UWORD)-1)
		cntry = 1;
            /* END OF HACK */
            r->AX = r->BX = cntry;
        }
      }
      break;

      /* Dos Create Directory                                         */
    case 0x39:
      rc = DosMkdir((BYTE FAR *) FP_DS_DX);
      if (rc != SUCCESS)
        goto error_exit;
      break;

      /* Dos Remove Directory                                         */
    case 0x3a:
      rc = DosRmdir((BYTE FAR *) FP_DS_DX);
      if (rc != SUCCESS)
        goto error_exit;
      break;

      /* Dos Change Directory                                         */
    case 0x3b:
      if ((rc = DosChangeDir((BYTE FAR *) FP_DS_DX)) < 0)
        goto error_exit;
      break;

      /* Dos Create File                                              */
    case 0x3c:
      if ((rc = DosCreat(FP_DS_DX, r->CX)) < 0)
        goto error_exit;
      else
        r->AX = rc;
      break;

      /* Dos Open                                                     */
    case 0x3d:
      if ((rc = DosOpen(FP_DS_DX, r->AL)) < 0)
        goto error_exit;
      else
        r->AX = rc;
      break;

      /* Dos Close                                                    */
    case 0x3e:
      if ((rc = DosClose(r->BX)) < 0)
        goto error_exit;
      break;

      /* Dos Read                                                     */
    case 0x3f:
      rc1 = DosRead(r->BX, r->CX, FP_DS_DX, (COUNT FAR *) & rc);
      if (rc != SUCCESS)
        goto error_exit;
      else
        r->AX = rc1;
      break;

      /* Dos Write                                                    */
    case 0x40:
      rc1 = DosWrite(r->BX, r->CX, FP_DS_DX, (COUNT FAR *) & rc);
      if (rc != SUCCESS)
        goto error_exit;
      else
        r->AX = rc1;
      break;

      /* Dos Delete File                                              */
    case 0x41:
      rc = DosDelete((BYTE FAR *) FP_DS_DX);
      if (rc < 0)
        goto error_exit;
      break;

      /* Dos Seek                                                     */
    case 0x42:
      {
      ULONG lrc;
      if ((rc = DosSeek(r->BX, (LONG) ((((LONG) (r->CX)) << 16) + r->DX), r->AL, &lrc)) < 0)
        goto error_exit;
      else
      {
        r->DX = (lrc >> 16);
        r->AX = (UWORD)lrc;
      }
      }
      break;

      /* Get/Set File Attributes                                      */
    case 0x43:
      switch (r->AL)
      {
        case 0x00:
          rc = DosGetFattr((BYTE FAR *) FP_DS_DX);
          if (rc >= SUCCESS)
              r->CX = rc;
          break;

        case 0x01:
          rc = DosSetFattr((BYTE FAR *) FP_DS_DX, r->CX);
          break;

        default:
          goto error_invalid;
      }
      if (rc < SUCCESS)
        goto error_exit;
      break;

      /* Device I/O Control                                           */
    case 0x44:
      rc = DosDevIOctl(r);

      if (rc != SUCCESS)
        goto error_exit;
      break;

      /* Duplicate File Handle                                        */
    case 0x45:
      rc = DosDup(r->BX);
      if (rc < SUCCESS)
        goto error_exit;
      else
        r->AX = rc;
      break;

      /* Force Duplicate File Handle                                  */
    case 0x46:
      rc = DosForceDup(r->BX, r->CX);
      if (rc < SUCCESS)
        goto error_exit;
      break;

      /* Get Current Directory                                        */
    case 0x47:
      if ((rc = DosGetCuDir(r->DL, MK_FP(r->DS, r->SI))) < 0)
        goto error_exit;
      else
        r->AX = 0x0100;         /*jpp: from interrupt list */
      break;

      /* Allocate memory */
    case 0x48:
      if ((rc = DosMemAlloc(r->BX, mem_access_mode, &(r->AX), &(r->BX))) < 0)
      {
        DosMemLargest(&(r->BX));
        goto error_exit;
      }
      else
        ++(r->AX);              /* DosMemAlloc() returns seg of MCB rather than data */
      break;

      /* Free memory */
    case 0x49:
      if ((rc = DosMemFree((r->ES) - 1)) < 0)
        goto error_exit;
      break;

      /* Set memory block size */
    case 0x4a:
      {
        UWORD maxSize;

        if ((rc = DosMemChange(r->ES, r->BX, &maxSize)) < 0)
        {
          if (rc == DE_NOMEM)
            r->BX = maxSize;

#if 0
          if (cu_psp == r->ES)
          {

            psp FAR *p;

            p = MK_FP(cu_psp, 0);
            p->ps_size = r->BX + cu_psp;
          }
#endif
          goto error_exit;
        }

        break;
      }

      /* Load and Execute Program */
    case 0x4b:
      break_flg = FALSE;

      if ((rc = DosExec(r->AL, MK_FP(r->ES, r->BX), FP_DS_DX))
          != SUCCESS)
        goto error_exit;
      break;

      /* Terminate Program                                            */
    case 0x00:
      r->AX = 0x4c00;

      /* End Program                                                  */
    case 0x4c:
      if (cu_psp == RootPsp
          || ((psp FAR *) (MK_FP(cu_psp, 0)))->ps_parent == cu_psp)
        break;
      tsr = FALSE;
      if (ErrorMode)
      {
        ErrorMode = FALSE;
        return_mode = 2;
      }
      else if (break_flg)
      {
        break_flg = FALSE;
        return_mode = 1;
      }
      else
      {
        return_mode = 0;
      }
      return_code = r->AL;
      if (DosMemCheck() != SUCCESS)
        panic("MCB chain corrupted");
#ifdef TSC
      StartTrace();
#endif
      return_user();
      break;

      /* Get Child-program Return Value                               */
    case 0x4d:
      r->AL = return_code;
      r->AH = return_mode;
      break;

      /* Dos Find First                                               */
    case 0x4e:
      /* dta for this call is set on entry.  This     */
      /* needs to be changed for new versions.        */
      if ((rc = DosFindFirst((UCOUNT) r->CX, (BYTE FAR *) FP_DS_DX)) < 0)
        goto error_exit;
      r->AX = 0;
      break;

      /* Dos Find Next                                                */
    case 0x4f:
      /* dta for this call is set on entry.  This     */
      /* needs to be changed for new versions.        */
      if ((rc = DosFindNext()) < 0)
      {
        if (rc == DE_FILENOTFND)
          rc = DE_NFILES;
        goto error_exit;
      }
      else
        r->AX = -SUCCESS;
      break;
/*
    case 0x50:  
    case 0x51:
    see int21_syscall
*/
      /* ************UNDOCUMENTED************************************* */
      /* Get List of Lists                                            */
    case 0x52:
      {
        BYTE FAR *p;

        p = (BYTE FAR *) & DPBp;
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

    case 0x53:
      /*  DOS 2+ internal - TRANSLATE BIOS PARAMETER BLOCK TO DRIVE PARAM BLOCK */
      bpb_to_dpb((bpb FAR *)MK_FP(r->DS, r->SI), (struct dpb FAR *)MK_FP(r->ES, r->BP));
      break;
      
      /* Get verify state                                             */
    case 0x54:
      r->AL = (verify_ena ? TRUE : FALSE);
      break;

      /* ************UNDOCUMENTED************************************* */
      /* Dos Create New Psp & set p_size                              */
    case 0x55:
      new_psp((psp FAR *) MK_FP(r->DX, 0), r->SI);
      cu_psp = r->DX;
      break;

      /* Dos Rename                                                   */
    case 0x56:
      rc = DosRename((BYTE FAR *) FP_DS_DX, (BYTE FAR *) MK_FP(r->ES, r->DI));
      if (rc < SUCCESS)
        goto error_exit;
      else
        CLEAR_CARRY_FLAG();
      break;

      /* Get/Set File Date and Time                                   */
    case 0x57:
      CLEAR_CARRY_FLAG();
      switch (r->AL)
      {
        case 0x00:
          rc = DosGetFtime(
                            (COUNT) r->BX,	/* Handle               */
                            (date FAR *) & r->DX,	/* FileDate             */
                            (time FAR *) & r->CX);	/* FileTime             */
          if (rc < SUCCESS)
            goto error_exit;
          break;

        case 0x01:
          rc = DosSetFtime(
                            (COUNT) r->BX,	/* Handle               */
                            (date) r->DX,	/* FileDate             */
                            (time) r->CX);	/* FileTime             */
          if (rc < SUCCESS)
            goto error_exit;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Get/Set Allocation Strategy                                  */
    case 0x58:
      CLEAR_CARRY_FLAG();
      switch (r->AL)
      {
        case 0x00:
          r->AL = mem_access_mode;
          r->AH = 0;
          break;

        case 0x01:
        {
            switch (r->BL)
            {
            case LAST_FIT:
            case LAST_FIT_U:
            case LAST_FIT_UO:
            case BEST_FIT:
            case BEST_FIT_U:
            case BEST_FIT_UO:
            case FIRST_FIT:
            case FIRST_FIT_U:
            case FIRST_FIT_UO:
                mem_access_mode = r->BL;
                break;

            default:
                goto error_invalid;
            }
        }
            break;

        case 0x02:
            r->AL = uppermem_link;
            break;

        case 0x03:
            if (uppermem_root) {
                DosUmbLink(r->BL);
                break;
            } /* else fall through */            

        default:
          goto error_invalid;
#ifdef DEBUG
        case 0xff:
          show_chain();
          break;
#endif
      }
      break;

      /* Get Extended Error */
    case 0x59:
        r->AX = CritErrCode;
        r->ES = FP_SEG(CritErrDev);
        r->DI = FP_OFF(CritErrDev);
        r->CH = CritErrLocus;
        r->BH = CritErrClass;
        r->BL = CritErrAction;
        CLEAR_CARRY_FLAG();
      break;

      /* Create Temporary File */
    case 0x5a:
      if ((rc = DosMkTmp(FP_DS_DX, r->CX)) < 0)
        goto error_exit;
      else
      {
        r->AX = rc;
        CLEAR_CARRY_FLAG();
      }
      break;

      /* Create New File */
    case 0x5b:
      if (!IsDevice(FP_DS_DX) && (rc = DosOpen(FP_DS_DX, 0)) >= 0)
      {
        DosClose(rc);
        r->AX = 80;
        goto error_out;
      }
      else
      {
        if ((rc = DosCreat(FP_DS_DX, r->CX)) < 0)
          goto error_exit;
        else
        {
          r->AX = rc;
          CLEAR_CARRY_FLAG();
        }
      }
      break;

/* /// Added for SHARE.  - Ron Cemer */
      /* Lock/unlock file access */
    case 0x5c:
      if ((rc = DosLockUnlock
        (r->BX,
         (((unsigned long)r->CX)<<16)|(((unsigned long)r->DX)&0xffffL),
         (((unsigned long)r->SI)<<16)|(((unsigned long)r->DI)&0xffffL),
         ((r->AX & 0xff) != 0))) != 0)
          goto error_exit;
      CLEAR_CARRY_FLAG();
      break;
/* /// End of additions for SHARE.  - Ron Cemer */

      /* UNDOCUMENTED: server, share.exe and sda function             */
    case 0x5d:
      switch (r->AL)
      {
          /* Remote Server Call */
        case 0x00:
          {
            UWORD FAR *x = FP_DS_DX;
            r->AX = x[0];
            r->BX = x[1];
            r->CX = x[2];
            r->DX = x[3];
            r->SI = x[4];
            r->DI = x[5];
            r->DS = x[6];
            r->ES = x[7];
          }
          goto dispatch;

        case 0x06:
          r->DS = FP_SEG(internal_data);
          r->SI = FP_OFF(internal_data);
          r->CX = swap_always - internal_data;
          r->DX = swap_indos - internal_data;
          CLEAR_CARRY_FLAG();
          break;

        case 0x07:
        case 0x08:
        case 0x09:
	  rc = -int2f_Remote_call(REM_PRINTREDIR, 0, 0, r->DX, 0, 0, (MK_FP(0, Int21AX)));
	  if (rc != SUCCESS)
            goto error_exit;
          CLEAR_CARRY_FLAG();
          break;
        default:
          goto error_invalid;
      }
      break;

    case 0x5e:
      CLEAR_CARRY_FLAG();
      switch (r->AL)
      {
        case 0x00:
          r->CX = get_machine_name(FP_DS_DX);
          break;

        case 0x01:
          set_machine_name(FP_DS_DX, r->CX);
          break;

        default:
          rc = -int2f_Remote_call(REM_PRINTSET, r->BX, r->CX, r->DX, (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX)));
	  if (rc != SUCCESS) goto error_exit;
          r->AX=SUCCESS;
          break;
      }
      break;

    case 0x5f:
      CLEAR_CARRY_FLAG();
      switch (r->AL)
      {
        case 0x07:
          if (r->DL < lastdrive) {
            CDSp->cds_table[r->DL].cdsFlags |= 0x100;
	  }
          break;

        case 0x08:
          if (r->DL < lastdrive) {
            CDSp->cds_table[r->DL].cdsFlags &= ~0x100;
	  }
          break;

        default:
/*              
            void int_2f_111e_call(iregs FAR *r);
            int_2f_111e_call(r);          
          break;*/

          rc = -int2f_Remote_call(REM_DOREDIRECT, r->BX, r->CX, r->DX,
                                 (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX)));
	  if (rc != SUCCESS)
            goto error_exit;
          r->AX=SUCCESS;
          break;
      }
      break;

    case 0x60:                 /* TRUENAME */
      CLEAR_CARRY_FLAG();
      if ((rc = truename(MK_FP(r->DS, r->SI),
                      adjust_far(MK_FP(r->ES, r->DI)), FALSE)) != SUCCESS)
        goto error_exit;
      break;

#ifdef TSC
      /* UNDOCUMENTED: no-op                                          */
      /*                                                              */
      /* DOS-C: tsc support                                           */
    case 0x61:
#ifdef DEBUG
      switch (r->AL)
      {
        case 0x01:
          bTraceNext = TRUE;
          break;

        case 0x02:
          bDumpRegs = FALSE;
          break;
      }
#endif
      r->AL = 0x00;
      break;
#endif

      /* UNDOCUMENTED: return current psp                             
    case 0x62: is in int21_syscall
      r->BX = cu_psp;
      break;
      */
      
      /* UNDOCUMENTED: Double byte and korean tables                  */
    case 0x63:
      {
#define DBLBYTE
#ifdef DBLBYTE
        static char dbcsTable[2] =
        {
          0, 0
        };
        void FAR *dp = &dbcsTable;

        r->DS = FP_SEG(dp);
        r->SI = FP_OFF(dp);
        r->AL = 0;
#else
        /* not really supported, but will pass.                 */
        r->AL = 0x00;           /*jpp: according to interrupt list */	
				/*Bart: fails for PQDI: use the above again */
#endif
        break;
      }
/*
    case 0x64:
      see above (invalid)
*/      

      /* Extended country info                                        */
    case 0x65:
    	switch(r->AL) {
    	case 0x20:				/* upcase single character */
            r->DL = DosUpChar(r->DL);
            break;
        case 0x21:				/* upcase memory area */
            DosUpMem(FP_DS_DX, r->CX);
            break;
        case 0x22:				/* upcase ASCIZ */
            DosUpString(FP_DS_DX);
            break;
    	case 0xA0:				/* upcase single character of filenames */
            r->DL = DosUpFChar(r->DL);
            break;
        case 0xA1:				/* upcase memory area of filenames */
            DosUpFMem(FP_DS_DX, r->CX);
            break;
        case 0xA2:				/* upcase ASCIZ of filenames */
            DosUpFString(FP_DS_DX);
            break;
        case 0x23:				/* check Yes/No response */
            r->AX = DosYesNo(r->DL);
            break;
      	default:
            if ((rc = DosGetData(
                         r->AL, r->BX, r->DX, r->CX,
                         MK_FP(r->ES, r->DI))) < 0) {
#ifdef NLS_DEBUG
   printf("DosGetData() := %d\n", rc);
#endif
               goto error_exit;
            }
#ifdef NLS_DEBUG
   printf("DosGetData() returned successfully\n", rc);
#endif

            break;
         }
		CLEAR_CARRY_FLAG();
      break;
      

      /* Code Page functions */
    case 0x66: {
    	int rc;
      switch (r->AL)
      {
        case 1:
          rc = DosGetCodepage(&r->BX, &r->DX);
			break;
        case 2:
          rc = DosSetCodepage(r->BX, r->DX);
          break;

        default:
          goto error_invalid;
      }
      if(rc != SUCCESS)
      	goto error_exit;
      CLEAR_CARRY_FLAG();
      break;
     }

      /* Set Max file handle count */
    case 0x67:
      if ((rc = SetJFTSize(r->BX)) != SUCCESS)
        goto error_exit;
      else
        CLEAR_CARRY_FLAG();
      break;

      /* Flush file buffer -- COMMIT FILE -- dummy function right now.  */
    case 0x68:
    case 0x6a:
      CLEAR_CARRY_FLAG();
      break;

      /* Get/Set Serial Number */
    case 0x69:
      rc = ( r->BL == 0 ? default_drive : r->BL - 1);
      if (rc < lastdrive)
      {
        UWORD saveCX = r->CX;
        if (CDSp->cds_table[rc].cdsFlags & CDSNETWDRV) {
          goto error_invalid;
        }
        switch(r->AL){
            case 0x00:
            r->AL = 0x0d;
            r->CX = 0x0866;
            rc = DosDevIOctl(r);
            break;

            case 0x01:
            r->AL = 0x0d;
            r->CX = 0x0846;
            rc = DosDevIOctl(r);
            break;
        }
        r->CX = saveCX;
        if (rc != SUCCESS)
          goto error_exit;
        CLEAR_CARRY_FLAG();
        break;
      }
      else
        r->AL = 0xFF;
      break;
/*
    case 0x6a: see case 0x68
    case 0x6b: dummy func: return AL=0
*/    
    /* Extended Open-Creat, not fully functional. (bits 4,5,6 of BH) */
    case 0x6c:
      {
        COUNT x = 0;
      
        if (r->AL != 0 || r->DH != 0 ||
              (r->DL&0x0f) > 0x2 || (r->DL&0xf0) > 0x10)
            goto error_invalid;
        CLEAR_CARRY_FLAG();
        if ((rc = DosOpen(MK_FP(r->DS, r->SI),
                          (r->DL&0x0f) == 0x1 ? r->BL : 0)) < 0)
        {
            if (r->DL < 0x10)
                goto error_exit;
            /* else try to create below */
        }
        else switch (r->DL & 0x0f)
        {
          case 0x0:
            /* fail if file exists */
            DosClose(rc);
            rc = DE_FILEEXISTS;
            goto error_exit;
          case 0x1:
            /* file exists and opened: OK */
            r->CX = 0x01;
            goto break_out;
          case 0x2:  
            /* file exists: replace/open */
            DosClose(rc);
            x = 1;
            break;
        }
        /* cases 0x00, 0x01 are finished now */
        if ((rc = DosCreat(MK_FP(r->DS, r->SI), r->CX)) < 0)
            goto error_exit;
            
        r->CX = x+2;
break_out:        
        r->AX = rc;
        break;
      }


    /* case 0x6d and above not implemented : see default; return AL=0 */
        
  }

#ifdef DEBUG
  if (bDumpRegs)
  {
    fbcopy((VOID FAR *) user_r, (VOID FAR *) & error_regs,
           sizeof(iregs));
    dump_regs = TRUE;
    dump();
  }
#endif
}
예제 #13
0
fint lsqfitd_c( double *xdat ,
                fint   *xdim ,
                double *ydat ,
                double *wdat ,
                fint   *ndat ,
                double *fpar ,
                double *epar ,
                fint   *mpar ,
                fint   *npar ,
                double *tol  ,
                fint   *its  ,
                double *lab  ,
                fint   *fopt )
/*
 * lsqfitd is exported, and callable from C as well as Fortran.
 */
{
   fint   i;
   fint   n;
   fint   r;

   itc = 0;				/* fate of fit */
   found = 0;				/* reset */
   nfree = 0;				/* number of free parameters */
   nuse = 0;				/* number of legal data points */
   if (*tol < (DBL_EPSILON * 10.0)) {
      tolerance = DBL_EPSILON * 10.0;	/* default tolerance */
   } else {
      tolerance = *tol;			/* tolerance */
   }
   labda = fabs( *lab ) * LABFAC;	/* start value for mixing parameter */
   for (i = 0; i < (*npar); i++) {
      if (mpar[i]) {
         if (nfree > MAXPAR) return( -1 );	/* too many free parameters */
         parptr[nfree++] = i;		/* a free parameter */
      }
   }
   if (nfree == 0) return( -2 );	/* no free parameters */
   for (n = 0; n < (*ndat); n++) {
      if (wdat[n] > 0.0) nuse++;	/* legal weight */
   }
   if (nfree >= nuse) return( -3 );	/* no degrees of freedom */
   if (labda == 0.0) {			/* linear fit */
      for (i = 0; i < nfree; fpar[parptr[i++]] = 0.0);
      getmat( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar, fopt );
      r = getvec( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar, fopt );
      if (r) return( r );		/* error */
      for (i = 0; i < (*npar); i++) {
         fpar[i] = epar[i];		/* save new parameters */
         epar[i] = 0.0;			/* and set errors to zero */
      }
      chi1 = sqrt( chi1 / (double) (nuse - nfree) );
      for (i = 0; i < nfree; i++) {
         if ((matrix1[i][i] <= 0.0) || (matrix2[i][i] <= 0.0)) return( -7 );
         epar[parptr[i]] = chi1 * sqrt( matrix2[i][i] ) / sqrt( matrix1[i][i] );
      }
   } else {				/* Non-linear fit */
      /*
       * The non-linear fit uses the steepest descent method in combination
       * with the Taylor method. The mixing of these methods is controlled
       * by labda. In the outer loop (called the iteration loop) we build
       * the matrix and calculate the correction vector. In the inner loop
       * (called the interpolation loop) we check whether we have obtained
       * a better solution than the previous one. If so, we leave the
       * inner loop, else we increase labda (give more weight to the
       * steepest descent method), calculate the correction vector and check
       * again. After the inner loop we do a final check on the goodness of
       * the fit and if this satisfies the tolerance we calculate the
       * errors of the fitted parameters.
       */
      while (!found) {				/* iteration loop */
         if (itc++ == (*its)) return( -4 );	/* increase iteration counter */
         getmat( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar, fopt );
         /*
          * here we decrease labda since we may assume that each iteration
          * brings us closer to the answer.
          */
         if (labda > LABMIN) labda /= LABFAC;	/* decrease labda */
         r = getvec( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar, fopt );
         if (r) return( r );		/* error */
         while (chi1 >= chi2) {		/* interpolation loop */
            /*
             * The next statement is based on experience, not on the
             * mathematics of the problem although I (KGB) think that it
             * is correct to assume that we have reached convergence
             * when the pure steepest descent method does not produce
             * a better solution. Think about this somewhat more, anyway,
             * as already stated, the next statement is based on experience.
             */
            if (labda > LABMAX) break;	/* assume solution found */
            labda *= LABFAC;		/* Increase mixing parameter */
            r = getvec( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar, fopt );
            if (r) return( r );		/* error */
         }
         if (labda <= LABMAX) {		/* save old parameters */
            for (i = 0; i < (*npar); i++) fpar[i] = epar[i];
         }
         if (fabs( chi2 - chi1 ) <= (tolerance * chi1) || (labda > LABMAX)) {
            /*
             * We have a satisfying solution, so now we need to calculate
             * the correct errors of the fitted parameters. This we do
             * by using the pure Taylor method because we are very close
             * to the real solution.
             */
            labda = 0.0;		/* for Taylor solution */
            getmat( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar, fopt );
            r = getvec( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar, fopt );
            if (r) return( r );		/* error */
            for (i = 0; i < (*npar); i++) {
               epar[i] = 0.0;		/* and set error to zero */
            }
            chi2 = sqrt( chi2 / (double) (nuse - nfree) );
            for (i = 0; i < nfree; i++) {
               if ((matrix1[i][i] <= 0.0) || (matrix2[i][i] <= 0.0)) return( -7);
               epar[parptr[i]] = chi2 * sqrt( matrix2[i][i] ) / sqrt( matrix1[i][i] );
            }
            found = 1;			/* we found a solution */
         }
      }
   }
   return( itc );			/* return number of iterations */
}
예제 #14
0
VOID int21_service(iregs FAR * r)
{
  COUNT rc,
    rc1;
  ULONG lrc;
  psp FAR *p = MK_FP(cu_psp, 0);

  p->ps_stack = (BYTE FAR *) r;

#ifdef DEBUG
  if (bDumpRegs)
  {
    fbcopy((VOID FAR *) user_r, (VOID FAR *) & error_regs, sizeof(iregs));
    printf("System call (21h): %02x\n", user_r->AX);
    dump_regs = TRUE;
    dump();
  }
#endif

dispatch:

  /* Check for Ctrl-Break */
  switch (r->AH)
  {
    default:
      if (!break_ena)
        break;
    case 0x01:
    case 0x02:
    case 0x03:
    case 0x04:
    case 0x05:
    case 0x08:
    case 0x09:
    case 0x0a:
    case 0x0b:
      if (control_break())
        handle_break();
  }

  /* The dispatch handler                                         */
  switch (r->AH)
  {
      /* int 21h common error handler                                 */
    case 0x64:
    case 0x6b:
    default:
    error_invalid:
      r->AX = -DE_INVLDFUNC;
      goto error_out;
    error_exit:
      r->AX = -rc;
    error_out:
      r->FLAGS |= FLG_CARRY;
      break;

#if 0
      /* Moved to simulate a 0x4c00 -- 1999/04/21 ska */
      /* Terminate Program                                            */
    case 0x00:
      if (cu_psp == RootPsp)
        break;
      else if (((psp FAR *) (MK_FP(cu_psp, 0)))->ps_parent == cu_psp)
        break;
      tsr = FALSE;
      return_mode = break_flg ? 1 : 0;
      return_code = r->AL;
      if (DosMemCheck() != SUCCESS)
        panic("MCB chain corrupted");
#ifdef TSC
      StartTrace();
#endif
      return_user();
      break;
#endif

      /* Read Keyboard with Echo                      */
    case 0x01:
      Do_DosIdle_loop();
      r->AL = _sti();
      sto(r->AL);
      break;

      /* Display Character                                            */
    case 0x02:
      sto(r->DL);
      break;

      /* Auxiliary Input                                                      */
    case 0x03:
      r->AL = _sti();
      break;

      /* Auxiliary Output                                                     */
    case 0x04:
      sto(r->DL);
      break;

      /* Print Character                                                      */
    case 0x05:
      sto(r->DL);
      break;

      /* Direct Cosole I/O                                            */
    case 0x06:
      if (r->DL != 0xff)
        sto(r->DL);
      else if (StdinBusy())
      {
        r->AL = 0x00;
        r->FLAGS |= FLG_ZERO;
      }
      else
      {
        r->FLAGS &= ~FLG_ZERO;
        r->AL = _sti();
      }
      break;

      /* Direct Console Input                                         */
    case 0x07:
      /* Read Keyboard Without Echo                                   */
    case 0x08:
      Do_DosIdle_loop();
      r->AL = _sti();
      break;

      /* Display String                                               */
    case 0x09:
      {
        static COUNT scratch;
        BYTE FAR *p = MK_FP(r->DS, r->DX),
          FAR * q;
        q = p;
        while (*q != '$')
          ++q;
        DosWrite(STDOUT, q - p, p, (COUNT FAR *) & scratch);
      }
      r->AL = '$';
      break;

      /* Buffered Keyboard Input                                      */
    case 0x0a:
      ((keyboard FAR *) MK_FP(r->DS, r->DX))->kb_count = 0;
      sti((keyboard FAR *) MK_FP(r->DS, r->DX));
      ((keyboard FAR *) MK_FP(r->DS, r->DX))->kb_count -= 2;
      break;

      /* Check Stdin Status                                           */
    case 0x0b:
      if (StdinBusy())
        r->AL = 0xFF;
      else
        r->AL = 0x00;
      break;

      /* Flush Buffer, Read Keayboard                                 */
    case 0x0c:
      KbdFlush();
      switch (r->AL)
      {
        case 0x01:
        case 0x06:
        case 0x07:
        case 0x08:
        case 0x0a:
          r->AH = r->AL;
          goto dispatch;

        default:
          r->AL = 0x00;
          break;
      }
      break;

      /* Reset Drive                                                  */
    case 0x0d:
      flush();
      break;

      /* Set Default Drive                                            */
    case 0x0e:
      r->AL = DosSelectDrv(r->DL);
      break;

    case 0x0f:
      if (FcbOpen(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x10:
      if (FcbClose(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x11:
      if (FcbFindFirst(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x12:
      if (FcbFindNext(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x13:
      if (FcbDelete(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x14:
      {
        COUNT nErrorCode;

        if (FcbRead(MK_FP(r->DS, r->DX), &nErrorCode))
          r->AL = 0;
        else
          r->AL = nErrorCode;
        break;
      }

    case 0x15:
      {
        COUNT nErrorCode;

        if (FcbWrite(MK_FP(r->DS, r->DX), &nErrorCode))
          r->AL = 0;
        else
          r->AL = nErrorCode;
        break;
      }

    case 0x16:
      if (FcbCreate(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x17:
      if (FcbRename(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

      /* CP/M compatibility functions                                 */
    case 0x18:
    case 0x1d:
    case 0x1e:
    case 0x20:
#ifndef TSC
    case 0x61:
#endif
      r->AL = 0;
      break;

      /* Get Default Drive                                            */
    case 0x19:
      r->AL = default_drive;
      break;

      /* Set DTA                                                      */
    case 0x1a:
      {
        psp FAR *p = MK_FP(cu_psp, 0);

        p->ps_dta = MK_FP(r->DS, r->DX);
        dos_setdta(p->ps_dta);
      }
      break;

      /* Get Default Drive Data                                       */
    case 0x1b:
      {
        BYTE FAR *p;

        FatGetDrvData(0,
                      (COUNT FAR *) & r->AX,
                      (COUNT FAR *) & r->CX,
                      (COUNT FAR *) & r->DX,
                      (BYTE FAR **) & p);
        r->DS = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get Drive Data                                               */
    case 0x1c:
      {
        BYTE FAR *p;

        FatGetDrvData(r->DL,
                      (COUNT FAR *) & r->AX,
                      (COUNT FAR *) & r->CX,
                      (COUNT FAR *) & r->DX,
                      (BYTE FAR **) & p);
        r->DS = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get default DPB                                              */
    case 0x1f:
      if (default_drive < lastdrive)
      {
        struct dpb FAR *dpb = (struct dpb FAR *)CDSp->cds_table[default_drive].cdsDpb;
        if (dpb == 0)
        {
          r->AL = 0xff;
          break;
        }

        r->DS = FP_SEG(dpb);
        r->BX = FP_OFF(dpb);
        r->AL = 0;
      }
      else
        r->AL = 0xff;
      break;

      /* Random read using FCB */
    case 0x21:
      {
        COUNT nErrorCode;

        if (FcbRandomRead(MK_FP(r->DS, r->DX), &nErrorCode))
          r->AL = 0;
        else
          r->AL = nErrorCode;
        break;
      }

      /* Random write using FCB */
    case 0x22:
      {
        COUNT nErrorCode;

        if (FcbRandomWrite(MK_FP(r->DS, r->DX), &nErrorCode))
          r->AL = 0;
        else
          r->AL = nErrorCode;
        break;
      }

      /* Get file size in records using FCB */
    case 0x23:
      if (FcbGetFileSize(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

      /* Set random record field in FCB */
    case 0x24:
      FcbSetRandom(MK_FP(r->DS, r->DX));
      break;

      /* Set Interrupt Vector                                         */
    case 0x25:
      {
        VOID(INRPT FAR * p) () = MK_FP(r->DS, r->DX);

        setvec(r->AL, p);
      }
      break;

      /* Dos Create New Psp                                           */
    case 0x26:
      {
        psp FAR *p = MK_FP(cu_psp, 0);

        new_psp((psp FAR *) MK_FP(r->DX, 0), p->ps_size);
      }
      break;

      /* Read random record(s) using FCB */
    case 0x27:
      {
        COUNT nErrorCode;

        if (FcbRandomBlockRead(MK_FP(r->DS, r->DX), r->CX, &nErrorCode))
          r->AL = 0;
        else
          r->AL = nErrorCode;
        break;
      }

      /* Write random record(s) using FCB */
    case 0x28:
      {
        COUNT nErrorCode;

        if (FcbRandomBlockWrite(MK_FP(r->DS, r->DX), r->CX, &nErrorCode))
          r->AL = 0;
        else
          r->AL = nErrorCode;
        break;
      }

      /* Parse File Name                                              */
    case 0x29:
      {
        BYTE FAR *lpFileName;

        lpFileName = MK_FP(r->DS, r->SI);
        r->AL = FcbParseFname(r->AL,
                              &lpFileName,
                              MK_FP(r->ES, r->DI));
        r->DS = FP_SEG(lpFileName);
        r->SI = FP_OFF(lpFileName);
      }
      break;

      /* Get Date                                                     */
    case 0x2a:
      DosGetDate(
                  (BYTE FAR *) & (r->AL),	/* WeekDay              */
                  (BYTE FAR *) & (r->DH),	/* Month                */
                  (BYTE FAR *) & (r->DL),	/* MonthDay             */
                  (COUNT FAR *) & (r->CX));	/* Year                 */
      break;

      /* Set Date                                                     */
    case 0x2b:
      rc = DosSetDate(
                       (BYTE FAR *) & (r->DH),	/* Month                */
                       (BYTE FAR *) & (r->DL),	/* MonthDay             */
                       (COUNT FAR *) & (r->CX));	/* Year                 */
      if (rc != SUCCESS)
        r->AL = 0xff;
      else
        r->AL = 0;
      break;

      /* Get Time                                                     */
    case 0x2c:
      DosGetTime(
                  (BYTE FAR *) & (r->CH),	/* Hour                 */
                  (BYTE FAR *) & (r->CL),	/* Minutes              */
                  (BYTE FAR *) & (r->DH),	/* Seconds              */
                  (BYTE FAR *) & (r->DL));	/* Hundredths           */
      break;

      /* Set Date                                                     */
    case 0x2d:
      rc = DosSetTime(
                       (BYTE FAR *) & (r->CH),	/* Hour                 */
                       (BYTE FAR *) & (r->CL),	/* Minutes              */
                       (BYTE FAR *) & (r->DH),	/* Seconds              */
                       (BYTE FAR *) & (r->DL));	/* Hundredths           */
      if (rc != SUCCESS)
        r->AL = 0xff;
      else
        r->AL = 0;
      break;

      /* Set verify flag                                              */
    case 0x2e:
      verify_ena = (r->AL ? TRUE : FALSE);
      break;

      /* Get DTA                                                      */
    case 0x2f:
      r->ES = FP_SEG(dta);
      r->BX = FP_OFF(dta);
      break;

      /* Get DOS Version                                              */
    case 0x30:
      r->AL = os_major;
      r->AH = os_minor;
      r->BH = OEM_ID;
      r->CH = REVISION_MAJOR;   /* JPP */
      r->CL = REVISION_MINOR;
      r->BL = REVISION_SEQ;
      break;

      /* Keep Program (Terminate and stay resident) */
    case 0x31:
      DosMemChange(cu_psp, r->DX < 6 ? 6 : r->DX, 0);
      return_mode = 3;
      return_code = r->AL;
      tsr = TRUE;
      return_user();
      break;

      /* Get DPB                                                      */
    case 0x32:
      if (r->DL < lastdrive)
      {
        struct dpb FAR *dpb = CDSp->cds_table[r->DL].cdsDpb;
        if (dpb == 0)
        {
          r->AL = 0xff;
          break;
        }
        r->DS = FP_SEG(dpb);
        r->BX = FP_OFF(dpb);
        r->AL = 0;
      }
      else
        r->AL = 0xFF;
      break;

      /* Get InDOS flag                                               */
    case 0x34:
      {
        BYTE FAR *p;

        p = (BYTE FAR *) ((BYTE *) & InDOS);
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get Interrupt Vector                                         */
    case 0x35:
      {
        BYTE FAR *p;

        p = getvec((COUNT) r->AL);
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Dos Get Disk Free Space                                      */
    case 0x36:
      DosGetFree(
                  (COUNT) r->DL,
                  (COUNT FAR *) & r->AX,
                  (COUNT FAR *) & r->BX,
                  (COUNT FAR *) & r->CX,
                  (COUNT FAR *) & r->DX);
      break;

      /* Undocumented Get/Set Switchar                                */
    case 0x37:
      switch (r->AL)
      {
          /* Get switch character */
        case 0x00:
          r->DL = switchar;
          r->AL = 0x00;
          break;

          /* Set switch character */
        case 0x01:
          switchar = r->DL;
          r->AL = 0x00;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Get/Set Country Info                                         */
    case 0x38:
      {
        BYTE FAR *lpTable
        = (BYTE FAR *) MK_FP(r->DS, r->DX);
        BYTE nRetCode;

        if (0xffff == r->DX)
        {
          r->BX = SetCtryInfo(
                               (UBYTE FAR *) & (r->AL),
                               (UWORD FAR *) & (r->BX),
                               (BYTE FAR *) & lpTable,
                               (UBYTE *) & nRetCode);

          if (nRetCode != 0)
          {
            r->AX = 0xff;
            r->FLAGS |= FLG_CARRY;
          }
          else
          {
            r->AX = nRetCode;
            r->FLAGS &= ~FLG_CARRY;
          }
        }
        else
        {
          r->BX = GetCtryInfo(&(r->AL), &(r->BX), lpTable);
          r->FLAGS &= ~FLG_CARRY;
        }
      }
      break;

      /* Dos Create Directory                                         */
    case 0x39:
      rc = dos_mkdir((BYTE FAR *) MK_FP(r->DS, r->DX));
      if (rc != SUCCESS)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Dos Remove Directory                                         */
    case 0x3a:
      rc = dos_rmdir((BYTE FAR *) MK_FP(r->DS, r->DX));
      if (rc != SUCCESS)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Dos Change Directory                                         */
    case 0x3b:
      if ((rc = DosChangeDir((BYTE FAR *) MK_FP(r->DS, r->DX))) < 0)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Dos Create File                                              */
    case 0x3c:
      if ((rc = DosCreat(MK_FP(r->DS, r->DX), r->CX)) < 0)
        goto error_exit;
      else
      {
        r->AX = rc;
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Dos Open                                                     */
    case 0x3d:
      if ((rc = DosOpen(MK_FP(r->DS, r->DX), r->AL)) < 0)
        goto error_exit;
      else
      {
        r->AX = rc;
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Dos Close                                                    */
    case 0x3e:
      if ((rc = DosClose(r->BX)) < 0)
        goto error_exit;
      else
        r->FLAGS &= ~FLG_CARRY;
      break;

      /* Dos Read                                                     */
    case 0x3f:
      rc = DosRead(r->BX, r->CX, MK_FP(r->DS, r->DX), (COUNT FAR *) & rc1);

      if (rc1 != SUCCESS)
      {
        r->FLAGS |= FLG_CARRY;
        r->AX = -rc1;
      }
      else
      {
        r->FLAGS &= ~FLG_CARRY;
        r->AX = rc;
      }
      break;

      /* Dos Write                                                    */
    case 0x40:
      rc = DosWrite(r->BX, r->CX, MK_FP(r->DS, r->DX), (COUNT FAR *) & rc1);
      if (rc1 != SUCCESS)
      {
        r->FLAGS |= FLG_CARRY;
        r->AX = -rc1;
      }
      else
      {
        r->FLAGS &= ~FLG_CARRY;
        r->AX = rc;
      }
      break;

      /* Dos Delete File                                              */
    case 0x41:
      rc = dos_delete((BYTE FAR *) MK_FP(r->DS, r->DX));
      if (rc < 0)
      {
        r->FLAGS |= FLG_CARRY;
        r->AX = -rc1;
      }
      else
        r->FLAGS &= ~FLG_CARRY;
      break;

      /* Dos Seek                                                     */
    case 0x42:
      if ((rc = DosSeek(r->BX, (LONG) ((((LONG) (r->CX)) << 16) + r->DX), r->AL, &lrc)) < 0)
        goto error_exit;
      else
      {
        r->DX = (lrc >> 16);
        r->AX = lrc & 0xffff;
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Get/Set File Attributes                                      */
    case 0x43:
      switch (r->AL)
      {
        case 0x00:
          rc = DosGetFattr((BYTE FAR *) MK_FP(r->DS, r->DX), (UWORD FAR *) & r->CX);
          if (rc < SUCCESS)
            goto error_exit;
          else
          {
            r->FLAGS &= ~FLG_CARRY;
          }
          break;

        case 0x01:
          rc = DosSetFattr((BYTE FAR *) MK_FP(r->DS, r->DX), (UWORD FAR *) & r->CX);
          if (rc != SUCCESS)
            goto error_exit;
          else
            r->FLAGS &= ~FLG_CARRY;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Device I/O Control                                           */
    case 0x44:
      {
        rc = DosDevIOctl(r, (COUNT FAR *) & rc1);

        if (rc1 != SUCCESS)
        {
          r->FLAGS |= FLG_CARRY;
          r->AX = -rc1;
        }
        else
        {
          r->FLAGS &= ~FLG_CARRY;
        }
      }
      break;

      /* Duplicate File Handle                                        */
    case 0x45:
      rc = DosDup(r->BX);
      if (rc < SUCCESS)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
        r->AX = rc;
      }
      break;

      /* Force Duplicate File Handle                                  */
    case 0x46:
      rc = DosForceDup(r->BX, r->CX);
      if (rc < SUCCESS)
        goto error_exit;
      else
        r->FLAGS &= ~FLG_CARRY;
      break;

      /* Get Current Directory                                        */
    case 0x47:
      if ((rc = DosGetCuDir(r->DL, MK_FP(r->DS, r->SI))) < 0)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
        r->AX = 0x0100;         /*jpp: from interrupt list */
      }
      break;

      /* Allocate memory */
    case 0x48:
      if ((rc = DosMemAlloc(r->BX, mem_access_mode, &(r->AX), &(r->BX))) < 0)
      {
        DosMemLargest(&(r->BX));
        goto error_exit;
      }
      else
      {
        ++(r->AX);              /* DosMemAlloc() returns seg of MCB rather than data */
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Free memory */
    case 0x49:
      if ((rc = DosMemFree((r->ES) - 1)) < 0)
        goto error_exit;
      else
        r->FLAGS &= ~FLG_CARRY;
      break;

      /* Set memory block size */
    case 0x4a:
      {
        UWORD maxSize;

        if ((rc = DosMemChange(r->ES, r->BX, &maxSize)) < 0)
        {
          if (rc == DE_NOMEM)
            r->BX = maxSize;

#if 0
          if (cu_psp == r->ES)
          {

            psp FAR *p;

            p = MK_FP(cu_psp, 0);
            p->ps_size = r->BX + cu_psp;
          }
#endif
          goto error_exit;
        }
        else
          r->FLAGS &= ~FLG_CARRY;

        break;
      }

      /* Load and Execute Program */
    case 0x4b:
      break_flg = FALSE;

      if ((rc = DosExec(r->AL, MK_FP(r->ES, r->BX), MK_FP(r->DS, r->DX)))
          != SUCCESS)
        goto error_exit;
      else
        r->FLAGS &= ~FLG_CARRY;
      break;

      /* Terminate Program                                            */
    case 0x00:
      r->AX = 0x4c00;

      /* End Program                                                  */
    case 0x4c:
      if (cu_psp == RootPsp
          || ((psp FAR *) (MK_FP(cu_psp, 0)))->ps_parent == cu_psp)
        break;
      tsr = FALSE;
/*      int2f_Remote_call(0x1122, 0, 0, 0, 0, 0, 0);
   int2f_Remote_call(REM_CLOSEALL, 0, 0, 0, 0, 0, 0);
 */
      if (ErrorMode)
      {
        ErrorMode = FALSE;
        return_mode = 2;
      }
      else if (break_flg)
      {
        break_flg = FALSE;
        return_mode = 1;
      }
      else
      {
        return_mode = 0;
      }
      return_code = r->AL;
      if (DosMemCheck() != SUCCESS)
        panic("MCB chain corrupted");
#ifdef TSC
      StartTrace();
#endif
      return_user();
      break;

      /* Get Child-program Return Value                               */
    case 0x4d:
      r->AL = return_code;
      r->AH = return_mode;
      break;

      /* Dos Find First                                               */
    case 0x4e:
      {
        /* dta for this call is set on entry.  This     */
        /* needs to be changed for new versions.        */
        if ((rc = DosFindFirst((UCOUNT) r->CX, (BYTE FAR *) MK_FP(r->DS, r->DX))) < 0)
          goto error_exit;
        else
        {
          r->AX = 0;
          r->FLAGS &= ~FLG_CARRY;
        }
      }
      break;

      /* Dos Find Next                                                */
    case 0x4f:
      {
        /* dta for this call is set on entry.  This     */
        /* needs to be changed for new versions.        */
        if ((rc = DosFindNext()) < 0)
        {
          r->AX = -rc;

          if (r->AX == 2)
            r->AX = 18;

          r->FLAGS |= FLG_CARRY;
        }
        else
        {
          r->FLAGS &= ~FLG_CARRY;
        }
      }
      break;

      /* ************UNDOCUMENTED************************************* */
      /* Get List of Lists                                            */
    case 0x52:
      {
        BYTE FAR *p;

        p = (BYTE FAR *) & DPBp;
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get verify state                                             */
    case 0x54:
      r->AL = (verify_ena ? TRUE : FALSE);
      break;

      /* ************UNDOCUMENTED************************************* */
      /* Dos Create New Psp & set p_size                              */
    case 0x55:
      new_psp((psp FAR *) MK_FP(r->DX, 0), r->SI);
      break;

      /* Dos Rename                                                   */
    case 0x56:
      rc = dos_rename(
                       (BYTE FAR *) MK_FP(r->DS, r->DX),	/* OldName      */
                       (BYTE FAR *) MK_FP(r->ES, r->DI));	/* NewName      */
      if (rc < SUCCESS)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Get/Set File Date and Time                                   */
    case 0x57:
      switch (r->AL)
      {
        case 0x00:
          rc = DosGetFtime(
                            (COUNT) r->BX,	/* Handle               */
                            (date FAR *) & r->DX,	/* FileDate             */
                            (time FAR *) & r->CX);	/* FileTime             */
          if (rc < SUCCESS)
            goto error_exit;
          else
            r->FLAGS &= ~FLG_CARRY;
          break;

        case 0x01:
          rc = DosSetFtime(
                            (COUNT) r->BX,	/* Handle               */
                            (date FAR *) & r->DX,	/* FileDate             */
                            (time FAR *) & r->CX);	/* FileTime             */
          if (rc < SUCCESS)
            goto error_exit;
          else
            r->FLAGS &= ~FLG_CARRY;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Get/Set Allocation Strategy                                  */
    case 0x58:
      switch (r->AL)
      {
        case 0x00:
          r->AX = mem_access_mode;
          break;

        case 0x01:
          if (((COUNT) r->BX) < 0 || r->BX > 2)
            goto error_invalid;
          else
          {
            mem_access_mode = r->BX;
            r->FLAGS &= ~FLG_CARRY;
          }
          break;

        default:
          goto error_invalid;
#ifdef DEBUG
        case 0xff:
          show_chain();
          break;
#endif
      }
      break;

      /* Create Temporary File */
    case 0x5a:
      if ((rc = DosMkTmp(MK_FP(r->DS, r->DX), r->CX)) < 0)
        goto error_exit;
      else
      {
        r->AX = rc;
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Create New File */
    case 0x5b:
      if ((rc = DosOpen(MK_FP(r->DS, r->DX), 0)) >= 0)
      {
        DosClose(rc);
        r->AX = 80;
        r->FLAGS |= FLG_CARRY;
      }
      else
      {
        if ((rc = DosCreat(MK_FP(r->DS, r->DX), r->CX)) < 0)
          goto error_exit;
        else
        {
          r->AX = rc;
          r->FLAGS &= ~FLG_CARRY;
        }
      }
      break;

      /* UNDOCUMENTED: server, share.exe and sda function             */
    case 0x5d:
      switch (r->AL)
      {
          /* Remote Server Call */
        case 0x00:
          {
            UWORD FAR *x = MK_FP(r->DS, r->DX);
            r->AX = x[0];
            r->BX = x[1];
            r->CX = x[2];
            r->DX = x[3];
            r->SI = x[4];
            r->DI = x[5];
            r->DS = x[6];
            r->ES = x[7];
          }
          goto dispatch;

        case 0x06:
          r->DS = FP_SEG(internal_data);
          r->SI = FP_OFF(internal_data);
          r->CX = swap_always - internal_data;
          r->DX = swap_indos - internal_data;
          r->FLAGS &= ~FLG_CARRY;
          break;

        case 0x07:
        case 0x08:
        case 0x09:
          int2f_Remote_call(REM_PRINTREDIR, 0, 0, r->DX, 0, 0, (MK_FP(0, Int21AX)));
          break;

        default:
          goto error_invalid;
      }
      break;

    case 0x5e:
      switch (r->AL)
      {
        case 0x00:
          r->CX = get_machine_name(MK_FP(r->DS, r->DX));
          break;

        case 0x01:
          set_machine_name(MK_FP(r->DS, r->DX), r->CX);
          break;

        default:
          int2f_Remote_call(REM_PRINTSET, r->BX, r->CX, r->DX, (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX)));
          break;
      }
      break;

    case 0x5f:
      switch (r->AL)
      {
        case 0x07:
          CDSp->cds_table[r->DL].cdsFlags |= 0x100;
          break;

        case 0x08:
          CDSp->cds_table[r->DL].cdsFlags &= ~0x100;
          break;

        default:
          int2f_Remote_call(REM_DOREDIRECT, r->BX, r->CX, r->DX, (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX)));
          break;
      }
      break;

    case 0x60:                 /* TRUENAME */
      if ((rc = truename(MK_FP(r->DS, r->SI),
                      adjust_far(MK_FP(r->ES, r->DI)), TRUE)) != SUCCESS)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

#ifdef TSC
      /* UNDOCUMENTED: no-op                                          */
      /*                                                              */
      /* DOS-C: tsc support                                           */
    case 0x61:
#ifdef DEBUG
      switch (r->AL)
      {
        case 0x01:
          bTraceNext = TRUE;
          break;

        case 0x02:
          bDumpRegs = FALSE;
          break;
      }
#endif
      r->AL = 0x00;
      break;
#endif

      /* UNDOCUMENTED: return current psp                             */
    case 0x62:
      r->BX = cu_psp;
      break;

      /* UNDOCUMENTED: Double byte and korean tables                  */
    case 0x63:
      {
#ifdef DBLBYTE
        static char dbcsTable[2] =
        {
          0, 0
        };
        void FAR *dp = &dbcsTable;

        r->DS = FP_SEG(dp);
        r->SI = FP_OFF(dp);
        r->AL = 0;
#else
        /* not really supported, but will pass.                 */
        r->AL = 0x00;           /*jpp: according to interrupt list */
#endif
        break;
      }

      /* Extended country info                                        */
    case 0x65:
      if (r->AL <= 0x7)
      {
        if (ExtCtryInfo(
                         r->AL,
                         r->BX,
                         r->CX,
                         MK_FP(r->ES, r->DI)))
          r->FLAGS &= ~FLG_CARRY;
        else
          goto error_invalid;
      }
      else if ((r->AL >= 0x20) && (r->AL <= 0x22))
      {
        switch (r->AL)
        {
          case 0x20:
            r->DL = upChar(r->DL);
            goto okay;

          case 0x21:
            upMem(
                   MK_FP(r->DS, r->DX),
                   r->CX);
            goto okay;

          case 0x22:
            upString(MK_FP(r->DS, r->DX));
          okay:
            r->FLAGS &= ~FLG_CARRY;
            break;

          case 0x23:
            r->AX = yesNo(r->DL);
            goto okay;

          default:
            goto error_invalid;
        }
      }
      else
        r->FLAGS |= FLG_CARRY;
      break;

      /* Code Page functions */
    case 0x66:
      switch (r->AL)
      {
        case 1:
          GetGlblCodePage(
                           (UWORD FAR *) & (r->BX),
                           (UWORD FAR *) & (r->DX));
          goto okay_66;

        case 2:
          SetGlblCodePage(
                           (UWORD FAR *) & (r->BX),
                           (UWORD FAR *) & (r->DX));
        okay_66:
          r->FLAGS &= ~FLG_CARRY;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Set Max file handle count */
    case 0x67:
      if ((rc = SetJFTSize(r->BX)) != SUCCESS)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Flush file buffer -- dummy function right now.  */
    case 0x68:
      r->FLAGS &= ~FLG_CARRY;
      break;
  }

#ifdef DEBUG
  if (bDumpRegs)
  {
    fbcopy((VOID FAR *) user_r, (VOID FAR *) & error_regs,
           sizeof(iregs));
    dump_regs = TRUE;
    dump();
  }
#endif
}