/****************************************************************/
/* */
/* 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: D:/dos-c/src/kernel/inthndlr.c_v 1.3 29 May 1996 21:03:40 patv $";
#endif
/*
* $Log: D:/dos-c/src/kernel/inthndlr.c_v $
*
* 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.
*/
int DosMktmp(BYTE FAR *pathname, UWORD attr);
/* Terminate the current process */
#pragma argsused
VOID INRPT far
int20_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;
InDOS++;
DosMemCheck();
return_user();
}
/* Convert an interrupt into our register struct definition */
VOID INRPT far
int21_handler (iregs UserRegs)
{
static COUNT FAR *stack;
++InDOS;
user_r = (iregs far *)&UserRegs;
stack = user_r -> 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;
}
/* Special entry for far call into the kernel */
#pragma argsused
VOID FAR
int21_entry (iregs UserRegs)
{
int21_handler(UserRegs);
}
VOID int21_service(iregs far *r)
{
COUNT rc, rc1;
ULONG lrc;
BYTE FAR *xp;
/* The dispatch handler */
#ifdef DEBUG
if(bDumpRegs)
{
fbcopy((VOID FAR *)r, (VOID FAR *)&error_regs, sizeof(iregs));
printf("System call (21h): %02x\n", r -> AX);
dump_regs = TRUE;
dump();
}
#endif
switch(r -> AH)
{
/* print unused and fall into terminate (debug only) */
#ifdef DEBUG
fbcopy((VOID FAR *)r, (VOID FAR *)&error_regs, sizeof(iregs));
printf("Invalid system call (21h)\n");
dump_regs = TRUE;
dump();
# ifdef KDB
break;
# endif
#else
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
break;
#endif
/* Terminate Program */
case 0x00:
tsr = FALSE;
return_mode = break_flg ? 1 : 0;
return_code = r -> AL;
DosMemCheck();
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));
break;
/* Buffered Keyboard Input */
case 0x0a:
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:
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:
r -> AH = 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;
else
r -> AL = 0xff;
break;
case 0x24:
FcbSetRandom(MK_FP(r -> DS, r -> DX));
break;
/* Set Interrupt Vector */
case 0x25:
{
VOID (INRPT FAR *p)() = MK_FP(r -> DS, r -> DX);
setvec(r -> AL, p);
}
break;
/* Dos Create New Psp */
case 0x26:
{
psp FAR *p = MK_FP(cu_psp, 0);
new_psp((psp FAR *)MK_FP(r -> DX, 0), p -> ps_size);
}
break;
case 0x27:
{
COUNT nErrorCode;
if(FcbRandomBlockRead(MK_FP(r -> DS, r -> DX), r -> CX, &nErrorCode))
r -> AL = 0;
else
r -> AL = nErrorCode;
break;
}
case 0x28:
{
COUNT nErrorCode;
if(FcbRandomBlockWrite(MK_FP(r -> DS, r -> DX), r -> CX, &nErrorCode))
r -> AL = 0;
else
r -> AL = nErrorCode;
break;
}
/* Parse File Name */
case 0x29:
{
BYTE FAR *lpFileName;
lpFileName = MK_FP(r -> DS, r -> SI);
r -> AL = FcbParseFname(r -> AL,
&lpFileName,
MK_FP(r -> ES, r -> DI));
r -> DS = FP_SEG(lpFileName);
r -> SI = FP_OFF(lpFileName);
}
break;
/* Get Date */
case 0x2a:
DosGetDate(
(BYTE FAR *)&(r -> AL), /* WeekDay */
(BYTE FAR *)&(r -> DH), /* Month */
(BYTE FAR *)&(r -> DL), /* MonthDay */
(COUNT FAR *)&(r -> CX)); /* Year */
break;
/* Set Date */
case 0x2b:
rc = DosSetDate(
(BYTE FAR *)&(r -> DH), /* Month */
(BYTE FAR *)&(r -> DL), /* MonthDay */
(COUNT FAR *)&(r -> CX)); /* Year */
if(rc != SUCCESS)
r -> AL = 0xff;
else
r -> AL = 0;
break;
/* Get Time */
case 0x2c:
DosGetTime(
(BYTE FAR *)&(r -> CH), /* Hour */
(BYTE FAR *)&(r -> CL), /* Minutes */
(BYTE FAR *)&(r -> DH), /* Seconds */
(BYTE FAR *)&(r -> DL)); /* Hundredths */
break;
/* Set Date */
case 0x2d:
rc = DosSetTime(
(BYTE FAR *)&(r -> CH), /* Hour */
(BYTE FAR *)&(r -> CL), /* Minutes */
(BYTE FAR *)&(r -> DH), /* Seconds */
(BYTE FAR *)&(r -> DL)); /* Hundredths */
if(rc != SUCCESS)
r -> AL = 0xff;
else
r -> AL = 0;
break;
/* Set verify flag */
case 0x2e:
verify_ena = (r -> AL ? TRUE : FALSE);
break;
/* Get DTA */
case 0x2f:
r -> ES = FP_SEG(dta);
r -> BX = FP_OFF(dta);
break;
/* Get DOS Version */
case 0x30:
r -> AL = os_major;
r -> AH = os_minor;
switch(r -> AL)
{
default:
case 0:
r -> BH= OEM_ID;
break;
case 1:
r -> BH = 0; /* RAM only for now */
break;
}
r -> BL = 0xff; /* for now */
r -> CX = 0xffff;
break;
/* Keep Program */
case 0x31:
DosMemChange(cu_psp, r -> DX < 6 ? 6 : r -> DX, 0);
flush();
tsr = TRUE;
return_user();
break;
/* Get DPB */
case 0x32:
r -> AH = 0xff;
break;
/* DosVars - get/set dos variables */
case 0x33:
switch((r -> AL) & 0xff)
{
/* Get Ctrl-C flag */
case 0x00:
r -> DL = (break_ena ? TRUE : FALSE);
break;
/* Set Ctrl-C flag */
case 0x01:
break_ena = (r -> DL ? TRUE : FALSE);
break;
/* Get Boot Drive */
case 0x05:
r -> DL = BootDrive;
break;
/* Get DOS-C version */
case 0x06:
r -> BL = os_major;
r -> BH = os_minor;
r -> DL = rev_number;
r -> DH = version_flags;
break;
default:
r -> AX = -DE_INVLDFUNC;
r -> FLAGS |= FLG_CARRY;
break;
#ifdef DEBUG
/* Toggle DOS-C rdwrblock trace dump */
case 0xfd:
bDumpRdWrParms = !bDumpRdWrParms;
break;
/* Toggle DOS-C syscall trace dump */
case 0xfe:
bDumpRegs = !bDumpRegs;
break;
#endif
/* Get DOS-C release string pointer */
case 0xff:
r -> DX = FP_SEG(os_release);
r -> AX = FP_OFF(os_release);
break;
}
break;
/* Get InDOS flag */
case 0x34:
{
BYTE FAR *p;
p = (BYTE FAR *)((BYTE *)&InDOS);
r -> ES = FP_SEG(p);
r -> BX = FP_OFF(p);
}
break;
/* Get Interrupt Vector */
case 0x35:
{
BYTE FAR *p;
p = getvec((COUNT)r -> AL);
r -> ES = FP_SEG(p);
r -> BX = FP_OFF(p);
}
break;
/* Dos Get Disk Free Space */
case 0x36:
DosGetFree(
(COUNT)r -> DL,
(COUNT FAR *)&r -> AX,
(COUNT FAR *)&r -> BX,
(COUNT FAR *)&r -> CX,
(COUNT FAR *)&r -> DX);
break;
/* Undocumented Get/Set Switchar */
case 0x37:
switch(r -> AL)
{
case 0:
r -> DL = switchar;
break;
case 1:
switchar = r -> DL;
break;
case 2:
case 3:
r -> DL = 0xff;
break;
default:
r -> AX = -DE_INVLDFUNC;
r -> FLAGS |= FLG_CARRY;
break;
}
break;
/* Get/Set Country Info */
case 0x38:
{
BYTE FAR *lpTable
= (BYTE FAR *)MK_FP(r -> DS, r -> DX);
BYTE nRetCode;
if(0xffff == r -> DX)
{
r -> BX = SetCtryInfo(
(UBYTE FAR *)&(r -> AL),
(UWORD FAR *)&(r -> BX),
(BYTE FAR *)&lpTable,
(UBYTE *)&nRetCode);
if(nRetCode != 0)
{
r -> AX = 0xff;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> AX = nRetCode;
r -> FLAGS &= ~FLG_CARRY;
}
}
else
{
r -> BX = GetCtryInfo(&(r -> AL), &(r -> BX), lpTable);
r -> DS = FP_SEG(lpTable);
r -> DX = FP_OFF(lpTable);
r -> FLAGS &= ~FLG_CARRY;
}
}
break;
/* Dos Create Directory */
case 0x39:
rc = dos_mkdir((BYTE FAR *)MK_FP(r -> DS, r -> DX));
if(rc != SUCCESS)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
}
break;
/* Dos Remove Directory */
case 0x3a:
rc = dos_rmdir((BYTE FAR *)MK_FP(r -> DS, r -> DX));
if(rc != SUCCESS)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
}
break;
/* Dos Change Directory */
case 0x3b:
xp = MK_FP( r -> DS, r -> DX);
if((rc = DosChangeDir((BYTE FAR *)MK_FP(r -> DS, r -> DX))) < 0)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
}
break;
/* Dos Create File */
case 0x3c:
if((rc = DosCreat(MK_FP(r -> DS, r -> DX), r -> CX)) < 0)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> AX = rc;
r -> FLAGS &= ~FLG_CARRY;
}
break;
/* Dos Open */
case 0x3d:
if((rc = DosOpen(MK_FP(r -> DS, r -> DX), r -> AL)) < 0)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> AX = rc;
r -> FLAGS &= ~FLG_CARRY;
}
break;
/* Dos Close */
case 0x3e:
if((rc = DosClose(r -> BX)) < 0)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
r -> FLAGS &= ~FLG_CARRY;
break;
/* Dos Read */
case 0x3f:
rc = DosRead(r -> BX, r -> CX, MK_FP(r -> DS, r -> DX), (COUNT FAR *)&rc1);
if(rc1 != SUCCESS)
{
r -> FLAGS |= FLG_CARRY;
r -> AX = -rc1;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
r -> AX = rc;
}
break;
/* Dos Write */
case 0x40:
rc = DosWrite(r -> BX, r -> CX, MK_FP(r -> DS, r -> DX), (COUNT FAR *)&rc1);
if(rc1 != SUCCESS)
{
r -> FLAGS |= FLG_CARRY;
r -> AX = -rc1;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
r -> AX = rc;
}
break;
/* Dos Delete File */
case 0x41:
rc = dos_delete((BYTE FAR *)MK_FP(r -> DS, r -> DX));
if(rc < 0)
{
r -> FLAGS |= FLG_CARRY;
r -> AX = -rc1;
}
else
r -> FLAGS &= ~FLG_CARRY;
break;
/* Dos Seek */
case 0x42:
if((rc = DosSeek(r -> BX, (LONG)((((LONG)(r -> CX)) << 16) + r -> DX), r -> AL, &lrc)) < 0)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> DX = (lrc >> 16);
r -> AX = lrc & 0xffff;
r -> FLAGS &= ~FLG_CARRY;
}
break;
/* Get/Set File Attributes */
case 0x43:
switch(r -> AL)
{
case 0x00:
rc = DosGetFattr((BYTE FAR *)MK_FP(r -> DS, r -> DX), (UWORD FAR *)&r -> CX);
if(rc < SUCCESS)
{
r -> FLAGS |= FLG_CARRY;
r -> AX = -rc;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
}
break;
case 0x01:
rc = DosSetFattr((BYTE FAR *)MK_FP(r -> DS, r -> DX), (UWORD FAR *)&r -> CX);
if(rc != SUCCESS)
{
r -> FLAGS |= FLG_CARRY;
r -> AX = -rc;
}
else
r -> FLAGS &= ~FLG_CARRY;
break;
default:
r -> AX = -DE_INVLDFUNC;
r -> FLAGS |= FLG_CARRY;
break;
}
break;
/* Device I/O Control */
case 0x44:
{
BOOL bNoChangeAx;
bNoChangeAx = ((r -> AL == 0) || (r -> AL == 1));
rc = DosDevIOctl(r, (COUNT FAR *)&rc1);
if(rc1 != SUCCESS)
{
r -> FLAGS |= FLG_CARRY;
r -> AX = -rc1;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
if(!bNoChangeAx)
r -> AX = rc;
}
}
break;
/* Duplicate File Handle */
case 0x45:
rc = DosDup(r -> BX);
if(rc < SUCCESS)
{
r -> FLAGS |= FLG_CARRY;
r -> AX = -rc;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
r -> AX = rc;
}
break;
/* Force Duplicate File Handle */
case 0x46:
rc = DosForceDup(r -> BX, r -> CX);
if(rc < SUCCESS)
{
r -> FLAGS |= FLG_CARRY;
r -> AX = -rc;
}
else
r -> FLAGS &= ~FLG_CARRY;
break;
/* Get Current Directory */
case 0x47:
if((rc = DosGetCuDir(r -> DL, MK_FP(r -> DS, r -> SI))) < 0)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
}
break;
/* Memory management */
case 0x48:
if((rc = DosMemAlloc(r -> BX, mem_access_mode, &(r -> AX), &(r -> BX))) < 0)
{
DosMemLargest(&(r -> BX));
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
++(r -> AX);
r -> FLAGS &= ~FLG_CARRY;
}
break;
case 0x49:
if((rc = DosMemFree(--(r -> ES))) < 0)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
r -> FLAGS &= ~FLG_CARRY;
break;
case 0x4a:
{
UWORD maxSize;
if((rc = DosMemChange(r -> ES, r -> BX, &maxSize)) < 0)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
if (rc == DE_NOMEM)
r -> BX = maxSize;
#if 0
if(cu_psp == r -> ES)
{
psp FAR *p;
p = MK_FP(cu_psp, 0);
p -> ps_size = r -> BX + cu_psp;
}
#endif
}
else
r -> FLAGS &= ~FLG_CARRY;
break;
}
/* Load and Execute Program */
case 0x4b:
break_flg = FALSE;
if((rc = DosExec(r -> AL, MK_FP(r -> ES, r -> BX), MK_FP(r -> DS, r -> DX)))
!= SUCCESS)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
r -> FLAGS &= ~FLG_CARRY;
break;
/* End Program */
case 0x4c:
tsr = FALSE;
return_mode = break_flg ? 1 : 0;
return_code = r -> AL;
DosMemCheck();
return_user();
break;
/* Get Child-program Return Value */
case 0x4d:
r -> AL = return_code;
r -> AH = return_mode;
break;
/* Dos Find First */
case 0x4e:
{
psp FAR *p = MK_FP(cu_psp,0);
BYTE FAR *xp = MK_FP(r -> DS, r -> DX);
/* dta for this call is set on entry. This */
/* needs to be changed for new versions. */
if((rc = DosFindFirst((UCOUNT)r -> CX, (BYTE FAR *)MK_FP(r -> DS, r -> DX))) < 0)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> AX = 0;
r -> FLAGS &= ~FLG_CARRY;
}
}
break;
/* Dos Find Next */
case 0x4f:
{
psp FAR *p = MK_FP(cu_psp,0);
/* dta for this call is set on entry. This */
/* needs to be changed for new versions. */
if((rc = DosFindNext()) < 0)
{
r -> AX = -rc;
if (r -> AX == 2)
r -> AX = 18;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
}
}
break;
/* Set PSP */
case 0x50:
cu_psp = r -> BX;
break;
/* Get PSP */
case 0x51:
r -> BX = cu_psp;
break;
/* ************UNDOCUMENTED**************************************/
/* Get List of Lists */
case 0x52:
{
BYTE FAR *p;
p = (BYTE FAR *)&DPBp;
r -> ES = FP_SEG(p);
r -> BX = FP_OFF(p);
}
break;
/* Get verify state */
case 0x54:
r -> AL = (verify_ena ? TRUE : FALSE);
break;
/* ************UNDOCUMENTED**************************************/
/* Dos Create New Psp & set p_size */
case 0x55:
new_psp((psp FAR *)MK_FP(r -> DX, 0), r -> SI);
break;
/* Dos Rename */
case 0x56:
rc = dos_rename(
(BYTE FAR *)MK_FP(r -> DS, r -> DX), /* OldName */
(BYTE FAR *)MK_FP(r -> ES, r -> DI)); /* NewName */
if(rc != SUCCESS)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
}
break;
/* Get/Set File Date and Time */
case 0x57:
switch(r -> AL)
{
case 0x00:
if(!DosGetFtime(
(COUNT)r -> BX, /* Handle */
(date FAR *)&r -> DX, /* FileDate */
(time FAR *)&r -> CX)) /* FileTime */
{
r -> AX = -DE_INVLDHNDL;
r -> FLAGS |= FLG_CARRY;
}
else
r -> FLAGS &= ~FLG_CARRY;
break;
case 0x01:
if(!DosSetFtime(
(COUNT)r -> BX, /* Handle */
(date FAR *)&r -> DX, /* FileDate */
(time FAR *)&r -> CX)) /* FileTime */
{
r -> AX = -DE_INVLDHNDL;
r -> FLAGS |= FLG_CARRY;
}
else
r -> FLAGS &= ~FLG_CARRY;
break;
default:
r -> AX = -DE_INVLDFUNC;
r -> FLAGS |= FLG_CARRY;
break;
}
break;
/* Get/Set Allocation Strategy */
case 0x58:
switch(r -> AL)
{
case 0x00:
r -> AX = mem_access_mode;
break;
case 0x01:
if(((COUNT)r -> BX) < 0 || r -> BX > 2)
{
r -> AX = -DE_INVLDFUNC;
r -> FLAGS |= FLG_CARRY;
}
else
{
mem_access_mode = r -> BX;
r -> FLAGS &= ~FLG_CARRY;
}
break;
default:
r -> AX = -DE_INVLDFUNC;
r -> FLAGS |= FLG_CARRY;
break;
#ifdef DEBUG
case 0xff:
show_chain();
break;
#endif
}
break;
case 0x5a:
if((rc = DosMkTmp(MK_FP(r -> DS, r -> DX), r -> CX)) < 0)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> AX = rc;
r -> FLAGS &= ~FLG_CARRY;
}
break;
case 0x5b:
if((rc = DosOpen(MK_FP(r -> DS, r -> DX), 0)) >= 0)
{
DosClose(rc);
r -> AX = 80;
r -> FLAGS |= FLG_CARRY;
}
else
{
if((rc = DosCreat(MK_FP(r -> DS, r -> DX), r -> CX)) < 0)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> AX = rc;
r -> FLAGS &= ~FLG_CARRY;
}
}
break;
/* UNDOCUMENTED: share.exe and sda function */
/* not really supported, but will pass. */
case 0x5d:
r -> AX = -DE_INVLDFUNC;
r -> FLAGS |= FLG_CARRY;
break;
case 0x60: /* TRUENAME */
if ((rc = truename(MK_FP(r -> DS, r-> SI), MK_FP( r -> ES, r -> DI))) != SUCCESS)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
}
break;
/* UNDOCUMENTED: no-op */
case 0x61:
break;
/* UNDOCUMENTED: return current psp */
case 0x62:
r -> BX = cu_psp;
break;
/* UNDOCUMENTED: Double byte and korean tables */
/* not really supported, but will pass. */
case 0x63:
{
#ifdef DBLBYTE
void FAR *dp = dbcsTable;
r -> DS = FP_SEG(dp);
r -> SI = FP_OFF(dp);
r -> AL = 0;
#else
r -> AL = 0xff;
#endif
break;
}
case 0x64:
r -> FLAGS &= ~FLG_CARRY;
break;
/* Extended country info */
case 0x65:
if(r -> AL <= 0x7)
{
if(ExtCtryInfo(
r -> AL,
r -> BX,
r -> CX,
MK_FP(r -> ES, r -> DI)))
r -> FLAGS &= ~FLG_CARRY;
else
{
r -> AX = -DE_INVLDFUNC;
r -> FLAGS |= FLG_CARRY;
}
}
else if((r -> AL >= 0x20) && (r -> AL <= 0x22))
{
switch(r -> AL)
{
case 0x20:
r -> DL = upChar(r -> DL);
goto okay;
case 0x21:
upMem(
MK_FP(r -> DS, r -> DX),
r -> CX);
goto okay;
case 0x22:
upString(MK_FP(r -> DS, r -> DX));
okay:
r -> FLAGS &= ~FLG_CARRY;
break;
case 0x23:
r -> AX = yesNo(r -> DL);
goto okay;
default:
r -> AX = -DE_INVLDFUNC;
r -> FLAGS |= FLG_CARRY;
break;
}
}
else
r -> FLAGS |= FLG_CARRY;
break;
case 0x66:
switch(r -> AL)
{
case 1:
GetGlblCodePage(
(UWORD FAR *)&(r -> BX),
(UWORD FAR *)&(r -> DX));
goto okay_66;
case 2:
SetGlblCodePage(
(UWORD FAR *)&(r -> BX),
(UWORD FAR *)&(r -> DX));
okay_66:
r -> FLAGS &= ~FLG_CARRY;
break;
default:
r -> AX = -DE_INVLDFUNC;
r -> FLAGS |= FLG_CARRY;
break;
}
break;
case 0x67:
if ((rc = SetJFTSize( r -> BX)) != SUCCESS)
{
r -> AX = -rc;
r -> FLAGS |= FLG_CARRY;
}
else
{
r -> FLAGS &= ~FLG_CARRY;
}
break;
}
#ifdef DEBUG
if(bDumpRegs)
{
printf("Exiting system call (21h)\n");
fbcopy((VOID FAR *)r, (VOID FAR *)&error_regs, sizeof(iregs));
dump_regs = TRUE;
dump();
printf("---\n");
}
#endif
}
VOID INRPT FAR
int22_handler (void)
{
}
#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();
return_user();
}
#pragma argsused
VOID INRPT FAR
int24_handler (void)
{
}
#pragma argsused
VOID INRPT FAR
int25_handler (void)
{
/* ...just turn this into a regular device driver request */
}
#pragma argsused
VOID INRPT FAR
int26_handler (void)
{
}
#pragma argsused
VOID INRPT FAR
int27_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 = 1;
InDOS++;
DosMemChange(cs , dx, 0);
flush();
return_user();
}
VOID INRPT FAR
int28_handler (void)
{
}
VOID INRPT FAR
empty_handler (void)
{
}