📄 inthndlr.c
字号:
} goto exit_dispatch;long_check: if (lrc >= SUCCESS) { lr.AX = (UWORD)lrc; goto exit_dispatch; } rc = (int)lrc;short_check: if (rc < SUCCESS) goto error_exit; goto exit_dispatch;error_invalid: rc = DE_INVLDFUNC;error_exit: lr.AX = -rc; if (CritErrCode == SUCCESS) CritErrCode = lr.AX; /* Maybe set */error_carry: SET_CARRY_FLAG();exit_dispatch: fmemcpy(r, &lr, sizeof(lregs) - 4); r->DS = lr.DS; r->ES = lr.ES;real_exit:;#ifdef DEBUG if (bDumpRegs) { fmemcpy(&error_regs, user_r, sizeof(iregs)); dump_regs = TRUE; dump(); }#endif}#if 0 /* No kernel INT-23 handler required no longer -- 1999/04/15 ska *//* ctrl-Break handler */#pragma argsusedVOID INRPT FAR int23_handler(int es, int ds, int di, int si, int bp, int sp, int bx, int dx, int cx, int ax, int ip, int cs, int flags){ tsr = FALSE; return_mode = 1; return_code = -1; mod_sto(CTL_C); DosMemCheck();#ifdef TSC StartTrace();#endif return_user();}#endifstruct int25regs { UWORD es, ds; UWORD di, si, bp, sp; UWORD bx, dx, cx, ax; UWORD flags, ip, cs;};/* this function is called from an assembler wrapper function */VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r){ ULONG blkno; UWORD nblks; BYTE FAR *buf; UBYTE drv; if (mode == 0x26) mode = DSKWRITEINT26; else mode = DSKREADINT25; drv = r->ax; if (drv >= lastdrive) { r->ax = 0x201; SET_CARRY_FLAG(); return; }#ifdef WITHFAT32 { struct dpb FAR *dpbp = get_dpb(drv); if (dpbp != NULL && ISFAT32(dpbp)) { r->ax = 0x207; SET_CARRY_FLAG(); return; } }#endif nblks = r->cx; blkno = r->dx; buf = MK_FP(r->ds, r->bx); if (nblks == 0xFFFF) { /*struct HugeSectorBlock FAR *lb = MK_FP(r->ds, r->bx); */ blkno = ((struct HugeSectorBlock FAR *)buf)->blkno; nblks = ((struct HugeSectorBlock FAR *)buf)->nblks; buf = ((struct HugeSectorBlock FAR *)buf)->buf; } InDOS++; r->ax = dskxfer(drv, blkno, buf, nblks, mode); CLEAR_CARRY_FLAG(); if (r->ax != 0) { SET_CARRY_FLAG(); if (mode == DSKWRITEINT26) setinvld(drv); } --InDOS;}/*VOID int25_handler(struct int25regs FAR * r) { int2526_handler(DSKREAD,r); }VOID int26_handler(struct int25regs FAR * r) { int2526_handler(DSKWRITE,r); }*/#ifdef TSCSTATIC VOID StartTrace(VOID){ if (bTraceNext) {#ifdef DEBUG bDumpRegs = TRUE;#endif bTraceNext = FALSE; }#ifdef DEBUG else bDumpRegs = FALSE;#endif}#endif/* this function is called from an assembler wrapper function and serves the internal dos calls - int2f/12xx and int2f/4a01,4a02.*/struct int2f12regs {#ifdef I386#ifdef __WATCOMC__ /* UWORD gs, fs; ** GS/FS are protected through SI/DI */#else UWORD high_edx,#ifdef _MSC_VER high_ecx,#else /* __BORLANDC__ */ high_ebx,#endif high_eax;#endif#endif UWORD es, ds; UWORD di, si, bp; xreg b, d, c, a; UWORD ip, cs, flags; UWORD callerARG1; /* used if called from INT2F/12 */};/* WARNING: modifications in `r' are used outside of int2F_12_handler() * On input r.AX==0x12xx, 0x4A01 or 0x4A02 */VOID ASMCFUNC int2F_12_handler(struct int2f12regs r){ COUNT rc; long lrc; if (r.AH == 0x4a) { size_t size = 0, offs = 0xffff; r.ES = offs; if (FP_SEG(firstAvailableBuf) == offs) /* HMA present? */ { offs = FP_OFF(firstAvailableBuf); size = ~offs; /* BX for query HMA */ if (r.AL == 0x02) /* allocate HMA space */ { if (r.BX < size) size = r.BX; AllocateHMASpace(offs, offs+size); firstAvailableBuf += size; } } r.DI = offs; r.BX = size; return; } switch (r.AL) { case 0x00: /* installation check */ r.AL = 0xff; break; case 0x03: /* get DOS data segment */ r.DS = FP_SEG(&nul_dev); break; case 0x06: /* invoke critical error */ /* code, drive number, error, device header */ r.AL = CriticalError(r.callerARG1 >> 8, (r.callerARG1 & (EFLG_CHAR << 8)) ? 0 : r.callerARG1 & 0xff, r.DI, MK_FP(r.BP, r.SI)); break; case 0x08: /* decrease SFT reference count */ { sft FAR *p = MK_FP(r.ES, r.DI); r.AX = p->sft_count; if (--p->sft_count == 0) --p->sft_count; } break; case 0x0c: /* perform "device open" for device, set owner for FCB */ if (lpCurSft->sft_flags & SFT_FDEVICE) { request rq; rq.r_unit = 0; rq.r_status = 0; rq.r_command = C_OPEN; rq.r_length = sizeof(request); execrh((request FAR *) & rq, lpCurSft->sft_dev); } /* just do it always, not just for FCBs */ lpCurSft->sft_psp = cu_psp; break; case 0x0d: /* get dos date/time */ r.AX = dos_getdate(); r.DX = dos_gettime(); break; case 0x11: /* normalise ASCIIZ filename */ { char c; char FAR *s = MK_FP(r.DS, r.SI); char FAR *t = MK_FP(r.ES, r.DI); do { c = *s++; /* uppercase character */ /* for now, ASCII only because nls.c cannot handle DS!=SS */ if (c >= 'a' && c <= 'z') c -= 'a' - 'A'; else if (c == '/') c = '\\'; *t++ = c; } while (c); break; } case 0x12: /* get length of asciiz string */ r.CX = fstrlen(MK_FP(r.ES, r.DI)) + 1; break; case 0x13: /* uppercase character */ /* for now, ASCII only because nls.c cannot handle DS!=SS */ r.AL = (unsigned char)r.callerARG1; if (r.AL >= 'a' && r.AL <= 'z') r.AL -= 'a' - 'A'; break; case 0x16: /* get address of system file table entry - used by NET.EXE BX system file table entry number ( such as returned from 2F/1220) returns ES:DI pointer to SFT entry BX relative entry number within SFT */ { int rel_idx = idx_to_sft_(r.BX); if (rel_idx == -1) { r.FLAGS |= FLG_CARRY; break; } r.FLAGS &= ~FLG_CARRY; r.BX = rel_idx; r.ES = FP_SEG(lpCurSft); r.DI = FP_OFF(lpCurSft); break; } case 0x17: /* get current directory structure for drive - used by NET.EXE STACK: drive (0=A:,1=B,...) ; returns ; CF set if error ; DS:SI pointer to CDS for drive ; ; called like ; push 2 (c-drive) ; mov ax,1217 ; int 2f ; ; probable use: get sizeof(CDSentry) */ { struct cds FAR *cdsp = get_cds(r.callerARG1 & 0xff); if (cdsp == NULL) { r.FLAGS |= FLG_CARRY; break; } r.DS = FP_SEG(cdsp); r.SI = FP_OFF(cdsp); r.FLAGS &= ~FLG_CARRY; break; } case 0x18: /* get caller's registers */ r.DS = FP_SEG(user_r); r.SI = FP_OFF(user_r); break; case 0x1b: /* #days in February - valid until 2099. */ r.AL = (r.CL & 3) ? 28 : 29; break; case 0x20: /* get job file table entry */ { psp FAR *p = MK_FP(cu_psp, 0); unsigned char FAR *idx; if (r.BX >= p->ps_maxfiles) { r.AL = -DE_INVLDHNDL; r.FLAGS |= FLG_CARRY; break; } idx = &p->ps_filetab[r.BX]; r.FLAGS &= ~FLG_CARRY; r.ES = FP_SEG(idx); r.DI = FP_OFF(idx); } break; case 0x21: /* truename */ DosTruename(MK_FP(r.DS, r.SI), MK_FP(r.ES, r.DI)); break; case 0x23: /* check if character device */ { struct dhdr FAR *dhp; dhp = IsDevice((BYTE FAR *) DirEntBuffer.dir_name); if (dhp == NULL) { r.FLAGS |= FLG_CARRY; break; } r.BH = dhp->dh_attr; r.FLAGS &= ~FLG_CARRY; } break; case 0x25: /* get length of asciiz string */ r.CX = fstrlen(MK_FP(r.DS, r.SI)) + 1; break; case 0x26: /* open file */ r.FLAGS &= ~FLG_CARRY; CritErrCode = SUCCESS; lrc = DosOpen(MK_FP(r.DS, r.DX), O_LEGACY | O_OPEN | r.CL, 0); goto long_check; case 0x27: /* close file */ r.FLAGS &= ~FLG_CARRY; CritErrCode = SUCCESS; rc = DosClose(r.BX); goto short_check; case 0x28: /* move file pointer */ /* * RBIL says: "sets user stack frame pointer to dummy buffer, * moves BP to AX, performs LSEEK, and restores frame pointer" * We obviously don't do it like that. Does this do any harm?! --L.G. */ r.FLAGS &= ~FLG_CARRY; CritErrCode = SUCCESS; if (r.BP < 0x4200 || r.BP > 0x4202) goto error_invalid;#if 0 { sft FAR *s = get_sft(r.BX); if ((rc = _SftSeek(s, MK_ULONG(r.CX, r.DX), r.BP & 0xff)) >= SUCCESS) { r.DX = hiword (s->sft_posit); r.AX = loword (s->sft_posit); } } goto short_check;#else goto error_invalid;#endif case 0x29: /* read from file */ r.FLAGS &= ~FLG_CARRY; CritErrCode = SUCCESS; lrc = DosRead(r.BX, r.CX, MK_FP(r.DS, r.DX)); goto long_check; case 0x2a: /* Set FastOpen but does nothing. */ r.FLAGS &= ~FLG_CARRY; break; case 0x2c: /* added by James Tabor For Zip Drives Return Null Device Pointer */ /* by UDOS+RBIL: get header of SECOND device driver in device chain, omitting the NUL device TE */ r.BX = FP_SEG(nul_dev.dh_next); r.AX = FP_OFF(nul_dev.dh_next); break; case 0x2e: /* GET or SET error table addresse - ignored called by MS debug with DS != DOSDS, printf doesn't work!! */ break; case 0x2f: if (r.DX) { os_setver_major = r.DL; os_setver_minor = r.DH; } else { os_setver_major = os_major; os_setver_minor = os_minor; } break; default: if (r.AL <= 0x31) { put_string("unimplemented internal dos function INT2F/12"); put_unsigned(r.AL, 16, 2); put_string("\n"); r.FLAGS |= FLG_CARRY; } } return;long_check: if (lrc >= SUCCESS) { r.AX = (UWORD)lrc; return; } rc = (int)lrc;short_check: if (rc < SUCCESS) goto error_exit; return;error_invalid: rc = DE_INVLDFUNC;error_exit: r.AX = -rc; if (CritErrCode == SUCCESS) CritErrCode = r.AX; /* Maybe set */ r.FLAGS |= FLG_CARRY;}/* * 2000/09/04 Brian Reifsnyder * Modified interrupts 0x25 & 0x26 to return more accurate error codes. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -