home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / c / pcw_c.zip / INT29C.C < prev    next >
C/C++ Source or Header  |  1991-12-17  |  7KB  |  172 lines

  1. /***************************************************************/
  2. /* File Id.                     INT29C.C.                      */
  3. /* Author.                      Stan Milam.                    */
  4. /* Date Written.                8 Oct. 91.                     */
  5. /*                                                             */
  6. /*              (c) Copyright 1991, by Stan Milam.             */
  7. /*                                                             */
  8. /* This code is responsible for writing DOS's standard output  */
  9. /* in a PCW window.  It seems DOS sends all characters to be   */
  10. /* output to the screen through interrupt 29H.  Here we capture*/
  11. /* interrupt 29h and and print the characters in the PCW window*/
  12. /*                                                             */
  13. /***************************************************************/
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <dos.h>
  19. #include "pcw.i"
  20. #include "pcwproto.h"
  21.  
  22. /* Function Declarations */
  23.  
  24. #ifdef __ZTC__
  25. #define interrupt
  26.  
  27. void far *getvect( int nbr ) {
  28.  
  29.     union  REGS  regs;
  30.     struct SREGS sregs;
  31.  
  32.     regs.h.ah = (char) 0x35;
  33.     regs.h.al = (char) nbr;
  34.     int86x(0x21,®s,®s,&sregs);
  35.     return ( MK_FP(sregs.es, regs.x.bx) );
  36. }
  37.  
  38. void setvect( int nbr, void far *isr ) {
  39.  
  40.     union  REGS  regs;
  41.     struct SREGS sregs;
  42.  
  43.     regs.h.ah = 0x25;
  44.     regs.h.al = (char) nbr;
  45.     regs.x.dx = FP_OFF(isr);
  46.     sregs.ds  = FP_SEG(isr);
  47.     int86x(0x21,®s,®s,&sregs);
  48. }
  49.  
  50. void (far *old_int29)(void);
  51. #endif
  52.  
  53. #ifdef MSC
  54. void (interrupt far *old_int29)(void);
  55. #endif
  56. #ifdef __TURBOC__
  57. void interrupt (far *old_int29)(void);
  58. #endif
  59. #ifdef __POWERC
  60. void interrupt (far *old_int29)(void);
  61. #endif
  62. extern void far interrupt Int29(void);
  63. int  far Int29c(int ax);
  64. void far _Save_ES_DS_(void);
  65. void far Save_Int29_Regs(void);
  66.  
  67. /**********************************************************/
  68. /*                       set_int29()                      */
  69. /*                                                        */
  70. /* Set INT 29 to point to our assembler routine, but first*/
  71. /* save the address of the old interrupt handler to call  */
  72. /* it if we need to.                                      */
  73. /**********************************************************/
  74.  
  75. int set_int29(void) {
  76.  
  77. #ifdef MSC
  78.    old_int29 = _dos_getvect(0x29);              /* Get old int29 address */
  79.    _dos_setvect(0x29,Int29);                    /* Set Int 29 to point to */
  80. #else                                           /* Our code */
  81.    old_int29 = getvect(0x29);
  82.    setvect(0x29, Int29);
  83. #endif
  84. #ifdef __POWERC
  85.    Save_Int29_Regs();                           /* Save Data & Extra Seg */
  86. #endif
  87. return(1);
  88. }
  89.  
  90. /***************************************************************/
  91. /*                          reset_int29()                      */
  92. /*                                                             */
  93. /* This function MUST BE CALLED IF YOU HAVE CAPTURED DOS OUTPUT*/
  94. /* If this function is not called and your program ends then   */
  95. /* surely bad things will happen.                              */
  96. /*                                                             */
  97. /***************************************************************/
  98.  
  99. void reset_int29(void) {
  100.  
  101. #ifdef MSC
  102.     _dos_setvect(0x29,old_int29);
  103. #else
  104.     setvect(0x29, old_int29);
  105. #endif
  106. }
  107.  
  108. /***************************************************************/
  109. /*                            Int29c()                         */
  110. /*                                                             */
  111. /* This code is called by the assembly language interrupt hand-*/
  112. /* ler and is responsible for handling the writing of a char-  */
  113. /* acter in the PCW window.  It makes sure we are not writing  */
  114. /* outside of the window and scrolls the window when needed.   */
  115. /* If there is no active window or the active window is hidden */
  116. /* then we simply return with a return code of -1.  This sig-  */
  117. /* nals the assembly langauge handler to call the original DOS */
  118. /* output interrupt.                                           */
  119. /*                                                             */
  120. /* Inputs:  The contents of AX register (char to print).       */
  121. /* Outputs: 1 if task accomplished, otherwise -1.              */
  122. /*                                                             */
  123. /***************************************************************/
  124.  
  125. int far Int29c( int __ax ) {
  126.  
  127.     WNDPTR *wnd;
  128.     union  REGS regs;
  129.     int    c_row, c_col, lrow, ucol, lcol;
  130.  
  131.     if ((wnd = get_active_wnd()) == NULL)
  132.         return -1;                          /* Call original int29 */
  133.  
  134.     if (wnd -> hideflag)
  135.         return 1;                           /* Can't show, window hidden */
  136.  
  137.     ucol = wnd -> ucol;                     /* Dereference the boundries */
  138.     lrow = wnd -> lrow;
  139.     lcol = wnd -> lcol;
  140.  
  141.     get_cursor_pos(&c_row, &c_col);         /* Get cursor position */
  142.     switch ( __ax ) {
  143.         case '\n' :
  144.              if (c_row == (lrow - 1)) {     /* Check for last row */
  145.                  wscroll(wnd, 1, -1);       /* Scroll wnd up 1 line */
  146.                  return 1;
  147.              }
  148.              break;
  149.         case '\r' :
  150.              set_cursor_pos(c_row,ucol+1);  /* Handle carriage return */
  151.              return ( 1 );
  152.     }
  153.  
  154.     memset(®s, 0, sizeof(union REGS));    /* Clear psuedo regs */
  155.     regs.h.ah = 0xe;                         /* Set the registers */
  156.     regs.h.al = (char) __ax;                 /* Character in AX */
  157.     regs.h.bh = (char) wnd -> page;          /* Active video page */
  158.     regs.h.bl = (char) wnd -> attr;          /* Color in Bl */
  159.     regs.x.cx = 1;
  160.     int86(0x10, ®s, ®s);               /* Call BIOS, write char and */
  161.                                              /* advance the cursor        */
  162.     get_cursor_pos(&c_row, &c_col);
  163.     if (c_col == lcol) {                     /* Is last column? */
  164.        if (c_row == lrow-1) {                /* If it is then is it last row */
  165.           wscroll(wnd, 1, -1);               /* If it is scroll the window */
  166.           set_cursor_pos(lrow - 1, ucol + 1);/* And pos cursor to 1st column */
  167.        }
  168.        else set_cursor_pos(c_row+1, ucol+1); /* Not last row so positon */
  169.     }                                        /* Next row,1st column of window */
  170.     return(1);                               /* Send back good return */
  171.  }                                           /* And quit */
  172.