home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 19.ddi / SAMPLES / DBWIN / MONOOUT.C_ / MONOOUT.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  5.8 KB  |  264 lines

  1. //--------------------------------------------------------------------
  2. //
  3. // Monochrome video output routine
  4. //
  5. // void MonoOut(LPCSTR lpsz)
  6. //
  7. // Output a string to the monochrome display (if present).  Handles
  8. // carriage return, line feed, tab, bell, and the ANSI clear-screen
  9. // escape sequence.
  10. //
  11. // BOOL MonoOpen(void);
  12. // BOOL MonoClose(void);
  13. //
  14. // BOOL MonoQuery(void);
  15. //
  16. // Returns TRUE if a secondary monochrome display exists.
  17. //
  18. // WARNING - PLEASE NOTE
  19. //
  20. // These output routines work by directly addressing the monochrome adapter
  21. // video memory.  If an application or debugger is also using this memory
  22. // (such as CodeView), debug output may trash the screen.
  23. //
  24. #include "dbwindlp.h"
  25.  
  26. typedef struct
  27. {
  28.     char ch;
  29.     BYTE attr;
  30. } CA;
  31.  
  32. // NOTE: In order to be able to check to see if a debugger or another
  33. // app is using the monochrome display, these routines do not use the
  34. // top line of the display.
  35. //
  36. #define CCOLMAX         80
  37. #define CROWMAX         24
  38.  
  39. // Macro used to access absolute exports from KERNEL
  40. //
  41. #define EXPVAL(name)    ((WORD)(void NEAR*)&name)
  42.  
  43. // Monochrome video memory base selector -- absolute exported by KERNEL.
  44. //
  45. extern WORD PASCAL __B000h;
  46.  
  47. #define ESC             27
  48. #define BELL            7
  49.  
  50. #define DEFATTR         0x07
  51. #define CA_SPACE        ((DEFATTR << 8) | ' ')
  52.  
  53. // Compute far pointer to character at row, col.  Note that top line is not used.
  54. //
  55. #define PCA(row, col)   MAKELP(EXPVAL(__B000h), (((row) + 1) * CCOLMAX + (col)) * sizeof(CA))
  56.  
  57. static void CACopy(CA FAR* pcaDst, CA FAR* pcaSrc, WORD cca);
  58. static void CAFill(CA FAR* pcaDst, WORD cca, WORD ca);
  59.  
  60. int rowCur = 0;
  61. int colCur = 0;
  62.  
  63. BOOL fMonoOpen = FALSE;
  64.  
  65. BOOL MonoOpen(void)
  66. {
  67.     if (fMonoOpen)
  68.         return FALSE;
  69.  
  70.     fMonoOpen = MonoQuery();
  71.  
  72.     if (fMonoOpen && !MonoInUse())
  73.     {
  74.         CAFill(PCA(0, 0), CCOLMAX * CROWMAX, CA_SPACE);
  75.         colCur = 0;
  76.         rowCur = 0;
  77.     }
  78.  
  79.     return fMonoOpen;
  80. }
  81.  
  82. BOOL MonoClose(void)
  83. {
  84.     if (!fMonoOpen)
  85.         return FALSE;
  86.  
  87.     fMonoOpen = FALSE;
  88.     return TRUE;
  89. }
  90.  
  91. BOOL MonoOut(LPCSTR sz)
  92. {
  93.     CA FAR* pca;
  94.     char ch;
  95.  
  96.     // If monochrome isn't open, bail out.
  97.  
  98.     if (!fMonoOpen)
  99.         return FALSE;
  100.  
  101.     // If the monochrome adapter is in use by another app,
  102.     // don't output anything.
  103.     //
  104.     if (MonoInUse())
  105.         return FALSE;
  106.  
  107.     pca = PCA(rowCur, colCur);
  108.  
  109.     while (ch = *sz++)
  110.     {
  111.         switch (ch)
  112.         {
  113.         case '\b':
  114.             if (colCur > 0)
  115.             {
  116.                 colCur--;
  117.                 pca--;
  118.                 pca->ch = ' ';
  119.                 pca->attr = DEFATTR;
  120.             }
  121.             break;
  122.  
  123.         case BELL:
  124.             MessageBeep(0);
  125.             break;
  126.  
  127.         case '\t':
  128.             pca    += 8 - colCur % 8;
  129.             colCur += 8 - colCur % 8;
  130.             break;
  131.  
  132.         case '\r':
  133.             colCur = 0;
  134.             pca = PCA(rowCur, colCur);
  135.             break;
  136.  
  137.         default:
  138.             pca->ch = ch;
  139.             pca->attr = DEFATTR;
  140.             pca++;
  141.             colCur++;
  142.  
  143.             if (colCur < CCOLMAX)
  144.                 break;
  145.  
  146.             // fall through to handle LF
  147.  
  148.         case '\n':
  149.             colCur = 0;
  150.             rowCur++;
  151.  
  152.             if (rowCur >= CROWMAX)
  153.             {
  154.                 CACopy(PCA(0, 0), PCA(1, 0), CCOLMAX * (CROWMAX - 1));
  155.                 CAFill(PCA(CROWMAX - 1, 0), CCOLMAX, CA_SPACE);
  156.                 rowCur = CROWMAX - 1;
  157.             }
  158.  
  159.             pca = PCA(rowCur, colCur);
  160.             break;
  161.  
  162.         case ESC:
  163.             //
  164.             // ANSI clear screen escape
  165.             //
  166.             if (sz[1] == '[' && sz[2] == '2' && sz[3] == 'J')
  167.             {
  168.                 CAFill(PCA(0,0), CCOLMAX * CROWMAX, CA_SPACE);
  169.                 rowCur = colCur = 0;
  170.                 sz += 3;
  171.             }
  172.         }
  173.     }
  174.     return TRUE;
  175. }
  176.  
  177. #pragma optimize("gle", off)
  178.  
  179. static void CACopy(CA FAR* pcaDst, CA FAR* pcaSrc, WORD cca)
  180. {
  181.     _asm {
  182.         push    ds
  183.  
  184.         mov     cx,cca
  185.         lds     si,pcaSrc
  186.         les     di,pcaDst
  187.         cld
  188.         rep     movsw
  189.  
  190.         pop     ds
  191.     }
  192. }
  193.  
  194. static void CAFill(CA FAR* pca, WORD cca, WORD ca)
  195. {
  196.     _asm {
  197.         mov     ax,ca
  198.         mov     cx,cca
  199.         les     di,pca
  200.         cld
  201.         rep     stosw
  202.  
  203.     }
  204. }
  205.  
  206. BOOL MonoQuery(void)
  207. {
  208.     BOOL fHasAdapter;
  209.  
  210.     // Query BIOS for display configuration.
  211.     // Return TRUE if secondary display is a monochrome adapter.
  212.     //
  213.     _asm
  214.     {
  215.         mov     ax,1a00h
  216.         int     10h
  217.         xor     ax,ax
  218.         cmp     bh,1                ; return TRUE if secondary adapter
  219.         jnz     nomono              ; is a monochrome adapter
  220.         inc     ax
  221.     nomono:
  222.         mov     fHasAdapter,ax
  223.     }
  224.     return fHasAdapter;
  225. }
  226.  
  227. // BOOL MonoInUse(void)
  228. //
  229. // This routine checks to see if the monochrome adapter is in use
  230. // by a debugger or another app.  This is done by checking to see
  231. // if there are any characters on the top line of the display other
  232. // than space.
  233. //
  234. // It's done in this way for speed, and to avoid calling any Kernel routines.
  235. // In order to ensure that this trick works, MonoOut does not use the
  236. // top line of the display.
  237. //
  238. BOOL MonoInUse(void)
  239. {
  240.     BOOL fCVW = FALSE;
  241.  
  242.     _asm
  243.     {
  244.         push    si
  245.  
  246.         mov     ax,offset __B000h
  247.         mov     es,ax
  248.         cmp     word ptr es:[0],CA_SPACE
  249.         jnz     InUse
  250.         cmp     word ptr es:[4],CA_SPACE
  251.         jnz     InUse
  252.         cmp     word ptr es:[8],CA_SPACE
  253.         jnz     InUse
  254.         cmp     word ptr es:[16],CA_SPACE
  255.         jz      NotInUse
  256. InUse:
  257.         inc     fCVW                ; CodeView is running: fCVW = TRUE
  258. NotInUse:
  259.     }
  260.     return fCVW;
  261. }
  262.  
  263. #pragma optimize("", on)
  264.