📄 inthndlr.c
字号:
/****************************************************************/
/* */
/* inthndlr.c */
/* */
/* Interrupt Handler and Function dispatcher for Kernel */
/* */
/* Copyright (c) 1995 */
/* Pasquale J. Villani */
/* All Rights Reserved */
/* */
/* This file is part of DOS-C. */
/* */
/* DOS-C is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License */
/* as published by the Free Software Foundation; either version */
/* 2, or (at your option) any later version. */
/* */
/* DOS-C is distributed in the hope that it will be useful, but */
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
/* the GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public */
/* License along with DOS-C; see the file COPYING. If not, */
/* write to the Free Software Foundation, 675 Mass Ave, */
/* Cambridge, MA 02139, USA. */
/* */
/****************************************************************/
#include "../../hdr/portab.h"
#include "globals.h"
#ifdef VERSION_STRINGS
BYTE *RcsId = "$Header: C:/dos-c/src/kernel/inthndlr.c_v 1.13 07 Feb 1998 20:38:46 patv $";
#endif
/* $Log: C:/dos-c/src/kernel/inthndlr.c_v $
*
* Rev 1.13 07 Feb 1998 20:38:46 patv
* Modified stack fram to match DOS standard
*
* Rev 1.12 22 Jan 1998 4:09:26 patv
* Fixed pointer problems affecting SDA
*
* Rev 1.11 06 Jan 1998 20:13:18 patv
* Broke apart int21_system from int21_handler.
*
* Rev 1.10 04 Jan 1998 23:15:22 patv
* Changed Log for strip utility
*
* Rev 1.9 04 Jan 1998 17:26:16 patv
* Corrected subdirectory bug
*
* Rev 1.8 03 Jan 1998 8:36:48 patv
* Converted data area to SDA format
*
* Rev 1.7 01 Aug 1997 2:00:10 patv
* COMPATIBILITY: Added return '$' in AL for function int 21h fn 09h
*
* Rev 1.6 06 Feb 1997 19:05:54 patv
* Added hooks for tsc command
*
* Rev 1.5 22 Jan 1997 13:18:32 patv
* pre-0.92 Svante Frey bug fixes.
*
* Rev 1.4 16 Jan 1997 12:46:46 patv
* pre-Release 0.92 feature additions
*
* Rev 1.3 29 May 1996 21:03:40 patv
* bug fixes for v0.91a
*
* Rev 1.2 19 Feb 1996 3:21:48 patv
* Added NLS, int2f and config.sys processing
*
* Rev 1.1 01 Sep 1995 17:54:20 patv
* First GPL release.
*
* Rev 1.0 02 Jul 1995 8:33:34 patv
* Initial revision.
*/
/* $EndLog$ */
#ifdef TSC
static VOID StartTrace(VOID);
static bTraceNext = FALSE;
#endif
extern UWORD Int21AX;
/* Special entry for far call into the kernel */
#pragma argsused
VOID FAR
int21_entry (iregs UserRegs)
{
int21_handler(UserRegs);
}
/* Convert an interrupt into our register struct definition */
VOID
int21_syscall(iregs FAR *irp)
{
static COUNT FAR *stack;
enable();
if (irp -> AH > 0x67)
{
irp -> AL = 0;
return;
}
Int21AX = irp -> AX;
switch(irp -> AH)
{
/* DosVars - get/set dos variables */
case 0x33:
switch(irp -> AL)
{
/* Get Ctrl-C flag */
case 0x00:
irp -> DL = break_ena ? TRUE : FALSE;
break;
/* Set Ctrl-C flag */
case 0x01:
break_ena = irp -> DL ? TRUE : FALSE;
break;
/* Get Boot Drive */
case 0x05:
irp -> DL = BootDrive;
break;
/* Get DOS-C version */
case 0x06:
irp -> BL = os_major;
irp -> BH = os_minor;
irp -> DL = rev_number;
irp -> DH = version_flags;
break;
default:
irp -> AX = -DE_INVLDFUNC;
irp -> FLAGS |= FLG_CARRY;
break;
/* Toggle DOS-C rdwrblock trace dump */
case 0xfd:
bDumpRdWrParms = !bDumpRdWrParms;
break;
/* Toggle DOS-C syscall trace dump */
case 0xfe:
bDumpRegs = !bDumpRegs;
break;
/* Get DOS-C release string pointer */
case 0xff:
irp -> DX = FP_SEG(os_release);
irp -> AX = FP_OFF(os_release);
break;
}
break;
/* Set PSP */
case 0x50:
cu_psp = irp -> BX;
break;
/* Get PSP */
case 0x51:
irp -> BX = cu_psp;
break;
/* UNDOCUMENTED: return current psp */
case 0x62:
irp -> BX = cu_psp;
break;
/* Normal DOS function - switch stacks */
default:
++InDOS;
user_r = irp;
stack = irp -> AH < 0x0c ? &char_api_tos : &disk_api_tos;
/* Initialize stacks */
api_sp = FP_OFF(stack);
api_ss = FP_SEG(stack);
set_stack();
int21_service(user_r);
restore_stack();
--InDOS;
}
}
VOID int21_service(iregs far *r)
{
COUNT rc, rc1;
ULONG lrc;
psp FAR *p = MK_FP(cu_psp, 0);
p -> ps_stack = r;
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();
}
/* The dispatch handler */
switch(r -> AH)
{
/* int 21h common error handler */
case 0x64:
case 0x6b:
error_invalid:
r -> AX = -DE_INVLDFUNC;
goto error_out;
error_exit:
r -> AX = -rc;
error_out:
r -> FLAGS |= FLG_CARRY;
break;
/* Terminate Program */
case 0x00:
tsr = FALSE;
return_mode = break_flg ? 1 : 0;
return_code = r -> AL;
DosMemCheck();
#ifdef TSC
StartTrace();
#endif
return_user();
break;
/* Read Keyboard with Echo */
case 0x01:
r -> AL = DosCharInputEcho();
break;
/* Display Character */
case 0x02:
DosDisplayOutput(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:
DosDirectConsoleIO(r);
break;
/* Direct Console Input */
case 0x07:
r -> AL = DosCharInput();
break;
/* Read Keyboard Without Echo */
case 0x08:
r -> AL = _sti();
break;
/* Display String */
case 0x09:
DosOutputString(MK_FP(r -> DS, r -> DX));
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 Keyboard Status */
case 0x0b:
if(KbdBusy())
r -> AL = 0x00;
else
r -> AL = 0xff;
break;
/* Flush Buffer, Read Keayboard */
case 0x0c:
KbdFlush();
switch(r -> AL)
{
/* Read Keyboard with Echo */
case 0x01:
r -> AL = DosCharInputEcho();
break;
/* Direct Cosole I/O */
case 0x06:
DosDirectConsoleIO(r);
break;
/* Direct Console Input */
case 0x07:
r -> AL = DosCharInput();
break;
/* Read Keyboard Without Echo */
case 0x08:
r -> AL = _sti();
break;
/* Buffered Keyboard Input */
case 0x0a:
sti((keyboard FAR *)MK_FP(r -> DS, r -> DX));
break;
default:
r -> AL = 0x00;
break;
}
break;
/* Reset Drive */
case 0x0d:
flush();
break;
/* Set Default Drive */
case 0x0e:
if(((COUNT)r -> DL) >= 0 && r -> DL < nblkdev)
default_drive = r -> DL;
r -> AL = nblkdev;
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
default:
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 < nblkdev)
{
struct dpb FAR *dpb = &blk_devices[default_drive];
r -> DS = FP_SEG(dpb);
r -> BX = FP_OFF(dpb);
r -> AL = 0;
}
else r -> AL = 0xff;
break;
case 0x21:
{
COUNT nErrorCode;
if(FcbRandomRead(MK_FP(r -> DS, r -> DX), &nErrorCode))
r -> AL = 0;
else
r -> AL = nErrorCode;
break;
}
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 */
case 0x23:
if(FcbGetFileSize(MK_FP(r -> DS, r -> DX)))
r -> AL = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -