INTHNDLR.C
上传用户:dcs7469208
上传日期:2010-01-02
资源大小:443k
文件大小:32k
源码类别:

操作系统开发

开发平台:

DOS

  1. /****************************************************************/
  2. /*                                                              */
  3. /*                          inthndlr.c                          */
  4. /*                                                              */
  5. /*    Interrupt Handler and Function dispatcher for Kernel      */
  6. /*                                                              */
  7. /*                      Copyright (c) 1995                      */
  8. /*                      Pasquale J. Villani                     */
  9. /*                      All Rights Reserved                     */
  10. /*                                                              */
  11. /* This file is part of DOS-C.                                  */
  12. /*                                                              */
  13. /* DOS-C is free software; you can redistribute it and/or       */
  14. /* modify it under the terms of the GNU General Public License  */
  15. /* as published by the Free Software Foundation; either version */
  16. /* 2, or (at your option) any later version.                    */
  17. /*                                                              */
  18. /* DOS-C is distributed in the hope that it will be useful, but */
  19. /* WITHOUT ANY WARRANTY; without even the implied warranty of   */
  20. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See    */
  21. /* the GNU General Public License for more details.             */
  22. /*                                                              */
  23. /* You should have received a copy of the GNU General Public    */
  24. /* License along with DOS-C; see the file COPYING.  If not,     */
  25. /* write to the Free Software Foundation, 675 Mass Ave,         */
  26. /* Cambridge, MA 02139, USA.                                    */
  27. /*                                                              */
  28. /****************************************************************/
  29. #include "../../hdr/portab.h"
  30. #include "globals.h"
  31. #ifdef VERSION_STRINGS
  32. BYTE *RcsId = "$Header:   C:/dos-c/src/kernel/inthndlr.c_v   1.13   07 Feb 1998 20:38:46   patv  $";
  33. #endif
  34. /* $Log:   C:/dos-c/src/kernel/inthndlr.c_v  $
  35.  * 
  36.  *    Rev 1.13   07 Feb 1998 20:38:46   patv
  37.  * Modified stack fram to match DOS standard
  38.  * 
  39.  *    Rev 1.12   22 Jan 1998  4:09:26   patv
  40.  * Fixed pointer problems affecting SDA
  41.  * 
  42.  *    Rev 1.11   06 Jan 1998 20:13:18   patv
  43.  * Broke apart int21_system from int21_handler.
  44.  * 
  45.  *    Rev 1.10   04 Jan 1998 23:15:22   patv
  46.  * Changed Log for strip utility
  47.  * 
  48.  *    Rev 1.9   04 Jan 1998 17:26:16   patv
  49.  * Corrected subdirectory bug
  50.  * 
  51.  *    Rev 1.8   03 Jan 1998  8:36:48   patv
  52.  * Converted data area to SDA format
  53.  * 
  54.  *    Rev 1.7   01 Aug 1997  2:00:10   patv
  55.  * COMPATIBILITY: Added return '$' in AL for function int 21h fn 09h
  56.  * 
  57.  *    Rev 1.6   06 Feb 1997 19:05:54   patv
  58.  * Added hooks for tsc command
  59.  * 
  60.  *    Rev 1.5   22 Jan 1997 13:18:32   patv
  61.  * pre-0.92 Svante Frey bug fixes.
  62.  * 
  63.  *    Rev 1.4   16 Jan 1997 12:46:46   patv
  64.  * pre-Release 0.92 feature additions
  65.  * 
  66.  *    Rev 1.3   29 May 1996 21:03:40   patv
  67.  * bug fixes for v0.91a
  68.  * 
  69.  *    Rev 1.2   19 Feb 1996  3:21:48   patv
  70.  * Added NLS, int2f and config.sys processing
  71.  * 
  72.  *    Rev 1.1   01 Sep 1995 17:54:20   patv
  73.  * First GPL release.
  74.  * 
  75.  *    Rev 1.0   02 Jul 1995  8:33:34   patv
  76.  * Initial revision.
  77.  */
  78. /* $EndLog$ */
  79. #ifdef TSC
  80. static VOID StartTrace(VOID);
  81. static bTraceNext = FALSE;
  82. #endif
  83. extern UWORD Int21AX;
  84. /* Special entry for far call into the kernel                           */
  85. #pragma argsused
  86. VOID FAR 
  87. int21_entry (iregs UserRegs)
  88. {
  89. int21_handler(UserRegs);
  90. }
  91. /* Convert an interrupt into our register struct definition             */
  92. VOID
  93. int21_syscall(iregs FAR *irp)
  94. {
  95. static COUNT FAR *stack;
  96. enable();
  97. if (irp -> AH > 0x67)
  98. {
  99. irp -> AL = 0;
  100. return;
  101. }
  102. Int21AX = irp -> AX;
  103. switch(irp -> AH)
  104. {
  105. /* DosVars - get/set dos variables                              */
  106. case 0x33:
  107. switch(irp -> AL)
  108. {
  109. /* Get Ctrl-C flag                                      */
  110. case 0x00:
  111. irp -> DL = break_ena ? TRUE : FALSE;
  112. break;
  113. /* Set Ctrl-C flag                                      */
  114. case 0x01:
  115. break_ena = irp -> DL ? TRUE : FALSE;
  116. break;
  117. /* Get Boot Drive                                       */
  118. case 0x05:
  119. irp -> DL = BootDrive;
  120. break;
  121. /* Get DOS-C version                                    */
  122. case 0x06:
  123. irp -> BL = os_major;
  124. irp -> BH = os_minor;
  125. irp -> DL = rev_number;
  126. irp -> DH = version_flags;
  127. break;
  128. default:
  129. irp -> AX = -DE_INVLDFUNC;
  130. irp -> FLAGS |= FLG_CARRY;
  131. break;
  132. /* Toggle DOS-C rdwrblock trace dump                    */
  133. case 0xfd:
  134. bDumpRdWrParms = !bDumpRdWrParms;
  135. break;
  136. /* Toggle DOS-C syscall trace dump                      */
  137. case 0xfe:
  138. bDumpRegs = !bDumpRegs;
  139. break;
  140. /* Get DOS-C release string pointer                     */
  141. case 0xff:
  142. irp -> DX = FP_SEG(os_release);
  143. irp -> AX = FP_OFF(os_release);
  144. break;
  145. }
  146. break;
  147. /* Set PSP                                                      */
  148. case 0x50:
  149. cu_psp = irp -> BX;
  150. break;
  151. /* Get PSP                                                      */
  152. case 0x51:
  153. irp -> BX = cu_psp;
  154. break;
  155. /* UNDOCUMENTED: return current psp                             */
  156. case 0x62:
  157. irp -> BX = cu_psp;
  158. break;
  159. /* Normal DOS function - switch stacks          */
  160. default:
  161. ++InDOS;
  162. user_r = irp;
  163. stack = irp -> AH < 0x0c ? &char_api_tos : &disk_api_tos;
  164.      
  165. /* Initialize stacks                                            */
  166. api_sp = FP_OFF(stack);
  167. api_ss = FP_SEG(stack);
  168. set_stack();
  169. int21_service(user_r);
  170. restore_stack();
  171. --InDOS;
  172. }
  173. }
  174. VOID int21_service(iregs far *r)
  175. {
  176. COUNT rc, rc1;
  177. ULONG lrc;
  178. psp FAR *p = MK_FP(cu_psp, 0);
  179. p -> ps_stack = r;
  180. if(bDumpRegs)
  181. {
  182. fbcopy((VOID FAR *)user_r, (VOID FAR *)&error_regs, sizeof(iregs));
  183. printf("System call (21h): %02xn", user_r -> AX);
  184. dump_regs = TRUE;
  185. dump();
  186. }
  187. /* The dispatch handler                                         */
  188. switch(r -> AH)
  189. {
  190. /* int 21h common error handler */
  191. case 0x64:
  192. case 0x6b:
  193. error_invalid:
  194. r -> AX = -DE_INVLDFUNC;
  195. goto error_out;
  196. error_exit:
  197. r -> AX = -rc;
  198. error_out:
  199. r -> FLAGS |= FLG_CARRY;
  200. break;
  201. /* Terminate Program                                            */
  202. case 0x00:
  203. tsr = FALSE;
  204. return_mode = break_flg ? 1 : 0;
  205. return_code = r -> AL;
  206. DosMemCheck();
  207. #ifdef TSC
  208. StartTrace();
  209. #endif
  210. return_user();
  211. break;
  212. /* Read Keyboard with Echo                      */
  213. case 0x01:
  214. r -> AL = DosCharInputEcho();
  215. break;
  216. /* Display Character                                            */
  217. case 0x02:
  218. DosDisplayOutput(r -> DL);
  219. break;
  220. /* Auxiliary Input                                                      */
  221. case 0x03:
  222. r -> AL = _sti();
  223. break;
  224. /* Auxiliary Output                                                     */
  225. case 0x04:
  226. sto(r -> DL);
  227. break;
  228. /* Print Character                                                      */
  229. case 0x05:
  230. sto(r -> DL);
  231. break;
  232. /* Direct Cosole I/O                                            */
  233. case 0x06:
  234. DosDirectConsoleIO(r);
  235. break;
  236. /* Direct Console Input                                         */
  237. case 0x07:
  238. r -> AL = DosCharInput();
  239. break;
  240. /* Read Keyboard Without Echo                                   */
  241. case 0x08:
  242. r -> AL = _sti();
  243. break;
  244. /* Display String                                               */
  245. case 0x09:
  246. DosOutputString(MK_FP(r -> DS, r -> DX));
  247. r -> AL = '$';
  248. break;
  249. /* Buffered Keyboard Input                                      */
  250. case 0x0a:
  251. ((keyboard FAR *)MK_FP(r -> DS, r -> DX)) -> kb_count = 0;
  252. sti((keyboard FAR *)MK_FP(r -> DS, r -> DX));
  253. ((keyboard FAR *)MK_FP(r -> DS, r -> DX)) -> kb_count -= 2;
  254. break;
  255. /* Check Keyboard Status                                        */
  256. case 0x0b:
  257. if(KbdBusy())
  258. r -> AL = 0x00;
  259. else
  260. r -> AL = 0xff;
  261. break;
  262. /* Flush Buffer, Read Keayboard                                 */
  263. case 0x0c:
  264. KbdFlush();
  265. switch(r -> AL)
  266. {
  267. /* Read Keyboard with Echo                      */
  268. case 0x01:
  269. r -> AL = DosCharInputEcho();
  270. break;
  271. /* Direct Cosole I/O                            */
  272. case 0x06:
  273. DosDirectConsoleIO(r);
  274. break;
  275. /* Direct Console Input                         */
  276. case 0x07:
  277. r -> AL = DosCharInput();
  278. break;
  279. /* Read Keyboard Without Echo                   */
  280. case 0x08:
  281. r -> AL = _sti();
  282. break;
  283. /* Buffered Keyboard Input                      */
  284. case 0x0a:
  285. sti((keyboard FAR *)MK_FP(r -> DS, r -> DX));
  286. break;
  287. default:
  288. r -> AL = 0x00;
  289. break;
  290. }
  291. break;
  292. /* Reset Drive                                                  */
  293. case 0x0d:
  294. flush();
  295. break;
  296. /* Set Default Drive                                            */
  297. case 0x0e:
  298. if(((COUNT)r -> DL) >= 0 && r -> DL < nblkdev)
  299. default_drive = r -> DL;
  300. r -> AL = nblkdev;            
  301. break;
  302. case 0x0f:
  303. if(FcbOpen(MK_FP(r -> DS, r -> DX)))
  304. r -> AL = 0;
  305. else
  306. r -> AL = 0xff;
  307. break;
  308. case 0x10:
  309. if(FcbClose(MK_FP(r -> DS, r -> DX)))
  310. r -> AL = 0;
  311. else
  312. r -> AL = 0xff;
  313. break;
  314. case 0x11:
  315. if(FcbFindFirst(MK_FP(r -> DS, r -> DX)))
  316. r -> AL = 0;
  317. else
  318. r -> AL = 0xff;
  319. break;
  320. case 0x12:
  321. if(FcbFindNext(MK_FP(r -> DS, r -> DX)))
  322. r -> AL = 0;
  323. else
  324. r -> AL = 0xff;
  325. break;
  326. case 0x13:
  327. if(FcbDelete(MK_FP(r -> DS, r -> DX)))
  328. r -> AL = 0;
  329. else
  330. r -> AL = 0xff;
  331. break;
  332. case 0x14:
  333. {
  334. COUNT nErrorCode;
  335. if(FcbRead(MK_FP(r -> DS, r -> DX), &nErrorCode))
  336. r -> AL = 0;
  337. else
  338. r -> AL = nErrorCode;
  339. break;
  340. }
  341. case 0x15:
  342. {
  343. COUNT nErrorCode;
  344. if(FcbWrite(MK_FP(r -> DS, r -> DX), &nErrorCode))
  345. r -> AL = 0;
  346. else
  347. r -> AL = nErrorCode;
  348. break;
  349. }
  350. case 0x16:
  351. if(FcbCreate(MK_FP(r -> DS, r -> DX)))
  352. r -> AL = 0;
  353. else
  354. r -> AL = 0xff;
  355. break;
  356. case 0x17:
  357. if(FcbRename(MK_FP(r -> DS, r -> DX)))
  358. r -> AL = 0;
  359. else
  360. r -> AL = 0xff;
  361. break;
  362. /* CP/M compatibility functions                                 */
  363. case 0x18:
  364. case 0x1d:
  365. case 0x1e:
  366. case 0x20:
  367. #ifndef TSC
  368. case 0x61:
  369. #endif
  370. default:
  371. r -> AL = 0;
  372. break;
  373. /* Get Default Drive                                            */
  374. case 0x19:
  375. r -> AL = default_drive;
  376. break;
  377. /* Set DTA                                                      */
  378. case 0x1a:
  379. {
  380. psp FAR *p = MK_FP(cu_psp,0);
  381. p -> ps_dta = MK_FP(r -> DS, r -> DX);
  382. dos_setdta(p -> ps_dta);
  383. }
  384. break;
  385. /* Get Default Drive Data                                       */
  386. case 0x1b:
  387. {
  388. BYTE FAR *p;
  389. FatGetDrvData(0,
  390.  (COUNT FAR *)&r -> AX,
  391.  (COUNT FAR *)&r -> CX,
  392.  (COUNT FAR *)&r -> DX,
  393.  (BYTE FAR **)&p);
  394. r -> DS = FP_SEG(p);
  395. r -> BX = FP_OFF(p);
  396. }
  397. break;
  398. /* Get Drive Data                                               */
  399. case 0x1c:
  400. {
  401. BYTE FAR *p;
  402. FatGetDrvData(r -> DL,
  403.  (COUNT FAR *)&r -> AX,
  404.  (COUNT FAR *)&r -> CX,
  405.  (COUNT FAR *)&r -> DX,
  406.  (BYTE FAR **)&p);
  407. r -> DS = FP_SEG(p);
  408. r -> BX = FP_OFF(p);
  409. }
  410. break;
  411. /* Get default DPB                                              */
  412. case 0x1f:
  413. if (default_drive < nblkdev)
  414. {
  415. struct dpb FAR *dpb = &blk_devices[default_drive];
  416. r -> DS = FP_SEG(dpb);
  417. r -> BX = FP_OFF(dpb);
  418. r -> AL = 0;
  419. }
  420. else r -> AL = 0xff;
  421. break;
  422. case 0x21:
  423. {
  424. COUNT nErrorCode;
  425. if(FcbRandomRead(MK_FP(r -> DS, r -> DX), &nErrorCode))
  426. r -> AL = 0;
  427. else
  428. r -> AL = nErrorCode;
  429. break;
  430. }
  431. case 0x22:
  432. {
  433. COUNT nErrorCode;
  434. if(FcbRandomWrite(MK_FP(r -> DS, r -> DX), &nErrorCode))
  435. r -> AL = 0;
  436. else
  437. r -> AL = nErrorCode;
  438. break;
  439. }
  440. /* Get file size in records                                     */
  441. case 0x23:
  442. if(FcbGetFileSize(MK_FP(r -> DS, r -> DX)))
  443. r -> AL = 0;
  444. else
  445. r -> AL = 0xff;
  446. break;
  447. case 0x24:
  448. FcbSetRandom(MK_FP(r -> DS, r -> DX));
  449. break;
  450. /* Set Interrupt Vector                                         */
  451. case 0x25:
  452. {
  453. VOID (INRPT FAR *p)() = MK_FP(r -> DS, r -> DX);
  454. setvec(r -> AL, p);
  455. }
  456. break;
  457. /* Dos Create New Psp                                           */
  458. case 0x26:
  459. {
  460. psp FAR *p = MK_FP(cu_psp, 0);
  461. new_psp((psp FAR *)MK_FP(r -> DX, 0), p -> ps_size);
  462. }
  463. break;
  464. case 0x27:
  465. {
  466. COUNT nErrorCode;
  467. if(FcbRandomBlockRead(MK_FP(r -> DS, r -> DX), r -> CX, &nErrorCode))
  468. r -> AL = 0;
  469. else
  470. r -> AL = nErrorCode;
  471. break;
  472. }
  473. case 0x28:
  474. {
  475. COUNT nErrorCode;
  476. if(FcbRandomBlockWrite(MK_FP(r -> DS, r -> DX), r -> CX, &nErrorCode))
  477. r -> AL = 0;
  478. else
  479. r -> AL = nErrorCode;
  480. break;
  481. }
  482. /* Parse File Name                                              */
  483. case 0x29:
  484. {
  485. BYTE FAR *lpFileName;
  486. lpFileName = MK_FP(r -> DS, r -> SI);
  487. r -> AL = FcbParseFname(r -> AL,
  488.  &lpFileName,
  489.  MK_FP(r -> ES, r -> DI));
  490. r -> DS = FP_SEG(lpFileName);
  491. r -> SI = FP_OFF(lpFileName);
  492. }
  493. break;
  494. /* Get Date                                                     */
  495. case 0x2a:
  496. DosGetDate(
  497.  (BYTE FAR *)&(r -> AL),        /* WeekDay              */
  498.  (BYTE FAR *)&(r -> DH),        /* Month                */
  499.  (BYTE FAR *)&(r -> DL),        /* MonthDay             */
  500.  (COUNT FAR *)&(r -> CX));      /* Year                 */
  501. break;
  502. /* Set Date                                                     */
  503. case 0x2b:
  504. rc = DosSetDate(
  505.  (BYTE FAR *)&(r -> DH),        /* Month                */
  506.  (BYTE FAR *)&(r -> DL),        /* MonthDay             */
  507.  (COUNT FAR *)&(r -> CX));      /* Year                 */
  508. if(rc != SUCCESS)
  509. r -> AL = 0xff;
  510. else
  511. r -> AL = 0;
  512. break;
  513. /* Get Time                                                     */
  514. case 0x2c:
  515. DosGetTime(
  516.  (BYTE FAR *)&(r -> CH),        /* Hour                 */
  517.  (BYTE FAR *)&(r -> CL),        /* Minutes              */
  518.  (BYTE FAR *)&(r -> DH),        /* Seconds              */
  519.  (BYTE FAR *)&(r -> DL));       /* Hundredths           */
  520. break;
  521. /* Set Date                                                     */
  522. case 0x2d:
  523. rc = DosSetTime(
  524.  (BYTE FAR *)&(r -> CH),        /* Hour                 */
  525.  (BYTE FAR *)&(r -> CL),        /* Minutes              */
  526.  (BYTE FAR *)&(r -> DH),        /* Seconds              */
  527.  (BYTE FAR *)&(r -> DL));       /* Hundredths           */
  528. if(rc != SUCCESS)
  529. r -> AL = 0xff;
  530. else
  531. r -> AL = 0;
  532. break;
  533. /* Set verify flag                                              */
  534. case 0x2e:
  535. verify_ena = (r -> AL ? TRUE : FALSE);
  536. break;
  537. /* Get DTA                                                      */
  538. case 0x2f:
  539. r -> ES = FP_SEG(dta);
  540. r -> BX = FP_OFF(dta);
  541. break;
  542. /* Get DOS Version                                              */
  543. case 0x30:
  544. r -> AL = os_major;
  545. r -> AH = os_minor;
  546. switch(r -> AL)
  547. {
  548. default:
  549. case 0:
  550. r -> BH= OEM_ID;
  551. break;
  552. case 1:
  553. r -> BH = 0;    /* RAM only for now             */
  554. break;
  555. }
  556. r -> BL = 0xff;         /* for now                      */
  557. r -> CX = 0xffff;
  558. break;
  559. /* Keep Program                                                 */
  560. case 0x31:
  561. DosMemChange(cu_psp, r -> DX < 6 ? 6 : r -> DX, 0);
  562. //flush();
  563. return_mode = 3;
  564. return_code = r -> AL;
  565. tsr = TRUE;
  566. return_user();
  567. break;
  568. /* Get DPB                                                      */
  569. case 0x32:
  570. if (r -> DL < nblkdev)
  571. {
  572. struct dpb FAR *dpb = &blk_devices[r -> DL];
  573. r -> DS = FP_SEG(dpb);
  574. r -> BX = FP_OFF(dpb);
  575. r -> AL = 0;
  576. } else r->AL = 0xFF;
  577. break;
  578. /* Get InDOS flag                                               */
  579. case 0x34:
  580. {
  581. BYTE FAR *p;
  582. p = (BYTE FAR *)((BYTE *)&InDOS);
  583. r -> ES = FP_SEG(p);
  584. r -> BX = FP_OFF(p);
  585. }
  586. break;
  587. /* Get Interrupt Vector                                         */
  588. case 0x35:
  589. {
  590. BYTE FAR *p;
  591. p = getvec((COUNT)r -> AL);
  592. r -> ES = FP_SEG(p);
  593. r -> BX = FP_OFF(p);
  594. }
  595. break;
  596. /* Dos Get Disk Free Space                                      */
  597. case 0x36:
  598. DosGetFree(
  599. (COUNT)r -> DL,
  600. (COUNT FAR *)&r -> AX,
  601. (COUNT FAR *)&r -> BX,
  602. (COUNT FAR *)&r -> CX,
  603. (COUNT FAR *)&r -> DX);
  604. break;
  605. /* Undocumented Get/Set Switchar                                */
  606. case 0x37:
  607. switch(r -> AL)
  608. {
  609. case 0:
  610. r -> DL = switchar;
  611. break;
  612. case 1:
  613. switchar = r -> DL;
  614. break;
  615. case 2:
  616. case 3:
  617. r -> DL = 0xff;
  618. break;
  619. default:
  620. goto error_invalid;
  621. }
  622. break;
  623. /* Get/Set Country Info                                         */
  624. case 0x38:
  625. {
  626. BYTE FAR *lpTable
  627. = (BYTE FAR *)MK_FP(r -> DS, r -> DX);
  628. BYTE nRetCode;
  629. if(0xffff == r -> DX)
  630. {
  631. r->AX = 0xff;
  632. r->FLAGS |= FLG_CARRY;
  633. break;
  634. r -> BX = SetCtryInfo(
  635. (UBYTE FAR *)&(r -> AL),
  636. (UWORD FAR *)&(r -> BX),
  637. (BYTE FAR *)&lpTable,
  638. (UBYTE *)&nRetCode);
  639. if(nRetCode != 0)
  640. {
  641. r -> AX = 0xff;
  642. r -> FLAGS |= FLG_CARRY;
  643. }
  644. else
  645. {
  646. r -> AX = nRetCode;
  647. r -> FLAGS &= ~FLG_CARRY;
  648. }
  649. }
  650. else
  651. {
  652. r -> BX = GetCtryInfo(&(r -> AL), &(r -> BX), lpTable);
  653. r -> FLAGS &= ~FLG_CARRY;
  654. }
  655. }
  656. break;
  657. /* Dos Create Directory                                         */
  658. case 0x39:
  659. rc = dos_mkdir((BYTE FAR *)MK_FP(r -> DS, r -> DX));
  660. if(rc != SUCCESS)
  661. goto error_exit;
  662. else
  663. {
  664. r -> FLAGS &= ~FLG_CARRY;
  665. }
  666. break;
  667. /* Dos Remove Directory                                         */
  668. case 0x3a:
  669. rc = dos_rmdir((BYTE FAR *)MK_FP(r -> DS, r -> DX));
  670. if(rc != SUCCESS)
  671. goto error_exit;
  672. else
  673. {
  674. r -> FLAGS &= ~FLG_CARRY;
  675. }
  676. break;
  677. /* Dos Change Directory                                         */
  678. case 0x3b:
  679. if((rc = DosChangeDir((BYTE FAR *)MK_FP(r -> DS, r -> DX))) < 0)
  680. goto error_exit;
  681. else
  682. {
  683. r -> FLAGS &= ~FLG_CARRY;
  684. }
  685. break;
  686. /* Dos Create File                                              */
  687. case 0x3c:
  688. if((rc = DosCreat(MK_FP(r -> DS, r -> DX), r -> CX)) < 0)
  689. goto error_exit;
  690. else
  691. {
  692. r -> AX = rc;
  693. r -> FLAGS &= ~FLG_CARRY;
  694. }
  695. break;
  696. /* Dos Open                                                     */
  697. case 0x3d:
  698. if((rc = DosOpen(MK_FP(r -> DS, r -> DX), r -> AL)) < 0)
  699. goto error_exit;
  700. else
  701. {
  702. r -> AX = rc;
  703. r -> FLAGS &= ~FLG_CARRY;
  704. }
  705. break;
  706. /* Dos Close                                                    */
  707. case 0x3e:
  708. if((rc = DosClose(r -> BX)) < 0)
  709. goto error_exit;
  710. else
  711. r -> FLAGS &= ~FLG_CARRY;
  712. break;
  713. /* Dos Read                                                     */
  714. case 0x3f:
  715. rc = DosRead(r -> BX, r -> CX, MK_FP(r -> DS, r -> DX), (COUNT FAR *)&rc1);
  716. if(rc1 != SUCCESS)
  717. {
  718. r -> FLAGS |= FLG_CARRY;
  719. r -> AX = -rc1;
  720. }
  721. else
  722. {
  723. r -> FLAGS &= ~FLG_CARRY;
  724. r -> AX = rc;
  725. }
  726. break;
  727. /* Dos Write                                                    */
  728. case 0x40:
  729. rc = DosWrite(r -> BX, r -> CX, MK_FP(r -> DS, r -> DX), (COUNT FAR *)&rc1);
  730. if(rc1 != SUCCESS)
  731. {
  732. r -> FLAGS |= FLG_CARRY;
  733. r -> AX = -rc1;
  734. }
  735. else
  736. {
  737. r -> FLAGS &= ~FLG_CARRY;
  738. r -> AX = rc;
  739. }
  740. break;
  741. /* Dos Delete File                                              */
  742. case 0x41:
  743. rc = dos_delete((BYTE FAR *)MK_FP(r -> DS, r -> DX));
  744. if(rc < 0)
  745. {
  746. r -> FLAGS |= FLG_CARRY;
  747. r -> AX = -rc1;
  748. }
  749. else
  750. r -> FLAGS &= ~FLG_CARRY;
  751. break;
  752. /* Dos Seek                                                     */
  753. case 0x42:
  754. if((rc = DosSeek(r -> BX, (LONG)((((LONG)(r -> CX)) << 16) + r -> DX), r -> AL, &lrc)) < 0)
  755. goto error_exit;
  756. else
  757. {
  758. r -> DX = (lrc >> 16);
  759. r -> AX = lrc & 0xffff;
  760. r -> FLAGS &= ~FLG_CARRY;
  761. }
  762. break;
  763. /* Get/Set File Attributes                                      */
  764. case 0x43:
  765. switch(r -> AL)
  766. {
  767. case 0x00:
  768. rc = DosGetFattr((BYTE FAR *)MK_FP(r -> DS, r -> DX), (UWORD FAR *)&r -> CX);
  769. if(rc < SUCCESS)
  770. goto error_exit;
  771. else
  772. {
  773. r -> FLAGS &= ~FLG_CARRY;
  774. }
  775. break;
  776. case 0x01:
  777. rc = DosSetFattr((BYTE FAR *)MK_FP(r -> DS, r -> DX), (UWORD FAR *)&r -> CX);
  778. if(rc != SUCCESS)
  779. goto error_exit;
  780. else
  781. r -> FLAGS &= ~FLG_CARRY;
  782. break;
  783. default:
  784. goto error_invalid;
  785. break;
  786. }
  787. break;
  788. /* Device I/O Control                                           */
  789. case 0x44:
  790. {
  791. BOOL bNoChangeAx;
  792. bNoChangeAx = ((r -> AL == 0) || (r -> AL == 1));
  793. rc = DosDevIOctl(r, (COUNT FAR *)&rc1);
  794. if(rc1 != SUCCESS)
  795. {
  796. r -> FLAGS |= FLG_CARRY;
  797. r -> AX = -rc1;
  798. }
  799. else
  800. {
  801. r -> FLAGS &= ~FLG_CARRY;
  802. //if(!bNoChangeAx)
  803. //   r -> AX = rc;
  804. }
  805. }
  806. break;
  807. /* Duplicate File Handle                                        */
  808. case 0x45:
  809. rc = DosDup(r -> BX);
  810. if(rc < SUCCESS)
  811. goto error_exit;
  812. else
  813. {
  814. r -> FLAGS &= ~FLG_CARRY;
  815. r -> AX = rc;
  816. }
  817. break;
  818. /* Force Duplicate File Handle                                  */
  819. case 0x46:
  820. rc = DosForceDup(r -> BX, r -> CX);
  821. if(rc < SUCCESS)
  822. goto error_exit;
  823. else
  824. r -> FLAGS &= ~FLG_CARRY;
  825. break;
  826. /* Get Current Directory                                        */
  827. case 0x47:
  828. if((rc = DosGetCuDir(r -> DL, MK_FP(r -> DS, r -> SI))) < 0)
  829. goto error_exit;
  830. else
  831. {
  832. r -> FLAGS &= ~FLG_CARRY;
  833. }
  834. break;
  835. /* Memory management                                            */
  836. case 0x48:
  837. if((rc = DosMemAlloc(r -> BX, mem_access_mode, &(r -> AX), &(r -> BX))) < 0)
  838. {
  839. DosMemLargest(&(r -> BX));
  840. goto error_exit;
  841. }
  842. else
  843. {
  844. ++(r -> AX);
  845. r -> FLAGS &= ~FLG_CARRY;
  846. }
  847. break;
  848. case 0x49:
  849. if((rc = DosMemFree(--(r -> ES))) < 0)
  850. goto error_exit;
  851. else
  852. r -> FLAGS &= ~FLG_CARRY;
  853. break;
  854. case 0x4a:
  855. {
  856. UWORD maxSize;
  857. if((rc = DosMemChange(r -> ES, r -> BX, &maxSize)) < 0)
  858. {
  859. if (rc == DE_NOMEM)
  860. r -> BX = maxSize;
  861. #if 0
  862. if(cu_psp == r -> ES)
  863. {
  864. psp FAR *p;
  865. p = MK_FP(cu_psp, 0);
  866. p -> ps_size = r -> BX + cu_psp;
  867. }
  868. #endif
  869. goto error_exit;
  870. }
  871. else
  872. r -> FLAGS &= ~FLG_CARRY;
  873. break;
  874. }
  875. /* Load and Execute Program                                     */
  876. case 0x4b:
  877. break_flg = FALSE;
  878. if((rc = DosExec(r -> AL, MK_FP(r -> ES, r -> BX), MK_FP(r -> DS, r -> DX))) 
  879. != SUCCESS)
  880. goto error_exit;
  881. else
  882. r -> FLAGS &= ~FLG_CARRY;
  883. break;
  884. /* End Program                                                  */
  885. case 0x4c:
  886. tsr = FALSE;
  887. return_mode = break_flg ? 1 : 0;
  888. return_code = r -> AL;
  889. DosMemCheck();
  890. #ifdef TSC
  891. StartTrace();
  892. #endif
  893. return_user();
  894. break;
  895. /* Get Child-program Return Value                               */
  896. case 0x4d:
  897. r -> AL = return_code;
  898. r -> AH = return_mode;
  899. break;
  900. /* Dos Find First                                               */
  901. case 0x4e:
  902. {
  903. psp FAR *p = MK_FP(cu_psp,0);
  904. /* dta for this call is set on entry.  This     */
  905. /* needs to be changed for new versions.        */
  906. if((rc = DosFindFirst((UCOUNT)r -> CX, (BYTE FAR *)MK_FP(r -> DS, r -> DX))) < 0)
  907. goto error_exit;
  908. else
  909. {
  910. r -> AX = 0;
  911. r -> FLAGS &= ~FLG_CARRY;
  912. }
  913. }
  914. break;
  915. /* Dos Find Next                                                */
  916. case 0x4f:
  917. {
  918. psp FAR *p = MK_FP(cu_psp,0);
  919. /* dta for this call is set on entry.  This     */
  920. /* needs to be changed for new versions.        */
  921. if((rc = DosFindNext()) < 0)
  922. {
  923. r -> AX = -rc;
  924. if (r -> AX == 2)
  925. r -> AX = 18;
  926. r -> FLAGS |= FLG_CARRY;
  927. }
  928. else
  929. {
  930. r -> FLAGS &= ~FLG_CARRY;
  931. }
  932. }
  933. break;
  934. /* Set PSP                                                      */
  935. case 0x50:
  936. cu_psp = r -> BX;
  937. break;
  938. /* Get PSP                                                      */
  939. case 0x51:
  940. r -> BX = cu_psp;
  941. break;
  942. /* ************UNDOCUMENTED**************************************/
  943. /* Get List of Lists                                            */
  944. case 0x52:
  945. {
  946. BYTE FAR *p;
  947. p = (BYTE FAR *)&DPBp;
  948. r -> ES = FP_SEG(p);
  949. r -> BX = FP_OFF(p);
  950. }
  951. break;
  952. /* Get verify state                                             */
  953. case 0x54:
  954. r -> AL = (verify_ena ? TRUE : FALSE);
  955. break;
  956. /* ************UNDOCUMENTED**************************************/
  957. /* Dos Create New Psp & set p_size                              */
  958. case 0x55:
  959. new_psp((psp FAR *)MK_FP(r -> DX, 0), r -> SI);
  960. break;
  961. /* Dos Rename                                                   */
  962. case 0x56:
  963. rc = dos_rename(
  964.  (BYTE FAR *)MK_FP(r -> DS, r -> DX),   /* OldName      */
  965.  (BYTE FAR *)MK_FP(r -> ES, r -> DI));  /* NewName      */
  966. if(rc < SUCCESS)
  967. goto error_exit;
  968. else
  969. {
  970. r -> FLAGS &= ~FLG_CARRY;
  971. }
  972. break;
  973. /* Get/Set File Date and Time                                   */
  974. case 0x57:
  975. switch(r -> AL)
  976. {
  977. case 0x00:
  978. if(!DosGetFtime(
  979.  (COUNT)r -> BX,        /* Handle               */
  980.  (date FAR *)&r -> DX,  /* FileDate             */
  981.  (time FAR *)&r -> CX)) /* FileTime             */
  982. {
  983. r -> AX = -DE_INVLDHNDL;
  984. r -> FLAGS |= FLG_CARRY;
  985. }
  986. else
  987. r -> FLAGS &= ~FLG_CARRY;
  988. break;
  989. case 0x01:
  990. if(!DosSetFtime(
  991.  (COUNT)r -> BX,        /* Handle               */
  992.  (date FAR *)&r -> DX,  /* FileDate             */
  993.  (time FAR *)&r -> CX)) /* FileTime             */
  994. {
  995. r -> AX = -DE_INVLDHNDL;
  996. r -> FLAGS |= FLG_CARRY;
  997. }
  998. else
  999. r -> FLAGS &= ~FLG_CARRY;
  1000. break;
  1001. default:
  1002. goto error_invalid;
  1003. }
  1004. break;
  1005. /* Get/Set Allocation Strategy                                  */
  1006. case 0x58:
  1007. switch(r -> AL)
  1008. {
  1009. case 0x00:
  1010. r -> AX = mem_access_mode;
  1011. break;
  1012. case 0x01:
  1013. if(((COUNT)r -> BX) < 0 || r -> BX > 2)
  1014. goto error_invalid;
  1015. else
  1016. {
  1017. mem_access_mode = r -> BX;
  1018. r -> FLAGS &= ~FLG_CARRY;
  1019. }
  1020. break;
  1021. default:
  1022. goto error_invalid;
  1023. #ifdef DEBUG
  1024. case 0xff:
  1025. show_chain();
  1026. break;
  1027. #endif
  1028. }
  1029. break;
  1030. case 0x5a:
  1031. if((rc = DosMkTmp(MK_FP(r -> DS, r -> DX), r -> CX)) < 0)
  1032. goto error_exit;
  1033. else
  1034. {
  1035.  r -> AX = rc;
  1036.  r -> FLAGS &= ~FLG_CARRY;
  1037. }
  1038. break;
  1039. case 0x5b:
  1040. if((rc = DosOpen(MK_FP(r -> DS, r -> DX), 0)) >= 0)
  1041. {
  1042. DosClose(rc);
  1043. r -> AX = 80;
  1044. r -> FLAGS |= FLG_CARRY;
  1045. else 
  1046. {
  1047.    if((rc = DosCreat(MK_FP(r -> DS, r -> DX), r -> CX)) < 0)
  1048. goto error_exit;
  1049.    else
  1050.    {
  1051. r -> AX = rc;
  1052. r -> FLAGS &= ~FLG_CARRY;
  1053.    }
  1054. }
  1055. break;
  1056. /* UNDOCUMENTED: server, share.exe and sda function */
  1057. case 0x5d:
  1058. switch(r -> AL)
  1059. {
  1060. case 0x06:
  1061. r -> DS = FP_SEG(internal_data);
  1062. r -> SI = FP_OFF(internal_data);
  1063. r -> CX = swap_always - internal_data;
  1064. r -> DX = swap_indos - internal_data;
  1065. r -> FLAGS &= ~FLG_CARRY;
  1066. break;
  1067. default:
  1068. goto error_invalid;
  1069. }
  1070. case 0x60:      /* TRUENAME */
  1071. if ((rc = truename(MK_FP(r -> DS, r-> SI),
  1072.  adjust_far(MK_FP( r -> ES, r -> DI)))) != SUCCESS)
  1073. goto error_exit;
  1074. else
  1075. {
  1076. r -> FLAGS &= ~FLG_CARRY;
  1077. }
  1078. break;
  1079. #ifdef TSC
  1080. /* UNDOCUMENTED: no-op */
  1081. /* */
  1082. /* DOS-C: tsc support */
  1083. case 0x61:
  1084. switch(r -> AL)
  1085. {
  1086. case 0x01:
  1087. bTraceNext = TRUE;
  1088. break;
  1089. case 0x02:
  1090. bDumpRegs = FALSE;
  1091. break;
  1092. }
  1093. #endif
  1094. break;
  1095. /* UNDOCUMENTED: return current psp                             */
  1096. case 0x62:
  1097. r -> BX = cu_psp;
  1098. break;
  1099. /* UNDOCUMENTED: Double byte and korean tables                  */
  1100. case 0x63:
  1101. {
  1102. #ifdef DBLBYTE
  1103. static char dbcsTable[2] = 
  1104. {
  1105. 0, 0
  1106. };
  1107. void FAR *dp = &dbcsTable;
  1108. r -> DS = FP_SEG(dp);
  1109. r -> SI = FP_OFF(dp);
  1110. r -> AL = 0;
  1111. #else
  1112. /* not really supported, but will pass. */
  1113. r -> AL = 0xff;
  1114. #endif
  1115. break;
  1116. }
  1117. /* Extended country info                                        */
  1118. case 0x65:
  1119. if(r -> AL <= 0x7)
  1120. {
  1121. if(ExtCtryInfo(
  1122. r -> AL,
  1123. r -> BX,
  1124. r -> CX,
  1125. MK_FP(r -> ES, r -> DI)))
  1126. r -> FLAGS &= ~FLG_CARRY;
  1127. else
  1128. goto error_invalid;
  1129. }
  1130. else if((r -> AL >= 0x20) && (r -> AL <= 0x22))
  1131. {
  1132. switch(r -> AL)
  1133. {
  1134. case 0x20:
  1135. r -> DL = upChar(r -> DL);
  1136. goto okay;
  1137. case 0x21:
  1138. upMem(
  1139. MK_FP(r -> DS, r -> DX),
  1140. r -> CX);
  1141. goto okay;
  1142. case 0x22:
  1143. upString(MK_FP(r -> DS, r -> DX));
  1144. okay:
  1145. r -> FLAGS &= ~FLG_CARRY;
  1146. break;
  1147. case 0x23:
  1148. r -> AX = yesNo(r -> DL);
  1149. goto okay;
  1150. default:
  1151. goto error_invalid;
  1152. }
  1153. }
  1154. else
  1155. r -> FLAGS |= FLG_CARRY;
  1156. break;
  1157. case 0x66:
  1158. switch(r -> AL)
  1159. {
  1160. case 1:
  1161. GetGlblCodePage(
  1162. (UWORD FAR *)&(r -> BX),
  1163. (UWORD FAR *)&(r -> DX));
  1164. goto okay_66;
  1165. case 2:
  1166. SetGlblCodePage(
  1167. (UWORD FAR *)&(r -> BX),
  1168. (UWORD FAR *)&(r -> DX));
  1169. okay_66:
  1170. r -> FLAGS &= ~FLG_CARRY;
  1171. break;
  1172. default:
  1173. goto error_invalid;
  1174. }
  1175. break;
  1176. case 0x67: 
  1177. if ((rc = SetJFTSize( r -> BX)) != SUCCESS)
  1178. goto error_exit;
  1179. else
  1180. {
  1181. r -> FLAGS &= ~FLG_CARRY;
  1182. }
  1183. break;
  1184. }
  1185. if(bDumpRegs)
  1186. {
  1187. fbcopy((VOID FAR *)user_r  , (VOID FAR *)&error_regs,
  1188.  sizeof(iregs));
  1189. dump_regs = TRUE;
  1190. dump();
  1191. }
  1192. }
  1193. VOID INRPT FAR 
  1194. int22_handler (void)
  1195. {
  1196. }
  1197. #pragma argsused
  1198. VOID INRPT FAR 
  1199. 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)
  1200. {
  1201. tsr = FALSE;
  1202. return_mode = 1;
  1203. return_code = -1;
  1204. mod_sto(CTL_C);
  1205. DosMemCheck();
  1206. #ifdef TSC
  1207. StartTrace();
  1208. #endif
  1209. return_user();
  1210. }
  1211. #pragma argsused
  1212. VOID INRPT FAR 
  1213. int24_handler (void)
  1214. {
  1215. }
  1216. /* Structures needed for int 25 / int 26 */
  1217. struct  HugeSectorBlock
  1218. {
  1219. ULONG   blkno;  
  1220. WORD    nblks;
  1221. BYTE    FAR *buf;
  1222. };
  1223. struct  int25regs
  1224. {
  1225. UWORD   es, ds;
  1226. UWORD   di, si, bp, sp;
  1227. UWORD   bx, dx, cx, ax;
  1228. UWORD   flags, ip, cs;
  1229. };
  1230. /* this function is called from an assembler wrapper function */ 
  1231. VOID    int25_handler (struct int25regs FAR *r)
  1232. {
  1233. ULONG   blkno;
  1234. UWORD   nblks;
  1235. BYTE    FAR *buf;
  1236. UBYTE   drv = r->ax & 0xFF;
  1237. InDOS++;
  1238. if (r->cx == 0xFFFF)
  1239. {
  1240. struct HugeSectorBlock FAR *lb = MK_FP(r->ds, r->bx);
  1241. blkno = lb->blkno;
  1242. nblks = lb->nblks;
  1243. buf = lb->buf;
  1244. } else {
  1245. nblks = r->cx;
  1246. blkno = r->dx;
  1247. buf = MK_FP(r->ds, r->bx);
  1248. }
  1249. if (drv >= nblkdev)
  1250. {
  1251. r->ax = 0x202; 
  1252. r->flags |= FLG_CARRY; 
  1253. return;
  1254. }
  1255. while (nblks--)
  1256. {
  1257. struct buffer FAR *bp;
  1258. if ((bp = getblock(blkno + 1, drv)) == NULL) 
  1259. {
  1260. r->ax = 0x202; 
  1261. r->flags |= FLG_CARRY; 
  1262. return;
  1263. }
  1264. fbcopy(bp->b_buffer, buf, maxbksize);
  1265. buf += maxbksize;
  1266. blkno++;
  1267. }
  1268. r->ax = 0;
  1269. r->flags &= ~FLG_CARRY;
  1270. --InDOS;
  1271. }
  1272. VOID int26_handler (struct int25regs FAR *r)
  1273. {
  1274. ULONG   blkno;
  1275. UWORD   nblks;
  1276. BYTE    FAR *buf;
  1277. UBYTE    drv = r->ax & 0xFF;
  1278. InDOS++;
  1279. if (r->cx == 0xFFFF)
  1280. {
  1281. struct HugeSectorBlock FAR *lb = MK_FP(r->ds, r->bx);
  1282. blkno = lb->blkno;
  1283. nblks = lb->nblks;
  1284. buf = lb->buf;
  1285. } else {
  1286. nblks = r->cx;
  1287. blkno = r->dx;
  1288. buf = MK_FP(r->ds, r->bx);
  1289. }
  1290. if (drv >= nblkdev)
  1291. {
  1292. r->ax = 0x202;
  1293. r->flags |= FLG_CARRY;
  1294. return;
  1295. }
  1296. while (nblks--)
  1297. {
  1298. struct buffer FAR *b;
  1299. getbuf(&b, blkno + 1, drv);
  1300. fbcopy(buf, b->b_buffer, maxbksize);
  1301. b -> b_flag |= (BFR_DIRTY | BFR_VALID);
  1302. b -> b_blkno = blkno + 1;
  1303. b -> b_unit = drv;
  1304. if (flush1(b) == FALSE)
  1305. {
  1306. r->ax = 0x202; 
  1307. r->flags |= FLG_CARRY;
  1308. return;
  1309. }
  1310. buf += maxbksize;
  1311. blkno++;
  1312. }
  1313. r->ax = 0;
  1314. r->flags &= ~FLG_CARRY;
  1315. --InDOS;
  1316. }
  1317. VOID INRPT FAR 
  1318. int28_handler (void)
  1319. {
  1320. }
  1321. VOID INRPT FAR
  1322. empty_handler (void)
  1323. {
  1324. }
  1325. #ifdef TSC
  1326. static VOID StartTrace(VOID)
  1327. {
  1328. if(bTraceNext)
  1329. {
  1330. bDumpRegs = TRUE;
  1331. bTraceNext = FALSE;
  1332. }
  1333. else
  1334. bDumpRegs = FALSE;
  1335. }
  1336. #endif