home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1988
/
03
/
chalk
/
chalk.ls2
< prev
Wrap
Text File
|
1987-12-22
|
10KB
|
266 lines
/* Copyright (C) Magna Carta Software, 1987. All Rights Reserved. */
/* MAKEFONT -- Makes an italic font for the EGA. */
/* Note: Do not run this program from within the IDE. */
/* First version 10/29/87. Last update: 10/31/87. */
#ifndef __SMALL__
#error Should use SMALL compilation model
#endif
#include <stdio.h>
#include <dos.h>
#include <process.h>
#include <mem.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
/* Functions related to video operations */
void load_user_egaxfont(char *fptr,int block,int bpc,int char_count,int spos);
void get_egafont(char *fptr, int font);
int get_video_info(void);
/* Global variables and #DEFINES related to video operations */
#include "mk_ital.asc" /* ITALIC.ASC contains our italic font */
#define VIDEO 0x10 /* BIOS video interrupt */
char fontarray[3585]; /* buffer for font storage */
int our_id1 = 0xfac, our_id2 = 0x1000; /* our ID words */
char ega_color;
/* Functions related to TSR operations */
int already_installed(void);
int deinstall(void);
void interrupt (*old_int10h)(void);
void interrupt int10h(unsigned bp, unsigned di, unsigned si,
unsigned ds, unsigned es, unsigned dx,
unsigned cx, unsigned bx, unsigned ax);
/* Global variables related to TSR operations */
unsigned save_bp1, save_bp2, old_ds, old_psp;
unsigned old_env;
/* Turbo C system variables (see text for explanation ) */
extern unsigned __brklvl;
extern unsigned _psp;
/* Other functions */
void error(int errnum);
main()
{
int i, j, k;
union REGS regs;
get_video_info();
if (!ega_color) regs.x.ax = 0x7; /* set the video mode */
else regs.x.ax = 0x3;
int86(VIDEO,®s,®s);
if (already_installed()) {
deinstall();
printf("\The Italic font is now no longer installed");
exit(0);
}
/* system checks out -- go ahead and put italic chars. in font */
get_egafont(fontarray,14); /* store the ROM font in fontarray */
for(i=14*32,j=0; i< 14*128;j++) {
for(k=0;k<14;k++) fontarray[i++] = italic_arr[j][k];
}
load_user_egaxfont(fontarray,0,14,256,0); /* load our font */
old_psp = _psp; /* save the resident program's PSP */
old_env = peek(_psp,0x2c); /* save the resident program's ENV */
old_int10h = getvect(VIDEO); /* save the old vector */
setvect(VIDEO,int10h); /* install our INT10h handler */
/* terminate and stay resident. Program length is determined by */
/* subtracting the psp address (_psp) from __brkval which is */
/* dynamically set to the address of the end of DS. This */
/* appears to be reliable in the TINY and SMALL models, but */
/* results are unknown for other models. */
keep(FALSE,_DS + (__brklvl + 15)/16 - _psp);
}
/* ALREADY_INSTALLED: This routine scans through memory for our ID byte.*/
/* Returns: 0 if not found, 1 if found. */
int already_installed()
{
unsigned int next_seg;
for(next_seg = _psp-1; next_seg > 0; next_seg--) {
if (peek(next_seg,(unsigned) &our_id1) == our_id1) {
if (peek(next_seg,(unsigned) &our_id2) == our_id2) {
old_ds = next_seg;
return (1);
}
}
}
return (0);
}
/* DEINSTALL: Remove our TSR by reseting interrupt 0x10 and video mode. */
int deinstall()
{
union REGS regs;
struct SREGS sregs;
/* initialize old interrupt vector */
old_int10h = MK_FP(peek(old_ds,(unsigned) &old_int10h+2),peek(old_ds,(unsigned) &old_int10h));
setvect(VIDEO,old_int10h); /* reset the interrupt vector */
if (!ega_color) regs.x.ax = 0x7; /* reset the video mode */
else regs.x.ax = 0x3;
int86(VIDEO,®s,®s);
/* Deallocate the memory used by the resident program */
old_psp = peek(old_ds, (unsigned) &old_psp);
old_env = peek(old_ds, (unsigned) &old_env);
regs.x.ax = 0x4900; /* DOS function to free allocated memory */
sregs.es = old_psp;
intdosx(®s,®s,&sregs);
if (regs.x.cflag) error(3);
regs.x.ax = 0x4900; /* DOS function to free allocated memory */
sregs.es = old_env;
intdosx(®s,®s,&sregs);
if (regs.x.cflag) error(4);
return (0);
}
/* INT10: This function is the BIOS video interrupt handler. */
void interrupt int10h(unsigned bp, unsigned di, unsigned si,
unsigned ds, unsigned es, unsigned dx,
unsigned cx, unsigned bx, unsigned ax)
{
/* execute the old video interrupt */
if (ax >> 8) { /* it is not a video mode reset */
_AX = ax;
_BX = bx;
_CX = cx;
_DX = dx;
save_bp1 = _BP;
_BP = bp;
(*old_int10h)();
_BP = save_bp1;
ax = _AX;
bx = _BX;
cx = _CX;
dx = _DX;
}
else { /* AH == 0 for a video mode reset */
_AX = ax;
_BX = bx;
_CX = cx;
_DX = dx;
(*old_int10h)();
ax = _AX;
bx = _BX;
cx = _CX;
dx = _DX;
/* reload our font destroyed by the mode reset */
load_user_egaxfont(fontarray,0,14,256,0);
}
}
/* LOAD_USER_EGAXFONT -- Load a user-defined font and reset page length.*/
/* Parms: ptr. to user table, block to load, bytes-per-char, */
/* number of chars to store, starting position in font table. */
/* First version 7/13/87. Last update 10/31/87. */
void load_user_egaxfont(char *fptr,int block,int bpc,int char_count,int spos)
{
unsigned byte_block;
byte_block = (bpc << 8) | block;
/* Can't use intr() due to Turbo C v1.0 compiler bug. */
/* Note: we must do any assignments to segments prior to doing */
/* assignments to AX since AX is destroyed. */
_ES = _DS;
_AX = 0x1100; /* call function 0x11 */
_BX = byte_block; /* block to load */
_CX = char_count; /* number of characters to load */
_DX = spos; /* character offset into table */
save_bp2 = _BP; /* save BP for stack addressing */
_BP = FP_OFF(fptr); /* load address of user font */
geninterrupt(VIDEO);
_BP = save_bp2; /* restore BP -- or die... */
}
/* GET_EGAFONT: This routine grabs an EGA font from ROM and stores it */
/* in the global variable fontarray */
void get_egafont(char *fptr, int font)
{
struct REGPACK regs;
regs.r_ax = 0x1130; /* EGA BIOS call to return font */
if (font == 8) regs.r_bx = 0x0300;
else if (font == 14) regs.r_bx = 0x0200;
intr(VIDEO,®s);
movedata(regs.r_es,regs.r_bp,_DS, (unsigned) fptr,14*256);
}
/* GET__VIDEO_INFO: A VGA or an EGA must be installed for this program */
/* to work. The monitor must be an Enahanced Color or Monochrome */
/* display and the correct adaptor must be active. */
int get_video_info()
{
union REGS regs;
unsigned char e_byte;
/* First check for the presence of an EGA */
regs.h.ah = 0x12; /* EGA BIOS alternate select */
regs.h.bl = 0x10; /* return EGA information. */
int86(VIDEO, ®s, ®s);
if (regs.h.bl == 0x10) error(1); /* EGA not found */
/* EGA is present -- is it active? */
e_byte = peekb(0,0x487); /* EGA info. byte */
if (e_byte & 8) error(2); /* EGA not active */
/* Does the present, active EGA drive a color or mono monitor? */
if (regs.h.bh) ega_color = FALSE; /* EGA drives a mono monitor */
else ega_color = TRUE; /* EGA drives a color monitor */
/* See if EGA drives an Enhanced Color Display */
if (ega_color) if (!(regs.h.cl == 3 || regs.h.cl == 9)) error(1);
return (1);
}
/* ERROR: A simple error handler. */
void error(int errnum)
{
switch (errnum) {
case 1: printf("\An EGA and Enhanced Color or Monochrome Display");
printf("\nmust be present to use this program.");
break;
case 2: printf("\Please make the EGA the active adapter");
printf("in order to run this program.");
break;
case 3: printf("\nError deallocating program memory.");
break;
case 4: printf("\nError deallocating program PSP.");
break;
default:break;
}
printf("\nProgram exiting.\n");
exit(0xf); /* Return code for DOS errorlevel */
}