📄 inthndlr.c
字号:
DOS_07:
lr.AL = read_char_stdin(FALSE);
break;
/* Read Keyboard Without Echo */
case 0x08:
DOS_08:
lr.AL = read_char_stdin(TRUE);
break;
/* Display String */
case 0x09:
{
unsigned char c;
unsigned char FAR *bp = FP_DS_DX;
while ((c = *bp++) != '$')
write_char_stdout(c);
lr.AL = c;
}
break;
/* Buffered Keyboard Input */
case 0x0a:
DOS_0A:
read_line(get_sft_idx(STDIN), get_sft_idx(STDOUT), FP_DS_DX);
break;
/* Check Stdin Status */
case 0x0b:
lr.AL = 0xFF;
if (StdinBusy())
lr.AL = 0x00;
break;
/* Flush Buffer, Read Keyboard */
case 0x0c:
{
struct dhdr FAR *dev = sft_to_dev(get_sft(STDIN));
if (dev)
con_flush(&dev);
switch (lr.AL)
{
case 0x01: goto DOS_01;
case 0x06: goto DOS_06;
case 0x07: goto DOS_07;
case 0x08: goto DOS_08;
case 0x0a: goto DOS_0A;
}
lr.AL = 0x00;
break;
}
/* Reset Drive */
case 0x0d:
flush();
break;
/* Set Default Drive */
case 0x0e:
lr.AL = DosSelectDrv(lr.DL);
break;
case 0x0f:
lr.AL = FcbOpen(FP_DS_DX, O_FCB | O_LEGACY | O_OPEN | O_RDWR);
break;
case 0x10:
lr.AL = FcbClose(FP_DS_DX);
break;
case 0x11:
lr.AL = FcbFindFirstNext(FP_DS_DX, TRUE);
break;
case 0x12:
lr.AL = FcbFindFirstNext(FP_DS_DX, FALSE);
break;
case 0x13:
lr.AL = FcbDelete(FP_DS_DX);
break;
case 0x14:
/* FCB read */
lr.AL = FcbReadWrite(FP_DS_DX, 1, XFR_READ);
break;
case 0x15:
/* FCB write */
lr.AL = FcbReadWrite(FP_DS_DX, 1, XFR_WRITE);
break;
case 0x16:
lr.AL = FcbOpen(FP_DS_DX, O_FCB | O_LEGACY | O_CREAT | O_TRUNC | O_RDWR);
break;
case 0x17:
lr.AL = FcbRename(FP_DS_DX);
break;
default:
#ifdef DEBUG
printf("Unsupported INT21 AH = 0x%x, AL = 0x%x.\n", lr.AH, lr.AL);
#endif
/* Fall through. */
/* CP/M compatibility functions */
case 0x18:
case 0x1d:
case 0x1e:
case 0x20:
#ifndef TSC
case 0x61:
#endif
case 0x6b:
lr.AL = 0;
break;
/* Get Default Drive */
case 0x19:
lr.AL = default_drive;
break;
/* Set DTA */
case 0x1a:
dta = FP_DS_DX;
break;
/* Get Default Drive Data */
case 0x1b:
lr.DL = 0;
/* fall through */
/* Get Drive Data */
case 0x1c:
{
BYTE FAR *p;
p = FatGetDrvData(lr.DL, &lr.AX, &lr.CX, &lr.DX);
lr.DS = FP_SEG(p);
lr.BX = FP_OFF(p);
}
break;
/* Get default DPB */
/* case 0x1f: see case 0x32 */
/* Random read using FCB: fields not updated
(XFR_RANDOM should not be used here) */
case 0x21:
lr.AL = FcbRandomIO(FP_DS_DX, XFR_READ);
break;
/* Random write using FCB */
case 0x22:
lr.AL = FcbRandomIO(FP_DS_DX, XFR_WRITE);
break;
/* Get file size in records using FCB */
case 0x23:
lr.AL = FcbGetFileSize(FP_DS_DX);
break;
/* Set random record field in FCB */
case 0x24:
FcbSetRandom(FP_DS_DX);
break;
/* Set Interrupt Vector */
/* case 0x25: handled above (re-entrant) */
/* Dos Create New Psp */
case 0x26:
new_psp(lr.DX, r->CS);
break;
/* Read random record(s) using FCB */
case 0x27:
lr.AL = FcbRandomBlockIO(FP_DS_DX, &lr.CX, XFR_READ | XFR_FCB_RANDOM);
break;
/* Write random record(s) using FCB */
case 0x28:
lr.AL = FcbRandomBlockIO(FP_DS_DX, &lr.CX, XFR_WRITE | XFR_FCB_RANDOM);
break;
/* Parse File Name */
case 0x29:
rc = 0;
lr.SI = FcbParseFname(&rc, MK_FP(lr.DS, lr.SI), FP_ES_DI);
lr.AL = rc;
break;
/* Get Date */
case 0x2a:
lr.AL = DosGetDate((struct dosdate *)&lr.CX);
break;
/* Set Date */
case 0x2b:
lr.AL = DosSetDate ((struct dosdate*)&lr.CX) == SUCCESS ? 0 : 0xFF;
break;
/* Get Time */
case 0x2c:
DosGetTime((struct dostime *)&lr.CL);
break;
/* Set Time */
case 0x2d:
lr.AL = DosSetTime ((struct dostime*)&lr.CX) == SUCCESS ? 0 : 0xFF;
break;
/* Set verify flag */
case 0x2e:
verify_ena = lr.AL & 1;
break;
/* Get DTA */
case 0x2f:
lr.ES = FP_SEG(dta);
lr.BX = FP_OFF(dta);
break;
/* Get (editable) DOS Version */
case 0x30:
lr.AL = os_setver_major;
lr.AH = os_setver_minor;
lr.BH = OEM_ID;
lr.CH = REVISION_MAJOR; /* JPP */
lr.CL = REVISION_MINOR;
lr.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 */
{
lr.AL = retp[1];
lr.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 */
{
lr.AL = retp[4];
lr.AH = retp[3];
}
}
break;
/* Keep Program (Terminate and stay resident) */
case 0x31:
DosMemChange(cu_psp, lr.DX < 6 ? 6 : lr.DX, 0);
return_code = lr.AL | 0x300;
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 */
{
int drv = (lr.DL == 0 || lr.AH == 0x1f) ? default_drive : lr.DL - 1;
struct dpb FAR *dpb = get_dpb(drv);
if (dpb == NULL)
{
CritErrCode = -DE_INVLDDRV;
lr.AL = 0xFF;
break;
}
/* hazard: no error checking! */
flush_buffers(dpb->dpb_unit);
dpb->dpb_flags = M_CHANGED; /* force flush and reread of drive BPB/DPB */
#ifdef WITHFAT32
if (media_check(dpb) < 0 || ISFAT32(dpb))
#else
if (media_check(dpb) < 0)
#endif
{
lr.AL = 0xff;
CritErrCode = -DE_INVLDDRV;
break;
}
lr.DS = FP_SEG(dpb);
lr.BX = FP_OFF(dpb);
lr.AL = 0;
}
break;
/*
case 0x33:
see int21_syscall
*/
/* Get InDOS flag */
case 0x34:
lr.ES = FP_SEG(&InDOS);
lr.BX = FP_OFF(&InDOS);
break;
/* Get Interrupt Vector */
/* case 0x35: handled above (reentrant) */
/* Dos Get Disk Free Space */
case 0x36:
DosGetFree(lr.DL, &lr.AX, &lr.BX, &lr.CX, &lr.DX);
break;
/* Undocumented Get/Set Switchar */
case 0x37:
switch (lr.AL)
{
/* Get switch character */
case 0x00:
lr.DL = switchar;
lr.AL = 0x00;
break;
/* Set switch character */
case 0x01:
switchar = lr.DL;
lr.AL = 0x00;
break;
default:
goto error_invalid;
}
break;
/* Get/Set Country Info */
case 0x38:
{
UWORD cntry = lr.AL;
if (cntry == 0xff)
cntry = lr.BX;
if (0xffff == lr.DX)
{
/* Set Country Code */
rc = DosSetCountry(cntry);
}
else
{
if (cntry == 0)
cntry--;
/* Get Country Information */
rc = DosGetCountryInformation(cntry, FP_DS_DX);
if (rc >= SUCCESS)
{
/* HACK FIXME */
if (cntry == (UWORD) - 1)
cntry = 1;
/* END OF HACK */
lr.AX = lr.BX = cntry;
}
}
goto short_check;
}
/* Dos Create Directory */
case 0x39:
/* Dos Remove Directory */
case 0x3a:
rc = DosMkRmdir(FP_DS_DX, lr.AH);
goto short_check;
/* Dos Change Directory */
case 0x3b:
rc = DosChangeDir(FP_DS_DX);
goto short_check;
/* Dos Create File */
case 0x3c:
lrc = DosOpen(FP_DS_DX, O_LEGACY | O_RDWR | O_CREAT | O_TRUNC, lr.CL);
goto long_check;
/* Dos Open */
case 0x3d:
lrc = DosOpen(FP_DS_DX, O_LEGACY | O_OPEN | lr.AL, 0);
goto long_check;
/* Dos Close */
case 0x3e:
rc = DosClose(lr.BX);
goto short_check;
/* Dos Read */
case 0x3f:
lrc = DosRead(lr.BX, lr.CX, FP_DS_DX);
goto long_check;
/* Dos Write */
case 0x40:
lrc = DosWrite(lr.BX, lr.CX, FP_DS_DX);
goto long_check;
/* Dos Delete File */
case 0x41:
rc = DosDelete((BYTE FAR *) FP_DS_DX, D_ALL);
goto short_check;
/* Dos Seek */
case 0x42:
if (lr.AL > 2)
goto error_invalid;
lrc = DosSeek(lr.BX, (LONG)((((ULONG) (lr.CX)) << 16) | lr.DX), lr.AL);
if (lrc == -1)
{
lrc = DE_INVLDHNDL;
}
else
{
lr.DX = (UWORD)(lrc >> 16);
lrc = (UWORD) lrc;
}
goto long_check;
/* Get/Set File Attributes */
case 0x43:
switch (lr.AL)
{
case 0x00:
rc = DosGetFattr((BYTE FAR *) FP_DS_DX);
if (rc >= SUCCESS)
lr.CX = rc;
break;
case 0x01:
rc = DosSetFattr((BYTE FAR *) FP_DS_DX, lr.CX);
lr.AX = lr.CX;
break;
default:
goto error_invalid;
}
goto short_check;
/* Device I/O Control */
case 0x44:
rc = DosDevIOctl(&lr); /* can set critical error code! */
if (rc < SUCCESS)
{
lr.AX = -rc;
if (rc != DE_DEVICE && rc != DE_ACCESS)
CritErrCode = lr.AX;
goto error_carry;
}
break;
/* Duplicate File Handle */
case 0x45:
lrc = DosDup(lr.BX);
goto long_check;
/* Force Duplicate File Handle */
case 0x46:
rc = DosForceDup(lr.BX, lr.CX);
goto short_check;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -