📄 inthndlr.c
字号:
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.AL, &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: lr.SI = FcbParseFname(&lr.AL, MK_FP(lr.DS, lr.SI), FP_ES_DI); 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.BL = REVISION_SEQ; lr.CX = 0; /* do not set this to a serial number! 32RTM won't like non-zero values */ 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: lr.AX = DosGetFree(lr.DL, &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; /* Get Current Directory */ case 0x47: rc = DosGetCuDir(lr.DL, MK_FP(lr.DS, lr.SI)); lr.AX = 0x0100; /*jpp: from interrupt list */ goto short_check; /* Allocate memory */ case 0x48: if ((rc = DosMemAlloc(lr.BX, mem_access_mode, &lr.AX, &lr.BX)) < 0) { DosMemLargest(&lr.BX); if (DosMemCheck() != SUCCESS) panic("MCB chain corrupted"); goto error_exit; } lr.AX++; /* DosMemAlloc() returns seg of MCB rather than data */ break; /* Free memory */ case 0x49: if ((rc = DosMemFree(lr.ES - 1)) < SUCCESS) { if (DosMemCheck() != SUCCESS) panic("MCB chain corrupted"); goto error_exit; } break; /* Set memory block size */ case 0x4a: if (DosMemCheck() != SUCCESS) panic("before 4a: MCB chain corrupted"); if ((rc = DosMemChange(lr.ES, lr.BX, &lr.BX)) < 0) {#if 0 if (cu_psp == lr.ES) { psp FAR *p = MK_FP(cu_psp, 0); p->ps_size = lr.BX + cu_psp; }#endif if (DosMemCheck() != SUCCESS) panic("after 4a: MCB chain corrupted"); goto error_exit; } lr.AX = lr.ES; /* Undocumented MS-DOS behaviour expected by BRUN45! */ break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -