home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1988 / 03 / chalk / chalk.ls2 < prev   
Text File  |  1987-12-22  |  10KB  |  266 lines

  1. /* Copyright (C) Magna Carta Software, 1987.  All Rights Reserved.      */
  2. /* MAKEFONT -- Makes an italic font for the EGA.                        */
  3. /* Note: Do not run this program from within the IDE.                   */
  4. /* First version 10/29/87.  Last update: 10/31/87.                      */
  5.  
  6. #ifndef __SMALL__
  7.      #error Should use SMALL compilation model
  8. #endif
  9.  
  10. #include <stdio.h>
  11. #include <dos.h>
  12. #include <process.h>
  13. #include <mem.h>
  14. #include <stdlib.h>
  15.  
  16. #define TRUE 1
  17. #define FALSE 0
  18.  
  19.  
  20. /* Functions related to video operations */
  21. void load_user_egaxfont(char *fptr,int block,int bpc,int char_count,int spos);
  22. void get_egafont(char *fptr, int font);
  23. int get_video_info(void);
  24.  
  25. /* Global variables and #DEFINES related to video operations */
  26. #include "mk_ital.asc"          /* ITALIC.ASC contains our italic font */
  27. #define VIDEO 0x10                              /* BIOS video interrupt */
  28. char fontarray[3585];                           /* buffer for font storage */
  29. int our_id1 = 0xfac, our_id2 = 0x1000;          /* our ID words */
  30. char ega_color;
  31.  
  32. /* Functions related to TSR operations */
  33. int already_installed(void);
  34. int deinstall(void);
  35. void interrupt (*old_int10h)(void);
  36. void interrupt int10h(unsigned bp, unsigned di, unsigned si,
  37.                       unsigned ds, unsigned es, unsigned dx,
  38.                       unsigned cx, unsigned bx, unsigned ax);
  39.  
  40. /* Global variables related to TSR operations */
  41. unsigned save_bp1, save_bp2, old_ds, old_psp;
  42. unsigned old_env;
  43.  
  44.  
  45. /* Turbo C system variables (see text for explanation ) */
  46. extern unsigned __brklvl;
  47. extern unsigned _psp;
  48.  
  49.  
  50. /* Other functions */
  51. void error(int errnum);
  52.  
  53.  
  54. main()
  55. {
  56.         int i, j, k;
  57.         union REGS regs;
  58.  
  59.         get_video_info();
  60.         if (!ega_color) regs.x.ax = 0x7;        /* set the video mode */
  61.         else regs.x.ax = 0x3;
  62.         int86(VIDEO,®s,®s);
  63.         if (already_installed()) {
  64.                 deinstall();
  65.                 printf("\The Italic font is now no longer installed");
  66.                 exit(0);
  67.         }
  68.  
  69.         /* system checks out -- go ahead and put italic chars. in font */
  70.         get_egafont(fontarray,14);      /* store the ROM font in fontarray */
  71.         for(i=14*32,j=0; i< 14*128;j++) {
  72.                 for(k=0;k<14;k++) fontarray[i++] = italic_arr[j][k];
  73.         }
  74.         load_user_egaxfont(fontarray,0,14,256,0);       /* load our font */
  75.  
  76.         old_psp = _psp;                 /* save the resident program's PSP */
  77.         old_env = peek(_psp,0x2c);      /* save the resident program's ENV */
  78.         old_int10h = getvect(VIDEO);    /* save the old vector */
  79.         setvect(VIDEO,int10h);          /* install our INT10h handler */
  80.  
  81.         /* terminate and stay resident. Program length is determined by */
  82.         /* subtracting the psp address (_psp) from __brkval which is    */
  83.         /* dynamically set to the address of the end of DS.  This       */
  84.         /* appears to be reliable in the TINY and SMALL models, but     */
  85.         /* results are unknown for other models.                        */
  86.         keep(FALSE,_DS + (__brklvl + 15)/16 - _psp);
  87. }
  88.  
  89.  
  90. /* ALREADY_INSTALLED: This routine scans through memory for our ID byte.*/
  91. /* Returns: 0 if not found, 1 if found.                                 */
  92. int already_installed()
  93. {
  94.         unsigned int next_seg;
  95.  
  96.         for(next_seg = _psp-1; next_seg > 0; next_seg--) {
  97.                 if (peek(next_seg,(unsigned) &our_id1) == our_id1) {
  98.                         if (peek(next_seg,(unsigned) &our_id2) == our_id2) {
  99.                                 old_ds = next_seg;
  100.                                 return (1);
  101.                         }
  102.                 }
  103.         }
  104.         return (0);
  105. }
  106.  
  107.  
  108. /* DEINSTALL: Remove our TSR by reseting interrupt 0x10 and video mode. */
  109. int deinstall()
  110. {
  111.         union REGS regs;
  112.         struct SREGS sregs;
  113.  
  114.         /* initialize old interrupt vector */
  115.         old_int10h = MK_FP(peek(old_ds,(unsigned) &old_int10h+2),peek(old_ds,(unsigned) &old_int10h));
  116.         setvect(VIDEO,old_int10h);      /* reset the interrupt vector */
  117.  
  118.         if (!ega_color) regs.x.ax = 0x7;        /* reset the video mode */
  119.         else regs.x.ax = 0x3;
  120.         int86(VIDEO,®s,®s);
  121.  
  122.         /* Deallocate the memory used by the resident program */
  123.         old_psp = peek(old_ds, (unsigned) &old_psp);
  124.         old_env = peek(old_ds, (unsigned) &old_env);
  125.  
  126.         regs.x.ax = 0x4900;     /* DOS function to free allocated memory */
  127.         sregs.es = old_psp;
  128.         intdosx(®s,®s,&sregs);
  129.         if (regs.x.cflag) error(3);
  130.  
  131.         regs.x.ax = 0x4900;     /* DOS function to free allocated memory */
  132.         sregs.es = old_env;
  133.         intdosx(®s,®s,&sregs);
  134.         if (regs.x.cflag) error(4);
  135.         return (0);
  136. }
  137.  
  138.  
  139. /* INT10: This function is the BIOS video interrupt handler.            */
  140. void interrupt int10h(unsigned bp, unsigned di, unsigned si,
  141.                       unsigned ds, unsigned es, unsigned dx,
  142.                       unsigned cx, unsigned bx, unsigned ax)
  143. {
  144.         /* execute the old video interrupt */
  145.         if (ax >> 8) {          /* it is not a video mode reset */
  146.                 _AX = ax;
  147.                 _BX = bx;
  148.                 _CX = cx;
  149.                 _DX = dx;
  150.                 save_bp1 = _BP;
  151.                 _BP = bp;
  152.                 (*old_int10h)();
  153.                 _BP = save_bp1;
  154.                 ax = _AX;
  155.                 bx = _BX;
  156.                 cx = _CX;
  157.                 dx = _DX;
  158.         }
  159.         else {                  /* AH == 0 for a video mode reset */
  160.                 _AX = ax;
  161.                 _BX = bx;
  162.                 _CX = cx;
  163.                 _DX = dx;
  164.                 (*old_int10h)();
  165.                 ax = _AX;
  166.                 bx = _BX;
  167.                 cx = _CX;
  168.                 dx = _DX;
  169.  
  170.                 /* reload our font destroyed by the mode reset */
  171.                 load_user_egaxfont(fontarray,0,14,256,0);
  172.         }
  173. }
  174.  
  175.  
  176. /* LOAD_USER_EGAXFONT -- Load a user-defined font and reset page length.*/
  177. /* Parms: ptr. to user table, block to load, bytes-per-char,            */
  178. /* number of chars to store, starting position in font table.           */
  179. /* First version 7/13/87.  Last update 10/31/87.                        */
  180. void load_user_egaxfont(char *fptr,int block,int bpc,int char_count,int spos)
  181. {
  182.         unsigned byte_block;
  183.  
  184.         byte_block = (bpc << 8) | block;
  185.  
  186.         /* Can't use intr() due to Turbo C v1.0 compiler bug.           */
  187.         /* Note: we must do any assignments to segments prior to doing  */
  188.         /* assignments to AX since AX is destroyed.                     */
  189.         _ES = _DS;
  190.         _AX = 0x1100;                   /* call function 0x11 */
  191.         _BX = byte_block;               /* block to load */
  192.         _CX = char_count;               /* number of characters to load */
  193.         _DX = spos;                     /* character offset into table */
  194.         save_bp2  = _BP;                /* save BP for stack addressing */
  195.         _BP = FP_OFF(fptr);             /* load address of user font */
  196.         geninterrupt(VIDEO);
  197.         _BP = save_bp2;                 /* restore BP -- or die... */
  198. }
  199.  
  200.  
  201. /* GET_EGAFONT: This routine grabs an EGA font from ROM and stores it   */
  202. /* in the global variable fontarray */
  203. void get_egafont(char *fptr, int font)
  204. {
  205.         struct REGPACK regs;
  206.  
  207.         regs.r_ax = 0x1130;             /* EGA BIOS call to return font */
  208.         if (font == 8) regs.r_bx = 0x0300;
  209.         else if (font == 14) regs.r_bx = 0x0200;
  210.         intr(VIDEO,®s);
  211.         movedata(regs.r_es,regs.r_bp,_DS, (unsigned) fptr,14*256);
  212. }
  213.  
  214.  
  215. /* GET__VIDEO_INFO: A VGA or an EGA must be installed for this program  */
  216. /* to work. The monitor must be an Enahanced Color or Monochrome        */
  217. /* display and the correct adaptor must be active.                      */
  218. int get_video_info()
  219. {
  220.         union REGS regs;
  221.         unsigned char e_byte;
  222.  
  223.         /* First check for the presence of an EGA */
  224.         regs.h.ah = 0x12;       /* EGA BIOS alternate select            */
  225.         regs.h.bl = 0x10;       /* return EGA information.              */
  226.         int86(VIDEO, ®s, ®s);
  227.         if (regs.h.bl == 0x10) error(1);        /* EGA not found */
  228.  
  229.         /* EGA is present -- is it active? */
  230.         e_byte = peekb(0,0x487);        /* EGA info. byte */
  231.         if (e_byte & 8) error(2);       /* EGA not active */
  232.  
  233.         /* Does the present, active EGA drive a color or mono monitor? */
  234.         if (regs.h.bh) ega_color = FALSE;  /* EGA drives a mono monitor */
  235.         else ega_color = TRUE;          /* EGA drives a color monitor */
  236.  
  237.         /* See if EGA drives an Enhanced Color Display */
  238.         if (ega_color) if (!(regs.h.cl == 3 || regs.h.cl == 9)) error(1);
  239.         return (1);
  240. }
  241.  
  242.  
  243. /* ERROR: A simple error handler.                                       */
  244. void error(int errnum)
  245. {
  246.         switch (errnum) {
  247.                 case 1: printf("\An EGA and Enhanced Color or Monochrome Display");
  248.                         printf("\nmust be present to use this program.");
  249.                         break;
  250.  
  251.                 case 2: printf("\Please make the EGA the active adapter");
  252.                         printf("in order to run this program.");
  253.                         break;
  254.  
  255.                 case 3: printf("\nError deallocating program memory.");
  256.                         break;
  257.  
  258.                 case 4: printf("\nError deallocating program PSP.");
  259.                         break;
  260.  
  261.                 default:break;
  262.         }
  263.         printf("\nProgram exiting.\n");
  264.         exit(0xf);      /* Return code for DOS errorlevel */
  265. }
  266.