home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************/
- /* File Id. INT29C.C. */
- /* Author. Stan Milam. */
- /* Date Written. 8 Oct. 91. */
- /* */
- /* (c) Copyright 1991, by Stan Milam. */
- /* */
- /* This code is responsible for writing DOS's standard output */
- /* in a PCW window. It seems DOS sends all characters to be */
- /* output to the screen through interrupt 29H. Here we capture*/
- /* interrupt 29h and and print the characters in the PCW window*/
- /* */
- /***************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #include "pcw.i"
- #include "pcwproto.h"
-
- /* Function Declarations */
-
- #ifdef __ZTC__
- #define interrupt
-
- void far *getvect( int nbr ) {
-
- union REGS regs;
- struct SREGS sregs;
-
- regs.h.ah = (char) 0x35;
- regs.h.al = (char) nbr;
- int86x(0x21,®s,®s,&sregs);
- return ( MK_FP(sregs.es, regs.x.bx) );
- }
-
- void setvect( int nbr, void far *isr ) {
-
- union REGS regs;
- struct SREGS sregs;
-
- regs.h.ah = 0x25;
- regs.h.al = (char) nbr;
- regs.x.dx = FP_OFF(isr);
- sregs.ds = FP_SEG(isr);
- int86x(0x21,®s,®s,&sregs);
- }
-
- void (far *old_int29)(void);
- #endif
-
- #ifdef MSC
- void (interrupt far *old_int29)(void);
- #endif
- #ifdef __TURBOC__
- void interrupt (far *old_int29)(void);
- #endif
- #ifdef __POWERC
- void interrupt (far *old_int29)(void);
- #endif
- extern void far interrupt Int29(void);
- int far Int29c(int ax);
- void far _Save_ES_DS_(void);
- void far Save_Int29_Regs(void);
-
- /**********************************************************/
- /* set_int29() */
- /* */
- /* Set INT 29 to point to our assembler routine, but first*/
- /* save the address of the old interrupt handler to call */
- /* it if we need to. */
- /**********************************************************/
-
- int set_int29(void) {
-
- #ifdef MSC
- old_int29 = _dos_getvect(0x29); /* Get old int29 address */
- _dos_setvect(0x29,Int29); /* Set Int 29 to point to */
- #else /* Our code */
- old_int29 = getvect(0x29);
- setvect(0x29, Int29);
- #endif
- #ifdef __POWERC
- Save_Int29_Regs(); /* Save Data & Extra Seg */
- #endif
- return(1);
- }
-
- /***************************************************************/
- /* reset_int29() */
- /* */
- /* This function MUST BE CALLED IF YOU HAVE CAPTURED DOS OUTPUT*/
- /* If this function is not called and your program ends then */
- /* surely bad things will happen. */
- /* */
- /***************************************************************/
-
- void reset_int29(void) {
-
- #ifdef MSC
- _dos_setvect(0x29,old_int29);
- #else
- setvect(0x29, old_int29);
- #endif
- }
-
- /***************************************************************/
- /* Int29c() */
- /* */
- /* This code is called by the assembly language interrupt hand-*/
- /* ler and is responsible for handling the writing of a char- */
- /* acter in the PCW window. It makes sure we are not writing */
- /* outside of the window and scrolls the window when needed. */
- /* If there is no active window or the active window is hidden */
- /* then we simply return with a return code of -1. This sig- */
- /* nals the assembly langauge handler to call the original DOS */
- /* output interrupt. */
- /* */
- /* Inputs: The contents of AX register (char to print). */
- /* Outputs: 1 if task accomplished, otherwise -1. */
- /* */
- /***************************************************************/
-
- int far Int29c( int __ax ) {
-
- WNDPTR *wnd;
- union REGS regs;
- int c_row, c_col, lrow, ucol, lcol;
-
- if ((wnd = get_active_wnd()) == NULL)
- return -1; /* Call original int29 */
-
- if (wnd -> hideflag)
- return 1; /* Can't show, window hidden */
-
- ucol = wnd -> ucol; /* Dereference the boundries */
- lrow = wnd -> lrow;
- lcol = wnd -> lcol;
-
- get_cursor_pos(&c_row, &c_col); /* Get cursor position */
- switch ( __ax ) {
- case '\n' :
- if (c_row == (lrow - 1)) { /* Check for last row */
- wscroll(wnd, 1, -1); /* Scroll wnd up 1 line */
- return 1;
- }
- break;
- case '\r' :
- set_cursor_pos(c_row,ucol+1); /* Handle carriage return */
- return ( 1 );
- }
-
- memset(®s, 0, sizeof(union REGS)); /* Clear psuedo regs */
- regs.h.ah = 0xe; /* Set the registers */
- regs.h.al = (char) __ax; /* Character in AX */
- regs.h.bh = (char) wnd -> page; /* Active video page */
- regs.h.bl = (char) wnd -> attr; /* Color in Bl */
- regs.x.cx = 1;
- int86(0x10, ®s, ®s); /* Call BIOS, write char and */
- /* advance the cursor */
- get_cursor_pos(&c_row, &c_col);
- if (c_col == lcol) { /* Is last column? */
- if (c_row == lrow-1) { /* If it is then is it last row */
- wscroll(wnd, 1, -1); /* If it is scroll the window */
- set_cursor_pos(lrow - 1, ucol + 1);/* And pos cursor to 1st column */
- }
- else set_cursor_pos(c_row+1, ucol+1); /* Not last row so positon */
- } /* Next row,1st column of window */
- return(1); /* Send back good return */
- } /* And quit */
-