📄 inthndlr.c
字号:
lr.AL = 00;
goto error_carry;
/* DOS 7.0+ FAT32 extended functions */
case 0x73:
CLEAR_CARRY_FLAG();
CritErrCode = SUCCESS;
rc = int21_fat32(&lr);
goto short_check;
#endif
#ifdef WITHLFNAPI
/* FreeDOS LFN helper API functions */
case 0x74:
{
switch (lr.AL)
{
/* Allocate LFN inode */
case 0x01:
rc = lfn_allocate_inode();
break;
/* Free LFN inode */
case 0x02:
rc = lfn_free_inode(lr.BX);
break;
/* Setup LFN inode */
case 0x03:
rc = lfn_setup_inode(lr.BX, ((ULONG)lr.CX << 16) | lr.DX, ((ULONG)lr.SI << 16) | lr.DI);
break;
/* Create LFN entries */
case 0x04:
rc = lfn_create_entries(lr.BX, (lfn_inode_ptr)FP_DS_DX);
break;
/* Read next LFN */
case 0x05:
rc = lfn_dir_read(lr.BX, (lfn_inode_ptr)FP_DS_DX);
break;
/* Write SFN pointed by LFN inode */
case 0x06:
rc = lfn_dir_write(lr.BX);
break;
default:
goto error_invalid;
}
lr.AX = rc;
CLEAR_CARRY_FLAG();
goto short_check;
}
#endif
}
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 argsused
VOID 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();
}
#endif
struct 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 TSC
STATIC 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)
{
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 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;
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;
}
}
}
/*
* 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 + -