VOID mod_sto(REG UCOUNT c) { if (c < ' ' && c != HT) { sto('^'); sto(c + '@'); } else sto(c); }
int main () { // define constants const int nmin = 1; // set the lowest allowed number const int nmax = 36; // set the highest allowed number const int select = 6; // the number of numbers to draw int32 seed = time(0); // generate random seed StochasticLib1 sto(seed); // make instance of random library int urn[nmax-nmin+1]; // contains the shuffled numbers int i; // loop counter // Make shuffled list of numbers from nmin to nmax: sto.Shuffle(urn, nmin, nmax-nmin+1); // output heading text printf("Random numbers without duplicates:\n\n"); // loop to output the first "select" numbers for (i=0; i < select; i++) { if (i < nmax-nmin+1) { // output number printf("%4i ", urn[i]);}} EndOfProgram(); // system-specific exit code return 0;}
void execute() { switch ( ir.op) { //lit case 1: lit(ir.m); break; // opr will require another sub-function to decide // which operation to run case 2: opr(); break; //lod case 3: lod(ir.l, ir.m); break; //sto case 4: sto(ir.l, ir.m); break; //cal case 5: cal(ir.l, ir.m); break; //inc case 6: inc(ir.m); break; //jmp case 7: jmp(ir.m); break; //jpc case 8: jpc(ir.m); break; //sio //this will require another sub function to decide //which i/o to run case 9: sio(); break; default: fprintf(output, "OP code input was invalid. "); sio3(); } //print pc, bp, sp //use loop to print stack fprintf(output, "\t%d\t\t%d\t%d\t", pc, bp, sp); stackPrint(); }
void TestSax() { for (unsigned int i=0; i<TESTS; ++i) { util::StringStream ss(saxtests[i].xml); size_t len = ss.str().length(); for (size_t j=len; j; --j) { // TRACE << "j=" << j << "\n"; util::DribbleStream dribble(&ss, j); SaxTestObserver sto(saxtests[i].events); xml::SaxParser saxp(&sto); unsigned int rc = saxp.Parse(&dribble); assert(rc == 0); } } }
int main( ) { std::int64_t the_value = 100; SomeNonTrivialObject sto( &the_value ); raft::map m; source s( &sto ); sink t; m += s >> t; m.exe(); if( global_bool == true ) { return( EXIT_SUCCESS ); } else { return( EXIT_FAILURE ); } }
int main () { int seed = (int)time(0); // generate random seed StochasticLib1 sto(seed); // make instance of random library int deck[52]; // deck of 52 cards const char * ColorNames[] = { // names of 4 colors "clubs", "diamonds", "hearts", "spades" }; const char * ValueNames[] = { // names of 13 card values "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" }; int i; // loop counter int color; // card color int value; // card value // Make shuffled list of cards. // The 52 cards are numbered from 0 to 51, where 0 = A-clubs, 1 = A-diamonds, // 51 = K-spades: sto.Shuffle(deck, 0, 52); // output heading text printf("Shuffled deck of cards:\n\n"); // loop for all cards for (i = 0; i < 52; i++) { // translate card number into color and value color = deck[i] % 4; value = deck[i] / 4; // output card printf("%8s %2s ", ColorNames[color], ValueNames[value]); // make linefeed for every four cards if (i % 4 == 3) printf("\n"); } EndOfProgram(); // system-specific exit code return 0; }
forceinline bool SortMap<TaskView,STO,inc>::operator ()(int& i, int& j) const { return sto(tasks[i],tasks[j]); }
// main int main() { // parameters. You may change these int32 n = 10; // number of balls double p = 0.4; // probability int32 nn = 1000000; // number of samples // other variables double sum; // sum double ssum; // squaresum int32 min, max; // minimum, maximum double mean; // mean double var; // variance int32 i; // loop counter int32 x; // random variate const int DSIZE = 18; // size of array int32 dis[DSIZE] = {0}; // number of samples in each range int c; // index into dis list double f; // calculated function value double xme; // expected mean double xva; // expected variance double xsd; // expected standard deviation int32 delta; // step in list int32 xa; // list minimum int32 x1, x2; // category range // make random library int32 seed = time(0); // random seed StochasticLib1 sto(seed); // make instance of random library // calculate mean and variance xme = n*p; // calculated mean xva = n*p*(1-p); // calculated variance // calculate appropriate list divisions xsd = sqrt(xva); // calculated std.dev. xa = int(xme - 6.*xsd + 0.5); // calculated minimum if (xa < 0) xa=0; delta = int(12.*xsd/(DSIZE-1)); // list step if (delta < 1) delta = 1; // initialize sum = ssum = 0; min = 2000000000; max = -1; // start message printf("taking %li samples from binomial distribution...", nn); // sample nn times for (i=0; i < nn; i++) { // generate random number with desired distribution x = sto.Binomial(n,p); // update sums sum += x; ssum += (double)x*x; if (x < min) min = x; if (x > max) max = x; c = (x-xa)/delta; if (c < 0) c = 0; if (c >= DSIZE) c = DSIZE-1; dis[c]++;} // calculate sampled mean and variance mean = sum / nn; var = (ssum - sum*sum/nn) / nn; // print sampled and theoretical mean and variance printf("\n\nparameters: n=%li, p=%.3G", n, p); printf("\n mean variance"); printf("\nsampled: %12.6f %12.6f", mean, var); printf("\nexpected: %12.6f %12.6f", xme, xva); // print found and expected frequencies printf("\n\n x found expected"); for (c = 0; c < DSIZE; c++) { x1 = c*delta + xa; if (x1 > n) break; x2 = x1+delta-1; if (c==0 && min<x1) x1 = min; if (c==DSIZE-1 && max>x2) x2 = max; if (x2 > n) x2 = n; // calculate expected frequency for (x=x1, f=0.; x <= x2; x++) { f += exp(LnFac(n) - LnFac(x) - LnFac(n-x) + x*log(p) + (n-x)*log(1-p));} // output found and expected frequency if (dis[c] || f*nn > 1E-4) { if (x1==x2) { printf("\n%7li %12.6f %12.6f", x1, (double)dis[c]/nn, f);} else { printf("\n%6li-%-6li %12.6f %12.6f", x1, x2, (double)dis[c]/nn, f);}}} EndOfProgram(); // system-specific exit code return 0;}
// main int main() { // hypergeometric parameters. You may change these int32_t n = 600; // number of balls taken int32_t m = 400; // number of red balls int32_t N = 1000; // total number of balls double omega = 3; // odds int32_t nn = 100000; // number of samples // other variables double sum; // sum double ssum; // squaresum int32_t min, max; // minimum, maximum double mean; // mean double var; // variance int32_t i; // loop counter int32_t x; // random variable const int DSIZE = 18; // size of array int32_t dis[DSIZE] = {0}; // number of samples in each range int c; // index into dis list double f; // calculated function value double xme1; // expected mean (approximate) double xme2; // expected mean (exact) double xva; // expected variance double xsd; // expected standard deviation int32_t delta; // step size in list int32_t xa, xb; // list minimum, maximum int32_t x1, x2; // category range // make random seed int32_t seed = (int32_t)time(0); // random seed = time // make instance of random library for producing random variates StochasticLib3 sto(seed); // make object for calculating mean, variance and probabilities CWalleniusNCHypergeometric nchyp(n, m, N, omega, 1E-10f); // calculate approximate mean xme1 = nchyp.mean(); // calculate exact mean and variance, and check precision sum = nchyp.moments(&xme2, &xva); // printf("obtained precision %.4G\n", sum-1.); // calculate appropriate list divisions xsd = sqrt(xva); // std.deviation xa = int(xme2 - 6.*xsd + 0.5); // expected minimum if (xa < 0) xa=0; if (xa < n+m-N) xa = n+m-N; delta = int(12.*xsd/(DSIZE-1)); // list step if (delta < 1) delta=1; xb = xa + (DSIZE-1)*delta; // expected maximum if (xb > n) xb = n; if (xb > m) xb = m; // initialize sum = ssum = 0; min = 2000000000; max = -1; // start message printf("taking %li samples from Wallenius noncentral hypergeometric distribution...", nn); // sample nn times for (i = 0; i < nn; i++) { // generate random number with desired distribution x = sto.WalleniusNCHyp(n, m, N, omega); // update sums sum += x; ssum += (double)x*x; if (x < min) min = x; if (x > max) max = x; c = (x-xa)/delta; if (c < 0) c = 0; if (c >= DSIZE) c = DSIZE-1; dis[c]++; } // calculate sampled mean and variance mean = sum / nn; var = (ssum - sum*sum/nn) / nn; // print sampled and theoretical mean and variance printf("\n\nparameters: n=%li, m=%li, N=%li, odds=%.3G", n, m, N, omega); printf("\n mean variance"); printf("\nsampled: %12.6f %12.6f", mean, var); printf("\nexpected: %12.6f %12.6f", xme2, xva); // print found and expected frequencies printf("\n\n x found expected"); for (c = 0; c < DSIZE; c++) { x1 = c*delta + xa; if (x1 > xb) break; x2 = x1+delta-1; if (x2 > xb) x2 = xb; if (c==0 && min<x1) x1 = min; if (c==DSIZE-1 && max>x2) x2 = max; // calculate expected frequency for (x=x1, f=0.; x <= x2; x++) { f += nchyp.probability(x); } if (dis[c] || f*nn > 1E-4) { if (x1==x2) { printf("\n%7li %12.6f %12.6f", x1, (double)dis[c]/nn, f); } else { printf("\n%6li-%-6li %12.6f %12.6f", x1, x2, (double)dis[c]/nn, f); } } } EndOfProgram(); // system-specific exit code return 0; }
VOID destr_bs(void) { sto(BS); sto(' '); sto(BS); }
main () { FILE *fin = fopen ("packrec.in", "r"); FILE *fout = fopen ("packrec.out", "w"); int rw,rh,era,ret,m[4]={0}; int i,j,k; rect rt,rt2,a,b,c,d; for(i=0;i<4;i++){ fscanf (fin, "%d %d", &(frec[i].w),&(frec[i].h)); frec[i]=vrt(frec[i]); } for(i=0;i<16;i++){//A pose(i); rt.w=rt.h=0; for(k=0;k<4;k++){ rt=cnnt(rt,frec[k],1,0); } sto(rt); } for(i=0;i<16;i++){//B pose(i); for(j=0;j<24;j++){ rt.w=rt.h=0; rt=cnnt(rt,frec[pm[j][0]],1,0); rt=cnnt(rt,frec[pm[j][1]],1,0); rt=cnnt(rt,frec[pm[j][2]],1,0); rt=cnnt(rt,frec[pm[j][3]],0,0); sto(rt); } } for(i=0;i<16;i++){//C pose(i); for(j=0;j<24;j++){ rt.w=rt.h=0; rt=cnnt(rt,frec[pm[j][0]],1,0); rt=cnnt(rt,frec[pm[j][1]],1,0); rt=cnnt(rt,frec[pm[j][2]],0,0); rt=cnnt(rt,frec[pm[j][3]],1,0); sto(rt); } } for(i=0;i<16;i++){//D,E pose(i); for(j=0;j<24;j++){ rt.w=rt.h=0; rt=cnnt(rt,frec[pm[j][0]],1,0); rt=cnnt(rt,frec[pm[j][1]],0,0); rt=cnnt(rt,frec[pm[j][2]],1,0); rt=cnnt(rt,frec[pm[j][3]],1,0); sto(rt); } } for(i=0;i<16;i++){//F pose(i); for(j=0;j<24;j++){ rt.w=rt.h=rt2.w=rt2.h=0; rt=cnnt(rt,a=frec[pm[j][0]],1,0); rt=cnnt(rt,b=frec[pm[j][1]],0,0); rt2=cnnt(rt2,c=frec[pm[j][2]],1,0); rt2=cnnt(rt2,d=frec[pm[j][3]],0,0); rt=cnnt(rt,rt2,1,0); if(b.h<d.h&&c.w>d.w&&a.w<b.w) rt.w=max(b.w+d.w,a.w+c.w); sto(rt); } } /*//ver0.1 rw=0;rh=0;ret=0; for(i=0;i<4;i++){ fscanf (fin, "%d %d", &(frec[i].w),&(frec[i].h)); frec[i]=vrt(frec[i]); if (frec[i].w>frec[i].h){ swap(&(frec[i].w),&(frec[i].h)); } rw+=frec[i].h; } rh=rw; era=rw*rh; */ //type A /*//ver0.2 rt.w=rt.h=0; for(i=0;i<4;i++){ rt=cnnt(rt,frec[i],1,0); } sto(vrt(rt)); */ /*//ver0.1 rh=0; for(i=0;i<4;i++){ if(frec[i].h>rh)rh=frec[i].h; rw+=frec[i].w; } rt.w=rw;rt.h=rh; sto(rt); */ //type B /*//ver0.2 rt.w=rt.h=0; for(i=0;i<4;i++){ m[i]=1; for(j=0;j<4;j++){ if(!m[j])rt=cnnt(rt,frec[j],1,0); } sto(vrt(rt,hor(frec[i]))); m[i]=0; } */ /*//ver0.1 for(i=0;i<4;i++)m[i]=0; for(i=0;i<4;i++){ m[i]=1; rw=frec[i].h;rh=0;t=0; for(j=0;j<4;j++){ if(!m[j]){ t+=frec[j].w; if (frec[j].h>rh)rh=frec[j].h; } } rw=max(rw,t); rh+=frec[i].w; rt.w=rw;rt.h=rh; sto(rt); m[i]=0; } */ //type C /*//ver0.2 for(i=0;i<4;i++){ m[i]=1; for(j=0;j<4;j++){ if(!m[j]){ m[j]=1; rt.w=rt.h=0; for(k=0;k<4;k++){ if(!frec[k]){ rt=cnnt(rt,frec[k],1,0); } } rt=cnnt(rt,hor(frec[j]),0,0); rt=cnnt(rt,frec[i],1,0); sto(vrt(rt)); m[j]=0; } } m[i]=0; } */ /*//ver0.1 for(i=0;i<4;i++)m[i]=0; for(i=0;i<4;i++){ m[i]=1; for(j=0;j<4;j++){ if(!m[j]){ m[j]=1; rw=0;rh=0; for(k=0;k<4;k++){ if(!frec[k]){ if(frec[k].h>rh)rh=frec[k].h; rw+=frec[k].w; } } rh+=frec[j].w; rw=max(frec[j].h,rw); rw+=frec[i].w; rh=max(frec[i].h,rh); rt.w=rw;rt.h=rh; sto(rt); m[j]=0; } } m[i]=0; } */ //type D /*//ver0.2 for(i=0;i<4;i++){ m[i]=1; for(j=0;j<4;j++){ if(!m[j]){ m[j]=1; rt.w=rt.h=0; for(k=0;k<4;k++){ if(!frec[k]){ rt=cnnt(rt,frec[k],0,0); } } rt=cnnt(rt,hor(frec[j]),1,0); rt=cnnt(rt,frec[i],1,0); sto(vrt(rt)); m[j]=0; } } m[i]=0; } */ //type E same as D //type F qsort(bxs,sz,sizeof(rect),cmp); fprintf (fout, "%d\n", min); for(i=0;i<sz;i++){ fprintf (fout, "%d %d\n", bxs[i].w, bxs[i].h); } exit (0); }
void executeInstruction() { switch(ir.op) { case 1: lit(); break; case 2: opr(); break; case 3: lod(); break; case 4: sto(); break; case 5: cal(); break; case 6: inc(); break; case 7: jmp(); break; case 8: jpc(); break; case 9: sio(); default: break; } void opr() { switch ( ir.m) { //rtn case 0: ret(); break; //neg case 1: neg(); break; //add case 2: add(); break; //sub case 3: sub(); break; //mul case 4: mul(); break; //div case 5: divid(); break; //odd case 6: odd(); break; //mod case 7: mod(); break; //eql case 8: eql(); break; //neq case 9: neq(); break; //lss case 10: lss(); break; //leq case 11: leq(); break; //gtr case 12: gtr(); break; //geq case 13: geq(); break; default: fprintf(output, "OP code input was invalid. "); halt = 1; break; } } }
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 }
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 }