From ec4f0db1f7da03b379704b1073931cb4e30275a2 Mon Sep 17 00:00:00 2001 From: sparky4 Date: Fri, 16 May 2014 19:32:17 -0500 Subject: [PATCH] new file: 16/PCX_LIB.ZIP new file: 16/PCX_LIB/PCX_COMM.C new file: 16/PCX_LIB/PCX_DISP.C new file: 16/PCX_LIB/PCX_EXAM.C new file: 16/PCX_LIB/PCX_EXAM.EXE new file: 16/PCX_LIB/PCX_EXT.H new file: 16/PCX_LIB/PCX_FILE.C new file: 16/PCX_LIB/PCX_FMT.DOC new file: 16/PCX_LIB/PCX_INT.H new file: 16/PCX_LIB/PCX_LIB.BAT new file: 16/PCX_LIB/PCX_LIB.DOC new file: 16/PCX_LIB/RD_DEMO.C new file: 16/PCX_LIB/RD_DEMO.EXE new file: 16/PCX_LIB/TEST_04.PCX new file: 16/PCX_LIB/TEST_06.PCX new file: 16/PCX_LIB/TEST_16.PCX new file: 16/PCX_LIB/TEST_19.PCX new file: 16/PCX_LIB/WR_DEMO.C new file: 16/PCX_LIB/WR_DEMO.EXE new file: 16/modex105.zip new file: 16/modex105/ASM.BAT new file: 16/modex105/DEMOS/BASIC7/CHARDEMO.BAS new file: 16/modex105/DEMOS/BASIC7/MAKE-LIB.BAT new file: 16/modex105/DEMOS/BASIC7/MODEX.BI new file: 16/modex105/DEMOS/BASIC7/MODEX.LIB new file: 16/modex105/DEMOS/BASIC7/MODEX.QLB new file: 16/modex105/DEMOS/BASIC7/TEST6.BAS new file: 16/modex105/DEMOS/BASIC7/UASM-BC7.BAT new file: 16/modex105/DEMOS/BASIC7/UTILS.ASM new file: 16/modex105/DEMOS/BASIC7/UTILS.BI new file: 16/modex105/DEMOS/C/C_UTILS.ASM new file: 16/modex105/DEMOS/C/C_UTILS.H new file: 16/modex105/DEMOS/C/MODEX.H new file: 16/modex105/DEMOS/C/UTLS-ASM.BAT new file: 16/modex105/DEMOS/C/X-DEMO.C new file: 16/modex105/DEMOS/C/X-DEMO.EXE new file: 16/modex105/DEMOS/C/X-DEMO.PRJ new file: 16/modex105/DEMOS/CHARDEMO.EXE new file: 16/modex105/DEMOS/PASCAL/TEST5.PAS new file: 16/modex105/DEMOS/QB45/MAKE-LIB.BAT new file: 16/modex105/DEMOS/QB45/MODEX.BI new file: 16/modex105/DEMOS/QB45/MODEX.LIB new file: 16/modex105/DEMOS/QB45/MODEX.QLB new file: 16/modex105/DEMOS/QB45/TEST6A.BAS new file: 16/modex105/DEMOS/QB45/TEST6A.EXE new file: 16/modex105/DEMOS/QB45/UASM-QB4.BAT new file: 16/modex105/DEMOS/QB45/UTILS.ASM new file: 16/modex105/DEMOS/QB45/UTILS.BI new file: 16/modex105/DEMOS/ROM_8X8.FNT new file: 16/modex105/DEMOS/SPACEAGE.FNT new file: 16/modex105/DEMOS/SYSTEM.FNT new file: 16/modex105/DEMOS/TEST6.EXE new file: 16/modex105/FONTEDIT/CHARSETS.CS new file: 16/modex105/FONTEDIT/CSEDIT.DOC new file: 16/modex105/FONTEDIT/CSEDIT.EXE new file: 16/modex105/FONTEDIT/INVERSE.FNT new file: 16/modex105/FONTEDIT/MOUSEIMG.CS new file: 16/modex105/FONTEDIT/PALETTE.CS new file: 16/modex105/FONTEDIT/ROM_8X8.FNT new file: 16/modex105/FONTEDIT/SPACEAGE.FNT new file: 16/modex105/FONTEDIT/SYSTEM.FNT new file: 16/modex105/MODE-X.TXT new file: 16/modex105/MODEX.ASM new file: 16/modex105/MODEX.BI new file: 16/modex105/MODEX.H new file: 16/modex105/PACKING.LST new file: 16/modex105/PALEDIT/CHARSETS.CS new file: 16/modex105/PALEDIT/GAMECOLR.PAL new file: 16/modex105/PALEDIT/MOUSEIMG.CS new file: 16/modex105/PALEDIT/PALEDIT.DOC new file: 16/modex105/PALEDIT/PALEDIT.EXE new file: 16/modex105/PALEDIT/PRIME.PAL new file: 16/modex105/PALEDIT/RGB.PAL new file: 16/modex105/README.DOC --- 16/PCX_LIB.ZIP | Bin 0 -> 103390 bytes 16/PCX_LIB/PCX_COMM.C | 198 ++ 16/PCX_LIB/PCX_DISP.C | 1140 +++++++++ 16/PCX_LIB/PCX_EXAM.C | 339 +++ 16/PCX_LIB/PCX_EXAM.EXE | Bin 0 -> 11193 bytes 16/PCX_LIB/PCX_EXT.H | 66 + 16/PCX_LIB/PCX_FILE.C | 1379 +++++++++++ 16/PCX_LIB/PCX_FMT.DOC | 941 +++++++ 16/PCX_LIB/PCX_INT.H | 195 ++ 16/PCX_LIB/PCX_LIB.BAT | 13 + 16/PCX_LIB/PCX_LIB.DOC | 387 +++ 16/PCX_LIB/RD_DEMO.C | 169 ++ 16/PCX_LIB/RD_DEMO.EXE | Bin 0 -> 26804 bytes 16/PCX_LIB/TEST_04.PCX | Bin 0 -> 3346 bytes 16/PCX_LIB/TEST_06.PCX | Bin 0 -> 3962 bytes 16/PCX_LIB/TEST_16.PCX | Bin 0 -> 32097 bytes 16/PCX_LIB/TEST_19.PCX | Bin 0 -> 9285 bytes 16/PCX_LIB/WR_DEMO.C | 209 ++ 16/PCX_LIB/WR_DEMO.EXE | Bin 0 -> 30472 bytes 16/modex105.zip | Bin 0 -> 264999 bytes 16/modex105/ASM.BAT | 1 + 16/modex105/DEMOS/BASIC7/CHARDEMO.BAS | 164 ++ 16/modex105/DEMOS/BASIC7/MAKE-LIB.BAT | 5 + 16/modex105/DEMOS/BASIC7/MODEX.BI | 63 + 16/modex105/DEMOS/BASIC7/MODEX.LIB | Bin 0 -> 7189 bytes 16/modex105/DEMOS/BASIC7/MODEX.QLB | Bin 0 -> 11141 bytes 16/modex105/DEMOS/BASIC7/TEST6.BAS | 562 +++++ 16/modex105/DEMOS/BASIC7/UASM-BC7.BAT | 1 + 16/modex105/DEMOS/BASIC7/UTILS.ASM | 406 +++ 16/modex105/DEMOS/BASIC7/UTILS.BI | 51 + 16/modex105/DEMOS/C/C_UTILS.ASM | 405 +++ 16/modex105/DEMOS/C/C_UTILS.H | 117 + 16/modex105/DEMOS/C/MODEX.H | 76 + 16/modex105/DEMOS/C/UTLS-ASM.BAT | 1 + 16/modex105/DEMOS/C/X-DEMO.C | 780 ++++++ 16/modex105/DEMOS/C/X-DEMO.EXE | Bin 0 -> 41090 bytes 16/modex105/DEMOS/C/X-DEMO.PRJ | Bin 0 -> 5188 bytes 16/modex105/DEMOS/CHARDEMO.EXE | Bin 0 -> 13066 bytes 16/modex105/DEMOS/PASCAL/TEST5.PAS | 488 ++++ 16/modex105/DEMOS/QB45/MAKE-LIB.BAT | 5 + 16/modex105/DEMOS/QB45/MODEX.BI | 63 + 16/modex105/DEMOS/QB45/MODEX.LIB | Bin 0 -> 7189 bytes 16/modex105/DEMOS/QB45/MODEX.QLB | Bin 0 -> 9739 bytes 16/modex105/DEMOS/QB45/TEST6A.BAS | 561 +++++ 16/modex105/DEMOS/QB45/TEST6A.EXE | Bin 0 -> 40544 bytes 16/modex105/DEMOS/QB45/UASM-QB4.BAT | 1 + 16/modex105/DEMOS/QB45/UTILS.ASM | 406 +++ 16/modex105/DEMOS/QB45/UTILS.BI | 51 + 16/modex105/DEMOS/ROM_8X8.FNT | Bin 0 -> 1024 bytes 16/modex105/DEMOS/SPACEAGE.FNT | Bin 0 -> 1024 bytes 16/modex105/DEMOS/SYSTEM.FNT | Bin 0 -> 1024 bytes 16/modex105/DEMOS/TEST6.EXE | Bin 0 -> 19990 bytes 16/modex105/FONTEDIT/CHARSETS.CS | Bin 0 -> 2144 bytes 16/modex105/FONTEDIT/CSEDIT.DOC | 196 ++ 16/modex105/FONTEDIT/CSEDIT.EXE | Bin 0 -> 68368 bytes 16/modex105/FONTEDIT/INVERSE.FNT | Bin 0 -> 1024 bytes 16/modex105/FONTEDIT/MOUSEIMG.CS | Bin 0 -> 128 bytes 16/modex105/FONTEDIT/PALETTE.CS | Bin 0 -> 768 bytes 16/modex105/FONTEDIT/ROM_8X8.FNT | Bin 0 -> 1024 bytes 16/modex105/FONTEDIT/SPACEAGE.FNT | Bin 0 -> 1024 bytes 16/modex105/FONTEDIT/SYSTEM.FNT | Bin 0 -> 1024 bytes 16/modex105/MODE-X.TXT | 44 + 16/modex105/MODEX.ASM | 3295 +++++++++++++++++++++++++ 16/modex105/MODEX.BI | 63 + 16/modex105/MODEX.H | 76 + 16/modex105/PACKING.LST | 87 + 16/modex105/PALEDIT/CHARSETS.CS | Bin 0 -> 2144 bytes 16/modex105/PALEDIT/GAMECOLR.PAL | Bin 0 -> 768 bytes 16/modex105/PALEDIT/MOUSEIMG.CS | Bin 0 -> 128 bytes 16/modex105/PALEDIT/PALEDIT.DOC | 166 ++ 16/modex105/PALEDIT/PALEDIT.EXE | Bin 0 -> 70230 bytes 16/modex105/PALEDIT/PRIME.PAL | Bin 0 -> 768 bytes 16/modex105/PALEDIT/RGB.PAL | Bin 0 -> 768 bytes 16/modex105/README.DOC | 76 + 74 files changed, 13246 insertions(+) create mode 100644 16/PCX_LIB.ZIP create mode 100644 16/PCX_LIB/PCX_COMM.C create mode 100644 16/PCX_LIB/PCX_DISP.C create mode 100644 16/PCX_LIB/PCX_EXAM.C create mode 100644 16/PCX_LIB/PCX_EXAM.EXE create mode 100644 16/PCX_LIB/PCX_EXT.H create mode 100644 16/PCX_LIB/PCX_FILE.C create mode 100644 16/PCX_LIB/PCX_FMT.DOC create mode 100644 16/PCX_LIB/PCX_INT.H create mode 100644 16/PCX_LIB/PCX_LIB.BAT create mode 100644 16/PCX_LIB/PCX_LIB.DOC create mode 100644 16/PCX_LIB/RD_DEMO.C create mode 100644 16/PCX_LIB/RD_DEMO.EXE create mode 100644 16/PCX_LIB/TEST_04.PCX create mode 100644 16/PCX_LIB/TEST_06.PCX create mode 100644 16/PCX_LIB/TEST_16.PCX create mode 100644 16/PCX_LIB/TEST_19.PCX create mode 100644 16/PCX_LIB/WR_DEMO.C create mode 100644 16/PCX_LIB/WR_DEMO.EXE create mode 100644 16/modex105.zip create mode 100644 16/modex105/ASM.BAT create mode 100644 16/modex105/DEMOS/BASIC7/CHARDEMO.BAS create mode 100644 16/modex105/DEMOS/BASIC7/MAKE-LIB.BAT create mode 100644 16/modex105/DEMOS/BASIC7/MODEX.BI create mode 100644 16/modex105/DEMOS/BASIC7/MODEX.LIB create mode 100644 16/modex105/DEMOS/BASIC7/MODEX.QLB create mode 100644 16/modex105/DEMOS/BASIC7/TEST6.BAS create mode 100644 16/modex105/DEMOS/BASIC7/UASM-BC7.BAT create mode 100644 16/modex105/DEMOS/BASIC7/UTILS.ASM create mode 100644 16/modex105/DEMOS/BASIC7/UTILS.BI create mode 100644 16/modex105/DEMOS/C/C_UTILS.ASM create mode 100644 16/modex105/DEMOS/C/C_UTILS.H create mode 100644 16/modex105/DEMOS/C/MODEX.H create mode 100644 16/modex105/DEMOS/C/UTLS-ASM.BAT create mode 100644 16/modex105/DEMOS/C/X-DEMO.C create mode 100644 16/modex105/DEMOS/C/X-DEMO.EXE create mode 100644 16/modex105/DEMOS/C/X-DEMO.PRJ create mode 100644 16/modex105/DEMOS/CHARDEMO.EXE create mode 100644 16/modex105/DEMOS/PASCAL/TEST5.PAS create mode 100644 16/modex105/DEMOS/QB45/MAKE-LIB.BAT create mode 100644 16/modex105/DEMOS/QB45/MODEX.BI create mode 100644 16/modex105/DEMOS/QB45/MODEX.LIB create mode 100644 16/modex105/DEMOS/QB45/MODEX.QLB create mode 100644 16/modex105/DEMOS/QB45/TEST6A.BAS create mode 100644 16/modex105/DEMOS/QB45/TEST6A.EXE create mode 100644 16/modex105/DEMOS/QB45/UASM-QB4.BAT create mode 100644 16/modex105/DEMOS/QB45/UTILS.ASM create mode 100644 16/modex105/DEMOS/QB45/UTILS.BI create mode 100644 16/modex105/DEMOS/ROM_8X8.FNT create mode 100644 16/modex105/DEMOS/SPACEAGE.FNT create mode 100644 16/modex105/DEMOS/SYSTEM.FNT create mode 100644 16/modex105/DEMOS/TEST6.EXE create mode 100644 16/modex105/FONTEDIT/CHARSETS.CS create mode 100644 16/modex105/FONTEDIT/CSEDIT.DOC create mode 100644 16/modex105/FONTEDIT/CSEDIT.EXE create mode 100644 16/modex105/FONTEDIT/INVERSE.FNT create mode 100644 16/modex105/FONTEDIT/MOUSEIMG.CS create mode 100644 16/modex105/FONTEDIT/PALETTE.CS create mode 100644 16/modex105/FONTEDIT/ROM_8X8.FNT create mode 100644 16/modex105/FONTEDIT/SPACEAGE.FNT create mode 100644 16/modex105/FONTEDIT/SYSTEM.FNT create mode 100644 16/modex105/MODE-X.TXT create mode 100644 16/modex105/MODEX.ASM create mode 100644 16/modex105/MODEX.BI create mode 100644 16/modex105/MODEX.H create mode 100644 16/modex105/PACKING.LST create mode 100644 16/modex105/PALEDIT/CHARSETS.CS create mode 100644 16/modex105/PALEDIT/GAMECOLR.PAL create mode 100644 16/modex105/PALEDIT/MOUSEIMG.CS create mode 100644 16/modex105/PALEDIT/PALEDIT.DOC create mode 100644 16/modex105/PALEDIT/PALEDIT.EXE create mode 100644 16/modex105/PALEDIT/PRIME.PAL create mode 100644 16/modex105/PALEDIT/RGB.PAL create mode 100644 16/modex105/README.DOC diff --git a/16/PCX_LIB.ZIP b/16/PCX_LIB.ZIP new file mode 100644 index 0000000000000000000000000000000000000000..d43913bb8b2eea8c6588db28cfef86105c9ee86f GIT binary patch literal 103390 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

)Ys~s8dy;Gz2U2!z0kIg$; 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 aFIz_g7w@kh$?o3gciub`ad&@G!2bd38mycE literal 0 HcmV?d00001 diff --git a/16/PCX_LIB/PCX_COMM.C b/16/PCX_LIB/PCX_COMM.C new file mode 100644 index 00000000..42520561 --- /dev/null +++ b/16/PCX_LIB/PCX_COMM.C @@ -0,0 +1,198 @@ +/* + ************************************************************************* + * + * PCX_COMM.C - PCX_LIB Library Common Functions + * + * Version: 1.00B + * + * History: 91/02/14 - Created + * 91/04/01 - Release 1.00A + * 91/04/03 - fixed "segread" call. + * 91/04/07 - Release 1.00B + * + * Compiler: Microsoft C V6.0 + * + * Author: Ian Ashdown, P.Eng. + * byHeart Software + * 620 Ballantree Road + * West Vancouver, B.C. + * Canada V7S 1W3 + * Tel. (604) 922-6148 + * Fax. (604) 987-7621 + * + * Copyright: Public Domain + * + ************************************************************************* + */ + +/* + ************************************************************************* + * + * PORTABILITY NOTES + * + * 1. While this program is written in ANSI C, it uses a number of + * function calls that are specific to the Microsoft C V6.0 library. + * These are documented as follows for the purposes of porting this + * program to other compilers and/or processors: + * + * int86x - execute 80x86 interrupt routine (far data) + * segread - get current 80x86 segment register values + * + ************************************************************************* + */ + +/* INCLUDE FILES */ + +#include +#include +#include +#include "pcx_int.h" + +/* FORWARD REFERENCES */ + +/* GLOBALS */ + +/* PUBLIC FUNCTIONS */ + +/* + ************************************************************************* + * + * PCX_OPEN - Open PCX Workblock + * + * Purpose: To allocate and initialize a PCX image file workblock. + * + * Setup: PCX_WORKBLK *pcx_open + * ( + * char *fname, + * BOOL wrt_flag + * ) + * + * Where: fname is a PCX image file name. + * wrt_flag is a Boolean flag which if TRUE indicates that + * the PCX image file is to be opened for writing; + * otherwise it is opened for reading. + * + * Return: A pointer to a PCX image file workblock if successful; + * otherwise NULL. + * + ************************************************************************* + */ + +PCX_WORKBLK *pcx_open +( + char *fname, + BOOL wrt_flag +) +{ + PCX_WORKBLK *wbp; /* PCX image file workblock pointer */ + + /* Allocate a workblock */ + + if ((wbp = (PCX_WORKBLK *) malloc(sizeof(PCX_WORKBLK))) == NULL) + return (NULL); + + /* Open the PCX image file in binary mode */ + + if (wrt_flag == FALSE) + wbp->fp = fopen(fname, "rb"); /* Open for reading */ + else + wbp->fp = fopen(fname, "wb"); /* Open for writing */ + + if (wbp->fp == NULL) /* Check for successful file opening */ + { + free(wbp); /* Free the workblock memory */ + return (NULL); + } + + return (wbp); /* Return the workblock pointer */ +} + +/* + ************************************************************************* + * + * PCX_CLOSE - Close PCX Workblock + * + * Purpose: To close a PCX image file and release its workblock + * memory. + * + * Setup: BOOL pcx_close + * ( + * PCX_WORKBLK *wbp + * ) + * + * Where: wbp is a PCX image file workblock pointer. + * + * Return: TRUE if successful; otherwise FALSE. + * + ************************************************************************* + */ + +BOOL pcx_close +( + PCX_WORKBLK *wbp +) +{ + free(wbp->palettep); /* Free the extended palette (if it exists) */ + + free(wbp); /* Free the PCX image file workblock */ + + if (fclose(wbp->fp) == EOF) /* Close the PCX image file */ + return (FALSE); + + return (TRUE); +} + +/* + ************************************************************************* + * + * PCX_ISVGA - Check For VGA Display Adapter + * + * Purpose: To determine whether a display adapter supports VGA BIOS + * service routines. + * + * Setup: BOOL pcx_isvga(void) + * + * Return: TRUE if display adapter is VGA-compatible; otherwise + * FALSE. + * + ************************************************************************* + */ + +BOOL pcx_isvga(void) +{ + unsigned char *vinfop; /* VGA information buffer pointer */ + union REGS regs; /* 80x86 register values */ + struct SREGS sregs; /* 80x86 segment register values */ + + /* Allocate a VGA functionality/state information buffer */ + + if ((vinfop = (unsigned char *) malloc(sizeof(unsigned char) * 64)) == + NULL) + return (FALSE); + + /* Attempt to read the VGA information */ + + regs.h.ah = 0x1b; /* Select "Return VGA Info" BIOS routine */ + regs.x.bx = 0; /* Implementation type */ + + /* Get the VGA information buffer offset value */ + + regs.x.di = (unsigned int) vinfop; + + segread(&sregs); /* Get the current DS segment register value */ + + sregs.es = sregs.ds; + + int86x(0x10, ®s, ®s, &sregs); /* Call BIOS video service */ + + free(vinfop); /* Free the VGA information buffer */ + + /* The value 0x1b is returned in register AL only if a VGA display */ + /* adapter is present */ + + if (regs.h.al == 0x1b) + return (TRUE); + else + return (FALSE); +} + diff --git a/16/PCX_LIB/PCX_DISP.C b/16/PCX_LIB/PCX_DISP.C new file mode 100644 index 00000000..7547b9f9 --- /dev/null +++ b/16/PCX_LIB/PCX_DISP.C @@ -0,0 +1,1140 @@ +/* + ************************************************************************* + * + * PCX_DISP.C - PCX_LIB Library Image Display Functions + * + * Version: 1.00B + * + * History: 91/02/14 - Created + * 91/04/01 - Release 1.00A + * 91/04/03 - fixed "segread" call. + * 91/04/07 - Release 1.00B + * + * Compiler: Microsoft C V6.0 + * + * Author: Ian Ashdown, P.Eng. + * byHeart Software + * 620 Ballantree Road + * West Vancouver, B.C. + * Canada V7S 1W3 + * Tel. (604) 922-6148 + * Fax. (604) 987-7621 + * + * Copyright: Public Domain + * + ************************************************************************* + */ + +/* + ************************************************************************* + * + * PORTABILITY NOTES + * + * 1. While this program is written in ANSI C, it uses a number of + * function calls that are specific to the Microsoft C V6.0 library. + * These are documented as follows for the purposes of porting this + * program to other compilers and/or processors: + * + * _fmemcpy - "memcpy" for small model / far data + * int86 - execute 80x86 interrupt routine + * int86x - execute 80x86 interrupt routine (far + * data) + * _remapallpalette - remap entire video display color palette + * _selectpalette - select CGA color palette + * outpw - output word to 80x86 I/O port + * segread - get current 80x86 segment register + * values + * + * 2. When porting this program to other processors, remember that words + * are stored by 80x86-based machines in the big-endian format. That + * is, the eight least significant bits (lower byte) are stored + * first, followed by the eight most significant bits (upper byte). + * If PCX-format files are transferred to little-endian machines + * (such as those based on 680x0 and Z8000 processors), the order of + * bytes within each word will have to be reversed before they can + * be interpreted. (This applies to the file header only, since the + * encoded image data and optional 256-color palette are stored as + * bytes.) + * + * 3. MS-DOS does not recognize the 720 x 348 graphics mode of the + * Hercules monochrome display adapter. Therefore, the constant + * PCX_HERC should never be passed as a video mode parameter to any + * BIOS service routine. + * + * The Microsoft C compiler includes a "video mode" parameter + * definition (_HERCMONO) that is defined as 0x08. This is a + * reserved MS-DOS video mode that is apparently used internally by + * the ROM BIOS. It can, however, be passed to the Microsoft C + * library function "_setvideomode" to force the Hercules display + * adapter into graphics mode. + * + * Most other MS-DOS C compilers offer similar library functions to + * force the Hercules monochrome display adapter into its 720 x 348 + * graphics mode. + * + ************************************************************************* + */ + +/* INCLUDE FILES */ + +#include +#include +#include +#include +#include +#include +#include +#include "pcx_int.h" + +/* FORWARD REFERENCES */ + +static BOOL pcx_read_init(PCX_WORKBLK *, int, int); +static BOOL pcx_read_extpal(PCX_WORKBLK *); +static BOOL pcx_read_header(PCX_WORKBLK *); +static BOOL pcx_read_line(PCX_WORKBLK *, unsigned char *, int); +static BOOL pcx_set_palette(PCX_PAL *, int); + +static void pcx_cga_palette(PCX_PAL *, int); +static void pcx_put_cga(PCX_WORKBLK *, unsigned char _far *, int); +static void pcx_put_ega(PCX_WORKBLK *, unsigned char _far *, int); +static void pcx_put_herc(PCX_WORKBLK *, unsigned char _far *, int); +static void pcx_put_vga(PCX_WORKBLK *, unsigned char _far *, int); + +/* GLOBALS */ + +/* PUBLIC FUNCTIONS */ + +/* + ************************************************************************* + * + * PCX_READ - Read PCX Image File + * + * Purpose: To read and display a PCX-format image file. + * + * Setup: BOOL pcx_read + * ( + * char *fname, + * int vmode, + * int page + * ) + * + * Where: fname is a PCX image file name. + * vmode is the MS-DOS video mode. Valid values are: + * + * PCX_HERC - 720 x 348 Hercules monochrome + * 0x04 - 320 x 200 4-color CGA + * 0x05 - 320 x 200 4-color CGA (color burst off) + * 0x06 - 640 x 200 2-color CGA + * 0x0d - 320 x 200 16-color EGA/VGA + * 0x0e - 640 x 200 16-color EGA/VGA + * 0x0f - 640 x 350 2-color EGA/VGA + * 0x10 - 640 x 350 16-color EGA/VGA + * 0x11 - 640 x 480 2-color VGA + * 0x12 - 640 x 480 16-color VGA + * 0x13 - 320 x 200 256-color VGA + * + * page is the video display page number. Valid values are: + * + * Mode PCX_HERC - 0 or 1 + * Mode 0x0d - 0 to 7 + * Mode 0x0e - 0 to 3 + * Mode 0x0f - 0 or 1 + * Mode 0x10 - 0 or 1 + * All Other - 0 + * + * Return: TRUE if successful; otherwise FALSE. + * + * Note: The video display adapter must be in the appropriate mode + * and active page for the image to be displayed. + * + ************************************************************************* + */ + +BOOL pcx_read +( + char *fname, + int vmode, + int page +) +{ + int bpline; /* Number of bytes per scan line */ + int line_num; /* Scan line number */ + int max_lines; /* Maximum number of scan lines */ + unsigned char *linep; /* PCX scan line buffer pointer */ + BOOL status = TRUE; /* Return status */ + PCX_WORKBLK *wbp; /* PCX image file workblock pointer */ + + /* Open a PCX image file workblock */ + + if ((wbp = pcx_open(fname, FALSE)) == (PCX_WORKBLK *) NULL) + return (FALSE); + + /* Initialize the workblock for reading */ + + if (pcx_read_init(wbp, vmode, page) == FALSE) + { + (void) pcx_close(wbp); /* Close the PCX workblock */ + return (FALSE); + } + + /* Calculate the image height */ + + max_lines = wbp->header.yul + wbp->header.ylr + 1; + + /* Calculate number of bytes per line (for all color planes) */ + + bpline = wbp->header.bppscan * wbp->header.nplanes; + + /* Allocate the PCX scan line buffer */ + + if ((linep = (unsigned char *) malloc(bpline)) != (unsigned char *) + NULL) + { + /* Set the file pointer to the beginning of the encoded image data */ + + if (status == TRUE) + if (fseek(wbp->fp, (long) (sizeof(PCX_HDR)), SEEK_SET) != 0) + status = FALSE; + + /* Set the video display adapter color palette unless the PCX file */ + /* is Version 3.0 (i.e. - PC Paintbrush Version 2.8 w/o palette) */ + + if (status == TRUE) + if (wbp->header.version != 3) + if (pcx_set_palette(wbp->palettep, vmode) == FALSE) + status = FALSE; + + /* Read the image line by line */ + + if (status == TRUE) + { + for (line_num = 0; line_num < max_lines; line_num++) + { + /* Read the current scan line */ + + if ((status = pcx_read_line(wbp, linep, bpline)) == FALSE) + { + status = FALSE; + break; + } + + /* Display the current scan line */ + + wbp->pcx_funcp(wbp, (unsigned char _far *) linep, line_num); + } + } + + free(linep); /* Free the PCX scan line buffer */ + } + else + status = FALSE; + + if (pcx_close(wbp) == FALSE) /* Close the PCX workblock */ + status = FALSE; + + return (status); +} + +/* PRIVATE FUNCTIONS */ + +/* + ************************************************************************* + * + * PCX_READ_INIT - Initialize PCX Workblock For Reading + * + * Purpose: To initialize a PCX image file workblock for reading. + * + * Setup: static BOOL pcx_read_init + * ( + * PCX_WORKBLK *wbp, + * int vmode, + * int page + * ) + * + * Where: wbp is a PCX workblock pointer. + * vmode is the MS-DOS video mode. Valid values are: + * + * PCX_HERC - 720 x 348 Hercules monochrome + * 0x04 - 320 x 200 4-color CGA + * 0x05 - 320 x 200 4-color CGA (color burst off) + * 0x06 - 640 x 200 2-color CGA + * 0x0d - 320 x 200 16-color EGA/VGA + * 0x0e - 640 x 200 16-color EGA/VGA + * 0x0f - 640 x 350 2-color EGA/VGA + * 0x10 - 640 x 350 16-color EGA/VGA + * 0x11 - 640 x 480 2-color VGA + * 0x12 - 640 x 480 16-color VGA + * 0x13 - 320 x 200 256-color VGA + * + * page is the video display page number. Valid values are: + * + * Mode PCX_HERC - 0 or 1 + * Mode 0x0d - 0 to 7 + * Mode 0x0e - 0 to 3 + * Mode 0x0f - 0 or 1 + * Mode 0x10 - 0 or 1 + * All Other - 0 + * + * Return: TRUE if successful; otherwise FALSE. + * + ************************************************************************* + */ + +static BOOL pcx_read_init +( + PCX_WORKBLK *wbp, + int vmode, + int page +) +{ + int width; /* Display width */ + int leftover; /* Number of unseen bits */ + BOOL status = TRUE; /* Return status */ + + /* Read the file header */ + + if ((pcx_read_header(wbp)) == FALSE) + return (FALSE); + + /* Initialize the workblock color palette pointer */ + + wbp->palettep = wbp->header.palette; + wbp->epal_flag = FALSE; + + /* Read the extended palette (if any) */ + + if (vmode == 0x13 && wbp->header.version == 5) + if (pcx_read_extpal(wbp) == FALSE) + return (FALSE); + + /* Initialize the display page address offset */ + + wbp->page_offset = (unsigned long) 0L; + + switch (vmode) /* Select PCX line display function */ + { + case PCX_HERC: /* 720 x 348 Hercules monochrome */ + + /* Hercules monochrome display adapter supports 2 pages */ + + wbp->page_offset = 0x08000000L * (unsigned long) page; + + /* Calculate display width in pixels */ + + width = min((wbp->header.xlr - wbp->header.xul + 1), 720); + + /* Calculate number of bytes to display */ + + wbp->num_bytes = (width + 7) >> 3; + + /* Calculate mask for leftover bits */ + + if ((leftover = width & 7) != 0) + wbp->mask = (0xff << (8 - leftover)) & 0xff; + else + wbp->mask = 0xff; + + wbp->pcx_funcp = pcx_put_herc; /* Set the display function ptr */ + + break; + + case 0x04: /* 320 x 200 4-color CGA */ + case 0x05: /* 320 x 200 4-color CGA (color burst off) */ + + /* Calculate display width in pixels */ + + width = min((wbp->header.xlr - wbp->header.xul + 1), 320); + + /* Calculate number of bytes to display */ + + wbp->num_bytes = (width + 3) >> 2; + + /* Calculate mask for leftover bits */ + + if ((leftover = (width & 3) << 1) != 0) + wbp->mask = (0xff << (8 - leftover)) & 0xff; + else + wbp->mask = 0xff; + + wbp->pcx_funcp = pcx_put_cga; /* Set the display function ptr */ + + break; + + case 0x06: /* 640 x 200 2-color CGA */ + + /* Calculate display width in pixels */ + + width = min((wbp->header.xlr - wbp->header.xul + 1), 640); + + /* Calculate number of bytes to display */ + + wbp->num_bytes = (width + 7) >> 3; + + /* Calculate mask for leftover bits */ + + if ((leftover = width & 7) != 0) + wbp->mask = (0xff << (8 - leftover)) & 0xff; + else + wbp->mask = 0xff; + + wbp->pcx_funcp = pcx_put_cga; /* Set the display function ptr */ + + break; + + case 0x0d: /* 320 x 200 16-color EGA/VGA */ + case 0x0e: /* 640 x 200 16-color EGA/VGA */ + case 0x0f: /* 640 x 350 2-color EGA/VGA */ + case 0x10: /* 640 x 350 16-color EGA/VGA */ + case 0x11: /* 640 x 480 2-color VGA */ + case 0x12: /* 640 x 480 16-color VGA */ + + switch (vmode) /* Initialize the display adapter page offset */ + { + case 0x0d: /* 320 x 200 16-color EGA/VGA (8 pages maximum) */ + + wbp->page_offset = 0x02000000L * (unsigned long) page; + + break; + + case 0x0e: /* 640 x 200 16-color EGA/VGA (4 pages maximum) */ + + wbp->page_offset = 0x04000000L * (unsigned long) page; + + break; + + case 0x0f: /* 640 x 350 2-color EGA/VGA (2 pages maximum) */ + case 0x10: /* 640 x 350 16-color EGA/VGA (2 pages maximum) */ + + wbp->page_offset = 0x08000000L * (unsigned long) page; + + break; + + default: /* All other modes support only one page */ + + break; + } + + /* Calculate display width in pixels */ + + width = min((wbp->header.xlr - wbp->header.xul + 1), 640); + + /* Calculate number of bytes to display */ + + wbp->num_bytes = (width + 7) >> 3; + + /* Calculate mask for leftover bits */ + + if ((leftover = width & 7) != 0) + wbp->mask = (0xff << (8 - leftover)) & 0xff; + else + wbp->mask = 0xff; + + wbp->pcx_funcp = pcx_put_ega; /* Set the display function ptr */ + + break; + + case 0x13: /* 320 x 200 256-color VGA */ + + /* Calculate number of bytes to display */ + + wbp->num_bytes = min((wbp->header.xlr - wbp->header.xul + 1), 320); + + wbp->mask = 0; /* Dummy parameter */ + + wbp->pcx_funcp = pcx_put_vga; /* Set the display function ptr */ + + break; + + default: /* Other display adapters not supported */ + + status = FALSE; + + break; + } + + return (status); +} + +/* + ************************************************************************* + * + * PCX_READ_HEADER - Read PCX File Header + * + * Purpose: To read and validate a PCX file header. + * + * Setup: static BOOL pcx_read_header + * ( + * PCX_WORKBLK *wbp + * ) + * + * Where: wbp is a PCX image file workblock pointer. + * + * Return: TRUE if successful; otherwise FALSE. + * + * Result: The file header is read into the "header" member of the + * PCX workblock. + * + ************************************************************************* + */ + +static BOOL pcx_read_header +( + PCX_WORKBLK *wbp +) +{ + BOOL status = TRUE; /* Status flag */ + PCX_HDR *hdrp; /* PCX file header buffer pointer */ + + hdrp = &(wbp->header); /* Initialize the file header pointer */ + + /* Read the file header */ + + if (fseek(wbp->fp, 0L, SEEK_SET) != 0) + status = FALSE; + + if (status == TRUE) + if (fread(hdrp, sizeof(PCX_HDR), 1, wbp->fp) != 1) + status = FALSE; + + /* Validate the PCX file format */ + + if (status == TRUE) + if ((hdrp->pcx_id != 0x0a) || (hdrp->encoding != 1)) + status = FALSE; + + return (status); +} + +/* + ************************************************************************* + * + * PCX_READ_EXTPAL - Read Extended Palette + * + * Purpose: To read an extended (256-color) palette (if it exists). + * + * Setup: static BOOL pcx_read_extpal + * ( + * PCX_WORKBLK *wbp + * ) + * + * Where: wbp is a PCX image file workblock pointer. + * + * Return: TRUE if successful; otherwise FALSE. + * + * Note: It is possible for a PCX image file without an appended + * 256-color palette to have the value 0x0c as the 769th byte + * (the location of the extended palette indicator byte) from + * the end of the file (i.e. - in the encoded image data + * section). This function will misinterpret the following + * 768 bytes of encoded image data as an extended palette. + * + * This problem will only occur if an attempt is made to + * display a PCX image using the wrong MS-DOS video mode. It + * can be detected by decoding the image data and using + * "ftell" to note the file position of the end of the + * encoded image data section, then comparing it to the file + * position of the indicator byte. If the supposed indicator + * byte is located within the encoded image data section, the + * indicator byte is invalid and so the file header palette + * should be used instead. + * + ************************************************************************* + */ + +static BOOL pcx_read_extpal +( + PCX_WORKBLK *wbp +) +{ + int indicator; /* PCX extended palette indicator */ + + /* Position the file pointer to the extended palette indicator byte */ + + if (fseek(wbp->fp, -769L, SEEK_END) != 0) + return (FALSE); + + /* Read the (assumed) extended palette indicator byte */ + + if ((indicator = getc(wbp->fp)) == EOF) + return (FALSE); + + if (indicator == PCX_EPAL_FLAG) /* Check for indicator byte */ + { + /* Allocate an extended palette buffer */ + + if ((wbp->palettep = (PCX_PAL *) calloc(sizeof(PCX_PAL), + PCX_EPAL_SIZE)) == (PCX_PAL *) NULL) + return (FALSE); + + /* Read the extended palette */ + + if (fread(wbp->palettep, sizeof(PCX_PAL), PCX_EPAL_SIZE, wbp->fp) != + PCX_EPAL_SIZE) + { + free(wbp->palettep); /* Free the extended palette buffer */ + return (FALSE); + } + + wbp->epal_flag = TRUE; /* Indicate extended palette present */ + } + + return (TRUE); +} + +/* + ************************************************************************* + * + * PCX_READ_LINE - Read PCX Line + * + * Purpose: To read an encoded line (all color planes) from a PCX- + * format image file and write the decoded data to a line + * buffer. + * + * Setup: static BOOL pcx_read_line + * ( + * PCX_WORKBLK *wbp, + * unsigned char *linep, + * int bpline + * ) + * + * Where: wbp is a PCX image file workblock pointer. + * linep is a PCX scan line buffer pointer. + * bpline is the number of bytes per scan line (all color + * planes). + * + * Return: TRUE if successful; otherwise FALSE. + * + ************************************************************************* + */ + +static BOOL pcx_read_line +( + PCX_WORKBLK *wbp, + unsigned char *linep, + int bpline +) +{ + int data; /* Image data byte */ + int count; /* Image data byte repeat count */ + int offset = 0; /* Scan line buffer offset */ + + while (offset < bpline) /* Decode current scan line */ + { + if ((data = getc(wbp->fp)) == EOF) /* Get next byte */ + return (FALSE); + + /* If top two bits of byte are set, lower six bits show how */ + /* many times to duplicate next byte */ + + if ((data & PCX_COMP_FLAG) == PCX_COMP_FLAG) + { + count = data & PCX_COMP_MASK; /* Mask off repeat count */ + + if ((data = getc(wbp->fp)) == EOF) /* Get next byte */ + return (FALSE); + + memset(linep, data, count); /* Duplicate byte */ + linep += count; + offset += count; + } + else + { + *linep++ = (unsigned char) data; /* Copy byte */ + offset++; + } + } + + return (TRUE); +} + +/* + ************************************************************************* + * + * PCX_SET_PALETTE - Set Palette + * + * Purpose: To set the display palette according to a PCX file + * palette. + * + * Setup: static BOOL pcx_set_palette + * ( + * PCX_PAL *palettep, + * int vmode + * ) + * + * Where: palettep is a pointer to a PCX file palette. + * vmode is the MS-DOS video mode. Valid values are: + * + * PCX_HERC - 720 x 348 Hercules monochrome + * 0x04 - 320 x 200 4-color CGA + * 0x05 - 320 x 200 4-color CGA (color burst off) + * 0x06 - 640 x 200 2-color CGA + * 0x0d - 320 x 200 16-color EGA/VGA + * 0x0e - 640 x 200 16-color EGA/VGA + * 0x0f - 640 x 350 2-color EGA/VGA + * 0x10 - 640 x 350 16-color EGA/VGA + * 0x11 - 640 x 480 2-color VGA + * 0x12 - 640 x 480 16-color VGA + * 0x13 - 320 x 200 256-color VGA + * + * Return: TRUE if successful; otherwise FALSE. + * + ************************************************************************* + */ + +static BOOL pcx_set_palette +( + PCX_PAL *palettep, + int vmode +) +{ + int i; /* Scratch counter */ + int red_lo; /* Low red intensity */ + int red_hi; /* High red intensity */ + int green_lo; /* Green low intensity */ + int green_hi; /* Green high intensity */ + int blue_lo; /* Blue low intensity */ + int blue_hi; /* Blue high intensity */ + unsigned char *ega_palp; /* EGA 16-color palette buffer pointer */ + unsigned long *vga_palp; /* VGA 256-color palette buffer pointer */ + BOOL status = TRUE; /* Return status */ + union REGS regs; /* 80x86 register values */ + struct SREGS sregs; /* 80x86 segment register values */ + + switch (vmode) + { + case PCX_HERC: /* 720 x 348 Hercules monochrome */ + + break; + + case 0x04: /* 320 x 200 4-color CGA display */ + case 0x05: /* 320 x 200 monochrome CGA display (burst off) */ + case 0x06: /* 640 x 200 2-color CGA display */ + + /* Set the CGA color palette */ + + pcx_cga_palette(palettep, vmode); + + break; + + case 0x0d: /* 320 x 200 16-color EGA/VGA */ + case 0x0e: /* 640 x 200 16-color EGA/VGA */ + case 0x0f: /* 640 x 350 2-color EGA/VGA */ + case 0x10: /* 640 x 350 16-color EGA/VGA */ + case 0x11: /* 640 x 480 2-color VGA */ + case 0x12: /* 640 x 480 16-color VGA */ + + if (pcx_isvga() == TRUE) /* Check for VGA display adapter */ + { + /* Allocate a 16-color VGA display adapter palette buffer */ + + if ((vga_palp = (unsigned long *) calloc(sizeof(unsigned long), + PCX_PAL_SIZE)) == (unsigned long *) NULL) + { + status = FALSE; + break; + } + + /* Map PCX hardware palette to 16-color VGA palette (each color */ + /* value is a "long" with the form: */ + /* */ + /* 00000000-00BBBBBB-00GGGGGG-00RRRRRR */ + /* */ + /* where each color is a 6-bit value. */ + + for (i = 0; i < PCX_PAL_SIZE; i++) + vga_palp[i] = (long) (palettep[i].red >> 2) | + ((long) (palettep[i].green >> 2)) << 8 | + ((long) (palettep[i].blue >> 2)) << 16; + + (void) _remapallpalette(vga_palp); /* Remap entire palette */ + + free(vga_palp); /* Free the VGA palette buffer */ + } + else /* EGA display adapter */ + { + /* Allocate an EGA display adapter palette buffer */ + + if ((ega_palp = (unsigned char *) calloc(sizeof(unsigned char), + PCX_PAL_SIZE + 1)) == (unsigned char *) NULL) + { + status = FALSE; + break; + } + + /* Map PCX hardware palette to 16-color EGA palette (each EGA */ + /* color value is an "unsigned char" with the form: */ + /* */ + /* 0 0 R' G' B' R G B */ + /* */ + /* where X' is the low-intensity value and X is the high */ + /* intensity value for the color X.) */ + /* */ + /* NOTE: the "_remapallpalette" function could be used to set */ + /* the palette for EGA display adapters. However, this */ + /* function does not appear to update the palette */ + /* register values in the Dynamic Save Area (see the */ + /* function header for "pcx_init_palette" in PCX_FILE.C) */ + /* for a detailed explanation). */ + + for (i = 0; i < PCX_PAL_SIZE; i++) + { + /* Extract low and high intensity bits for each color */ + + red_lo = (palettep[i].red >> 6) & 0x01; + red_hi = (palettep[i].red >> 6) & 0x02; + green_lo = (palettep[i].green >> 6) & 0x01; + green_hi = (palettep[i].green >> 6) & 0x02; + blue_lo = (palettep[i].blue >> 6) & 0x01; + blue_hi = (palettep[i].blue >> 6) & 0x02; + + /* Combine color intensity bits for EGA palette value */ + + ega_palp[i] = (unsigned char) ((red_lo << 5) | (green_lo << 4) | + (blue_lo << 3) | (red_hi << 1) | green_hi | (blue_hi >> + 1)); + } + + /* Set the border (overscan) color to black (BIOS default) */ + + ega_palp[16] = (unsigned char) 0; + + regs.h.ah = 0x10; /* Select "Set All Palette Registers" */ + regs.h.al = 0x02; + + /* Get the EGA palette registers buffer offset value */ + + regs.x.dx = (unsigned int) ega_palp; + + segread(&sregs); /* Get the current DS segment register value */ + + sregs.es = sregs.ds; + + int86x(0x10, ®s, ®s, &sregs); /* Call BIOS video service */ + + free(ega_palp); /* Free the EGA palette buffer */ + } + + break; + + case 0x13: /* 320 x 200 256-color VGA display */ + + /* Allocate a 256-color VGA display adapter palette buffer */ + + if ((vga_palp = (unsigned long *) calloc(sizeof(unsigned long), + PCX_EPAL_SIZE)) == (unsigned long *) NULL) + { + status = FALSE; + break; + } + + /* Map PCX extended palette to 256-color VGA palette */ + + for (i = 0; i < PCX_EPAL_SIZE; i++) + vga_palp[i] = (long) (palettep[i].red >> 2) | + ((long) (palettep[i].green >> 2)) << 8 | + ((long) (palettep[i].blue >> 2)) << 16; + + (void) _remapallpalette(vga_palp); /* Remap entire palette */ + + free(vga_palp); /* Free the VGA palette buffer */ + + break; + + default: /* Other modes not supported */ + + status = FALSE; + + break; + } + + return (status); +} + +/* + ************************************************************************* + * + * PCX_CGA_PALETTE - Select CGA Palette + * + * Purpose: To set the Color Graphics Adapter (CGA) display palette + * according to a PCX file palette. + * + * Setup: static void pcx_cga_palette + * ( + * PCX_PAL *palettep, + * int vmode + * ) + * + * Where: palettep is a pointer to a PCX file palette. + * vmode is the MS-DOS video mode. Valid values are: + * + * 0x04 - 320 x 200 4-color CGA + * 0x05 - 320 x 200 4-color CGA (color burst off) + * 0x06 - 640 x 200 2-color CGA + * + * Note: ZSoft's PC Paintbrush products no longer support the CGA + * color palette. When a CGA color palette is encountered, + * PC Paintbrush maps it to a monochrome (black and white) + * palette. + * + * MS-DOS video mode 0x05 (320 x 200 monochrome CGA display, + * color burst off) will only display a monochrome image on + * a composite video monitor (typically a television set with + * an RF adapter). All other monitors will display a color + * palette in this mode (which is different for CGA and EGA + * or VGA display adapters). + * + * The "background" color is actually the foreground color + * (i.e. - the color of activated pixels) for MS-DOS video + * mode 0x06. The background color is black for CGA display + * adapters. + * + ************************************************************************* + */ + +static void pcx_cga_palette +( + PCX_PAL *palettep, + int vmode +) +{ + short pal_num; /* Palette number */ + BOOL sel_flag; /* Palette selector bit flag */ + BOOL int_flag; /* Intensity bit flag */ + union REGS regs; /* 80x86 register values */ + + /* Set the background color */ + + regs.h.ah = 0x0b; /* Select "Set Color Palette" BIOS routine */ + regs.h.bh = 0; + + regs.h.bl = (unsigned char) PCX_CGA_BKGND(palettep); + + int86(0x10, ®s, ®s); /* Call BIOS video service */ + + if (vmode != 0x06) /* Select the CGA color palette */ + { + /* Check the palette selector bit flag */ + + sel_flag = PCX_CGA_SELECT(palettep) ? TRUE : FALSE; + + /* Check the intensity bit flag */ + + int_flag = PCX_CGA_INTENSITY(palettep) ? TRUE : FALSE; + + /* Determine the CGA palette number */ + + if (int_flag == TRUE) /* Intensity = bright */ + { + if (sel_flag == TRUE) + pal_num = 3; /* Light cyan - light magenta - white */ + else + pal_num = 1; /* Cyan - magenta - light grey */ + } + else /* Intensity = dim */ + { + if (sel_flag == TRUE) + pal_num = 2; /* Light green - light red - yellow */ + else + pal_num = 0; /* Green - red - brown */ + } + + /* Select the foreground color palette */ + + (void) _selectpalette(pal_num); + } +} + +/* + ************************************************************************* + * + * PCX_PUT_HERC - Display Hercules PCX Line + * + * Purpose: To copy a decoded PCX image scan line to a Hercules + * monochrome graphics display adapter buffer. + * + * Setup: static void pcx_put_herc + * ( + * PCX_WORKBLK *wbp, + * unsigned char _far *linep, + * int line_num + * ) + * + * Where: wbp is a PCX image file workblock pointer. + * linep is a PCX scan line buffer pointer. + * line_num is the scan line number. + * + ************************************************************************* + */ + +void pcx_put_herc +( + PCX_WORKBLK *wbp, + unsigned char _far *linep, + int line_num +) +{ + unsigned char _far *displayp; /* Display buffer pointer */ + + /* Mask off unseen pixels */ + + linep[wbp->num_bytes - 1] &= wbp->mask; + + /* Calculate Hercules display buffer pointer */ + + displayp = (unsigned char _far *) (0xb0000000L + wbp->page_offset) + + ((line_num >> 2) * 90) + 0x2000 * (line_num & 3); + + /* Copy data from the scan line buffer to the Hercules display buffer */ + + (void) _fmemcpy(displayp, linep, wbp->num_bytes); +} + +/* + ************************************************************************* + * + * PCX_PUT_CGA - Display CGA PCX Line + * + * Purpose: To copy a decoded PCX image scan line to a CGA display + * adapter buffer. + * + * Setup: static void pcx_put_cga + * ( + * PCX_WORKBLK *wbp, + * unsigned char _far *linep, + * int line_num + * ) + * + * Where: wbp is a PCX image file workblock pointer. + * linep is a PCX scan line buffer pointer. + * line_num is the scan line number. + * + ************************************************************************* + */ + +static void pcx_put_cga +( + PCX_WORKBLK *wbp, + unsigned char _far *linep, + int line_num +) +{ + unsigned char _far *displayp; /* Display buffer pointer */ + + /* Mask off unseen pixels */ + + linep[wbp->num_bytes - 1] &= wbp->mask; + + /* Calculate CGA display buffer pointer */ + + displayp = (unsigned char _far *) 0xb8000000L + ((line_num >> 1) * 80) + + 0x2000 * (line_num & 1); + + /* Copy data from the scan line buffer to the CGA display buffer */ + + (void) _fmemcpy(displayp, linep, wbp->num_bytes); +} + +/* + ************************************************************************* + * + * PCX_PUT_EGA - Display EGA/VGA PCX Line + * + * Purpose: To copy a decoded PCX image scan line to an EGA/VGA + * display adapter buffer. + * + * Setup: static void pcx_put_ega + * ( + * PCX_WORKBLK *wbp, + * unsigned char _far *linep, + * int line_num + * ) + * + * Where: wbp is a PCX image file workblock pointer. + * linep is a PCX scan line buffer pointer. + * line_num is the scan line number. + * + ************************************************************************* + */ + +static void pcx_put_ega +( + PCX_WORKBLK *wbp, + unsigned char _far *linep, + int line_num +) +{ + int plane_num; /* EGA/VGA color plane number */ + int plane_mask; /* EGA/VGA color plane mask */ + unsigned char _far *displayp; /* Display buffer pointer */ + + /* Calculate buffer pointer */ + + displayp = (unsigned char _far *) (0xa0000000L + wbp->page_offset) + + line_num * 80; + + outpw(0x03ce, 0x0005); /* Select EGA/VGA write mode 0 */ + + /* Copy PCX scan line data to each color plane */ + + plane_mask = 0x0100; /* Start with color plane 0 */ + + for (plane_num = 0; plane_num < (int) wbp->header.nplanes; plane_num++) + { + /* Mask off unseen pixels */ + + linep[wbp->num_bytes - 1] &= wbp->mask; + + outpw(0x03c4, plane_mask + 2); /* Select current color plane */ + + /* Copy data from the scan line buffer to the EGA/VGA display */ + + (void) _fmemcpy(displayp, linep, wbp->num_bytes); + + linep += wbp->header.bppscan; /* Increment plane offset */ + + plane_mask <<= 1; /* Sequence plane mask */ + } + + outpw(0x03c4, 0x0f02); /* Select all color planes */ +} + +/* + ************************************************************************* + * + * PCX_PUT_VGA - Display VGA PCX Line + * + * Purpose: To copy a decoded PCX image scan line to a VGA display + * adapter buffer. + * + * Setup: static void pcx_put_vga + * ( + * PCX_WORKBLK *wbp, + * unsigned char _far *linep, + * int line_num + * ) + * + * Where: wbp is a PCX image file workblock pointer. + * linep is a PCX scan line buffer pointer. + * line_num is the scan line number. + * + ************************************************************************* + */ + +static void pcx_put_vga +( + PCX_WORKBLK *wbp, + unsigned char _far *linep, + int line_num +) +{ + unsigned char _far *displayp; /* Display buffer pointer */ + + /* Calculate buffer pointer */ + + displayp = (unsigned char _far *) 0xa0000000L + line_num * 320; + + /* Copy data from the scan line buffer to the VGA display buffer */ + + (void) _fmemcpy(displayp, linep, wbp->num_bytes); +} + diff --git a/16/PCX_LIB/PCX_EXAM.C b/16/PCX_LIB/PCX_EXAM.C new file mode 100644 index 00000000..556f0f00 --- /dev/null +++ b/16/PCX_LIB/PCX_EXAM.C @@ -0,0 +1,339 @@ +/* + ************************************************************************* + * + * PCX_EXAM.C - PCX_LIB File Header Examination Utility + * + * Version: 1.00B + * + * History: 91/02/14 - Created + * 91/04/01 - Release 1.00A + * 91/04/06 - Release 1.00B + * + * Compiler: Microsoft C V6.0 + * + * Author: Ian Ashdown, P.Eng. + * byHeart Software + * 620 Ballantree Road + * West Vancouver, B.C. + * Canada V7S 1W3 + * Tel. (604) 922-6148 + * Fax. (604) 987-7621 + * + * Copyright: Public Domain + * + ************************************************************************* + */ + +/* + ************************************************************************* + * + * PORTABILITY NOTES + * + * 1. When porting this program to other processors, remember that words + * are stored by 80x86-based machines in the big-endian format. That + * is, the eight least significant bits (lower byte) are stored + * first, followed by the eight most significant bits (upper byte). + * If PCX-format files are transferred to little-endian machines + * (such as those based on 680x0 and Z8000 processors), the order of + * bytes within each word will have to be reversed before they can + * be interpreted. (This applies to the file header only, since the + * encoded image data and optional 256-color palette are stored as + * bytes.) + * + ************************************************************************* + */ + +/* INCLUDE FILES */ + +#include +#include +#include "pcx_int.h" + +/* FORWARD REFERENCES */ + +/* GLOBALS */ + +/* PUBLIC FUNCTIONS */ + +/* + ************************************************************************* + * + * MAIN - Executive Function + * + * Purpose: To read and display a PCX-format image file header. + * + * Setup: int main + * ( + * int argc, + * char **argv + * ) + * + * Where: argc is the number of command-line arguments. + * argv is a pointer to an array of command-line argument + * strings. + * + * Return: 0 if successful; otherwise 2. + * + * Result: The file header information is written to "stdout". + * + * Note: Usage is: + * + * PCX_EXAM filename + * + * where "filename" is the name of a PCX-format image file. + * + ************************************************************************* + */ + +int main +( + int argc, + char **argv +) +{ + char *vers; /* Version number string pointer */ + char *pal_type; /* Palette type string pointer */ + int range; /* Palette range */ + int indicator; /* Extended palette indicator byte */ + BOOL status = TRUE; /* Return status */ + BOOL ep_flag = FALSE; /* Extended palette flag */ + FILE *fp; /* File pointer */ + PCX_HDR *hdrp; /* File header structure pointer */ + PCX_PAL *ext_palettep; /* Extended palette pointer */ + + /* Display program title */ + + puts("\nPCX_EXAM - PCX Image File Examination Utility\n"); + + /* Check for filename */ + + if (argc < 2) + { + /* Display usage information */ + + fputs(" Synopsis: This public domain utility displays inf", stderr); + fputs("ormation contained in the\n header of a ", stderr); + fputs("Paintbrush (R) PCX-format image file.\n\n Usage: ", stderr); + fputs(" PCX_EXAM filename\n\n Example: PCX_EXAM picture", stderr); + fputs(".pcx\n", stderr); + + return (2); + } + + /* Allocate a PCX file header buffer */ + + if ((hdrp = (PCX_HDR *) malloc(sizeof(PCX_HDR))) == (PCX_HDR *) NULL) + { + fputs("ERROR: out of memory\n", stderr); + return (2); + } + + /* Open the PCX image file in binary mode */ + + if ((fp = fopen(argv[1], "rb")) == (FILE *) NULL) + { + fprintf(stderr, "ERROR: cannot open file %s\n", argv[1]); + + free(hdrp); /* Free the file header memory */ + + return (2); + } + + /* Read the file header */ + + if (status == TRUE) + if (fseek(fp, 0L, SEEK_SET) != 0) + { + fprintf(stderr, "ERROR: cannot read file %s\n", argv[1]); + status = FALSE; + } + + if (status == TRUE) + if (fread(hdrp, sizeof(PCX_HDR), 1, fp) != 1) + { + fprintf(stderr, "ERROR: cannot read file %s\n", argv[1]); + status = FALSE; + } + + /* Validate the PCX file format */ + + if (status == TRUE) + if ((hdrp->pcx_id != 0x0a) || (hdrp->encoding != 1)) + { + fprintf(stderr, "ERROR: file %s not valid PCX format\n", argv[1]); + status = FALSE; + } + + /* Determine the version number */ + + switch (hdrp->version) + { + case 0: + + vers = "PC Paintbrush 2.5"; + + break; + + case 2: + + vers = "PC Paintbrush 2.8 (with palette information)"; + + break; + + case 3: + + vers = "PC Paintbrush 2.8 (without palette information)"; + + break; + + case 4: + + vers = "PC Paintbrush for Windows (not 3.0)"; + + break; + + case 5: + + vers = "PC Paintbrush 3.0 and greater"; + + break; + + default: + + vers = "Unknown version"; + + break; + } + + /* Display the PCX file header information */ + + printf("PCX filename: %s\n", argv[1]); + printf("Version: %s\n", vers); + printf("Encoding: %s\n", hdrp->encoding == 1 ? "Run length" : + "Unknown"); + printf("%d bits per pixel\n", hdrp->bppixel); + printf("Image from (%d, %d) to (%d, %d) pixels.\n", hdrp->xul, + hdrp->yul, hdrp->xlr, hdrp->ylr); + printf("Created on a device with %d x %d dpi resolution\n", + hdrp->horz_res, hdrp->vert_res); + printf("Number of color planes: %d\n", hdrp->nplanes); + printf("Bytes per color plane scan line: %d\n", hdrp->bppscan); + + switch (hdrp->palette_type & PCX_PAL_MASK) + { + case 1: + + pal_type = "color or B&W"; + + break; + + case 2: + + pal_type = "grayscale"; + + break; + + default: + + pal_type = "unknown"; + + break; + } + + printf("Palette type: %s\n", pal_type); + + /* Check for extended (256-color) palette */ + + if (hdrp->version == 5) + { + /* Check for valid palette indicator byte */ + + if (fseek(fp, -769L, SEEK_END) != 0) + { + fprintf(stderr, "ERROR: cannot read file %s\n", argv[1]); + status = FALSE; + } + + if (status == TRUE) + { + if ((indicator = getc(fp)) == PCX_EPAL_FLAG) + { + /* Allocate an extended palette buffer */ + + if ((ext_palettep = (PCX_PAL *) calloc(sizeof(PCX_PAL), + PCX_EPAL_SIZE)) == (PCX_PAL *) NULL) + { + fputs("ERROR: out of memory\n", stderr); + status = FALSE; + } + + /* Read the extended palette */ + + if (status == TRUE) + { + if (fread(ext_palettep, sizeof(PCX_PAL), PCX_EPAL_SIZE, fp) != + PCX_EPAL_SIZE) + { + free(ext_palettep); /* Free extended palette buffer */ + status = FALSE; + } + } + + ep_flag = TRUE; /* Indicate extended palette exists */ + } + } + } + + if (status == TRUE) + if (ep_flag == TRUE) + { + /* Display extended (256-color) palette */ + + puts("Extended 256-color palette:\n"); + + puts("COLOR RED GREEN BLUE\n"); + + for (range = 0; range < PCX_EPAL_SIZE; range++) + printf(" %03d %2x %2x %2x\n", range, + ext_palettep[range].red, ext_palettep[range].green, + ext_palettep[range].blue); + + putchar('\n'); + + free(ext_palettep); /* Free the extended palette */ + } + else + { + /* Display file header palette */ + + puts("File header color palette:\n"); + + printf("RED ... "); + + for (range = 0; range < PCX_PAL_SIZE; range++) + printf("%2x ", hdrp->palette[range].red); + + printf("\nGREEN ... "); + + for (range = 0; range < PCX_PAL_SIZE; range++) + printf("%2x ", hdrp->palette[range].green); + + printf("\nBLUE ... "); + + for (range = 0; range < PCX_PAL_SIZE; range++) + printf("%2x ", hdrp->palette[range].blue); + + putchar('\n'); + } + + if (fclose(fp) == EOF) /* Close the file */ + { + fprintf(stderr, "Error: cannot close file %s\n", argv[1]); + status = FALSE; + } + + free (hdrp); /* Free the file header buffer */ + + return (0); +} + diff --git a/16/PCX_LIB/PCX_EXAM.EXE b/16/PCX_LIB/PCX_EXAM.EXE new file mode 100644 index 0000000000000000000000000000000000000000..ddbc98805b7f3a2b9bf669d7e27bac9cefb1071d GIT binary patch literal 11193 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 aU`+4_%r&6_$pi&wrG9_KwvnX_!}vEtuKr&D literal 0 HcmV?d00001 diff --git a/16/PCX_LIB/PCX_EXT.H b/16/PCX_LIB/PCX_EXT.H new file mode 100644 index 00000000..78dbcf18 --- /dev/null +++ b/16/PCX_LIB/PCX_EXT.H @@ -0,0 +1,66 @@ +/* + ************************************************************************* + * + * PCX_EXT.H - PCX_LIB Library External Definitions Include File + * + * Version: 1.00B + * + * History: 91/02/14 - Created + * 91/04/01 - Release 1.00A + * 91/04/07 - Release 1.00B + * + * Compiler: Microsoft C V6.0 + * + * Author: Ian Ashdown, P.Eng. + * byHeart Software + * 620 Ballantree Road + * West Vancouver, B.C. + * Canada V7S 1W3 + * Tel. (604) 922-6148 + * Fax. (604) 987-7621 + * + * Copyright: Public Domain + * + ************************************************************************* + */ + +/* DEFINITIONS */ + +#define _PCX_EXT_H 1 + +#define FALSE 0 +#define TRUE 1 + +typedef int BOOL; /* Boolean flag */ + +/* STRUCTURE DECLARATIONS */ + +typedef struct pcx_vsb /* BIOS video services data save buffer */ +{ + struct pcx_ppt /* Primary Pointer Table */ + { + void _far *vptp; /* Video Parameter Table pointer */ + unsigned char _far *dsap; /* Dynamic Save Area pointer */ + void _far *tmacgp; /* Text Mode Aux Char Generator pointer */ + void _far *gmacgp; /* Graphics Mode Aux Char Generator ptr */ + void _far *sptp; /* Secondary Pointer Table pointer */ + void _far *rsv_1; /* Reserved */ + void _far *rsv_2; /* Reserved */ + } + pcx_ppt; + + /* Previous Primary Pointer Table pointer */ + + struct pcx_ppt _far *prev_pptp; +} +PCX_VSB; + +/* FUNCTIONS PROTOTYPES */ + +extern BOOL pcx_init_dsa(PCX_VSB **); +extern BOOL pcx_isvga(void); +extern BOOL pcx_read(char *, int, int); +extern BOOL pcx_write(char *, int, int, int, int); + +extern void pcx_free_dsa(PCX_VSB *); + diff --git a/16/PCX_LIB/PCX_FILE.C b/16/PCX_LIB/PCX_FILE.C new file mode 100644 index 00000000..8e4162c0 --- /dev/null +++ b/16/PCX_LIB/PCX_FILE.C @@ -0,0 +1,1379 @@ +/* + ************************************************************************* + * + * PCX_FILE.C - PCX_LIB Library Image File Functions + * + * Version: 1.00B + * + * History: 91/02/14 - Created + * 91/04/01 - Release 1.00A + * 91/04/03 - fixed "segread" call. + * 91/04/07 - Release 1.00B + * + * Compiler: Microsoft C V6.0 + * + * Author: Ian Ashdown, P.Eng. + * byHeart Software + * 620 Ballantree Road + * West Vancouver, B.C. + * Canada V7S 1W3 + * Tel. (604) 922-6148 + * Fax. (604) 987-7621 + * + * Copyright: Public Domain + * + ************************************************************************* + */ + +/* + ************************************************************************* + * + * PORTABILITY NOTES + * + * 1. While this program is written in ANSI C, it uses a number of + * function calls that are specific to the Microsoft C V6.0 library. + * These are documented as follows for the purposes of porting this + * program to other compilers and/or processors: + * + * _ffree - "free" for small model / far data + * _fmalloc - "malloc" for small model / far data + * _fmemcpy - "memcpy" for small model / far data + * int86 - execute 80x86 interrupt routine + * int86x - execute 80x86 interrupt routine (far data) + * outpw - output word to 80x86 I/O port + * segread - get current 80x86 segment register values + * + * 2. When porting this program to other processors, remember that words + * are stored by 80x86-based machines in the big-endian format. That + * is, the eight least significant bits (lower byte) are stored + * first, followed by the eight most significant bits (upper byte). + * If PCX-format files are transferred to little-endian machines + * (such as those based on 680x0 and Z8000 processors), the order of + * bytes within each word will have to be reversed before they can + * be interpreted. (This applies to the file header only, since the + * encoded image data and optional 256-color palette are stored as + * bytes.) + * + * 3. MS-DOS does not recognize the 720 x 348 graphics mode of the + * Hercules monochrome display adapter. Therefore, the constant + * PCX_HERC should never be passed as a video mode parameter to any + * BIOS service routine. + * + * The Microsoft C compiler includes a "video mode" parameter + * definition (_HERCMONO) that is defined as 0x08. This is a + * reserved MS-DOS video mode that is apparently used internally by + * the ROM BIOS. It can, however, be passed to the Microsoft C + * library function "_setvideomode" to force the Hercules display + * adapter into graphics mode. + * + * Most other MS-DOS C compilers offer similar library functions to + * force the Hercules monochrome display adapter into its 720 x 348 + * graphics mode. + * + ************************************************************************* + */ + +/* INCLUDE FILES */ + +#include +#include +#include +#include +#include +#include +#include +#include "pcx_int.h" + +/* FORWARD REFERENCES */ + +static BOOL pcx_encode(int, int, FILE *); +static BOOL pcx_init_palette(PCX_PAL *, int); +static BOOL pcx_write_extpal(FILE *); +static BOOL pcx_write_line(unsigned char *, int, FILE *); +static BOOL pcx_write_init(PCX_WORKBLK *, int, int, int, int); + +static void pcx_get_cga(PCX_WORKBLK *, unsigned char _far *, int); +static void pcx_get_ega(PCX_WORKBLK *, unsigned char _far *, int); +static void pcx_get_herc(PCX_WORKBLK *, unsigned char _far *, int); +static void pcx_get_vga(PCX_WORKBLK *, unsigned char _far *, int); + +/* GLOBALS */ + +/* Default EGA palette register values */ + +static BYTE pcx_EGA_DefPal_1[16] = /* Modes 0x0d and 0x0e */ +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17 +}; + +static BYTE pcx_EGA_DefPal_2[16] = /* Mode 0x0f */ +{ + 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00 +}; + +static BYTE pcx_EGA_DefPal_3[16] = /* Mode 0x10 */ +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f +}; + +/* PUBLIC FUNCTIONS */ + +/* + ************************************************************************* + * + * PCX_WRITE - Write PCX File + * + * Purpose: To write a PCX-format image file from an image stored in + * a video buffer. The image is assumed to start in the + * upper left corner of the screen. + * + * Setup: BOOL pcx_write + * ( + * char *fname, + * int vmode, + * int page, + * int width, + * int height, + * ) + * + * Where: fname is a PCX image file name. + * vmode is the MS-DOS video mode. Valid values are: + * + * PCX_HERC - 720 x 348 Hercules monochrome + * 0x04 - 320 x 200 4-color CGA + * 0x05 - 320 x 200 4-color CGA (color burst off) + * 0x06 - 640 x 200 2-color CGA + * 0x0d - 320 x 200 16-color EGA/VGA + * 0x0e - 640 x 200 16-color EGA/VGA + * 0x0f - 640 x 350 2-color EGA/VGA + * 0x10 - 640 x 350 16-color EGA/VGA + * 0x11 - 640 x 480 2-color VGA + * 0x12 - 640 x 480 16-color VGA + * 0x13 - 320 x 200 256-color VGA + * + * page is the video display page number. Valid values are: + * + * Mode PCX_HERC - 0 or 1 + * Mode 0x0d - 0 to 7 + * Mode 0x0e - 0 to 3 + * Mode 0x0f - 0 or 1 + * Mode 0x10 - 0 or 1 + * All Other - 0 + * + * width is the image width in pixels. + * height is the image height in pixels. + * + * Return: TRUE if successful; otherwise FALSE. + * + ************************************************************************* + */ + +BOOL pcx_write +( + char *fname, + int vmode, + int page, + int width, + int height +) +{ + int bpline; /* Number of bytes per scan line */ + int line_num; /* Scan line number */ + unsigned char *linep; /* Image scan line buffer pointer */ + BOOL status = TRUE; /* Return status */ + PCX_WORKBLK *wbp; /* PCX image file workblock pointer */ + + /* Open a PCX image file workblock */ + + if ((wbp = pcx_open(fname, TRUE)) == (PCX_WORKBLK *) NULL) + return (FALSE); + + /* Initialize the workblock for writing */ + + if (pcx_write_init(wbp, vmode, page, width, height) == FALSE) + status = FALSE; + + /* Calculate number of bytes per line (for all color planes) */ + + bpline = wbp->header.bppscan * wbp->header.nplanes; + + /* Allocate a scan line buffer */ + + if (status == TRUE) + if ((linep = (unsigned char *) malloc(bpline)) == (unsigned char *) + NULL) + status = FALSE; + + /* Write the file header to the file */ + + if (status == TRUE) + if (fwrite(&(wbp->header), sizeof(PCX_HDR), 1, wbp->fp) != 1) + status = FALSE; + + /* Write the encoded image data to the file */ + + if (status == TRUE) + { + for (line_num = 0; line_num <= (int) wbp->header.ylr; line_num++) + { + /* Get the current video buffer scan line */ + + wbp->pcx_funcp(wbp, (unsigned char _far *) linep, line_num); + + /* Encode the scan line and write it to the file */ + + if (pcx_write_line(linep, bpline, wbp->fp) == FALSE) + { + status = FALSE; + break; + } + } + } + + if (vmode == 0x13) /* Is a 256-color palette supported ? */ + { + /* Write the extended palette to the file */ + + if (status == TRUE) + if (pcx_write_extpal(wbp->fp) == FALSE) + status = FALSE; + } + + if (pcx_close(wbp) == FALSE) /* Close the PCX workblock */ + status = FALSE; + + free(linep); /* Free the scan line buffer */ + + /* Remove the PCX image file if an error occurred */ + + if (status == FALSE) + (void) remove(fname); + + return (status); +} + +/* + ************************************************************************* + * + * PCX_INIT_DSA - Initialize Dynamic Save Area + * + * Purpose: To set up a Video Services Primary Pointer Table and an + * associated Dynamic Save Area where BIOS service "Set All + * Palette Registers" (function 0x02) can store the EGA color + * palette registers settings after it updates them. + * + * Setup: BOOL pcx_init_dsa + * ( + * PCX_VSB **vsbpp + * ) + * + * Where: vsbp is a pointer to where a pointer to an instantiated + * PCX_VSB structure is to be returned. + * + * Return: TRUE if successful; otherwise FALSE. + * + * Note: The EGA display adapter color palette registers are + * write-only. In order to save the current color palette + * with a PCX-format image file by calling "pcx_write", you + * must call this function BEFORE you display the image in + * the following MS-DOS video modes: + * + * 0x0d - 320 x 200 16-color EGA + * 0x0e - 640 x 200 16-color EGA + * 0x0f - 640 x 350 2-color EGA + * 0x10 - 640 x 350 16-color EGA + * + * You MUST call "pcx_free_dsa" upon completion of your + * program. See the function header of "pcx_init_palette" + * for more information. + * + ************************************************************************* + */ + +BOOL pcx_init_dsa +( + PCX_VSB **vsbpp +) +{ + unsigned char _far *dsap; /* Dynamic Save Area pointer */ + PCX_VSB *vsbp; /* Video services data save buffer ptr */ + + *vsbpp = (PCX_VSB *) NULL; /* Initialize returned pointer */ + + /* Allocate a Dynamic Save Area buffer */ + + if ((dsap = (unsigned char _far *) _fmalloc(sizeof(unsigned char) * + 256)) == (unsigned char _far *) NULL) + return (FALSE); + + /* Allocate a BIOS video services data save buffer */ + + if ((vsbp = (PCX_VSB *) malloc(sizeof(PCX_VSB))) == (PCX_VSB *) NULL) + { + _ffree(dsap); /* Free the Dynamic Save Area buffer */ + return (FALSE); + } + + /* Save the existing Primary Pointer Table pointer */ + + vsbp->prev_pptp = *((struct pcx_ppt _far * _far *) 0x004000a8L); + + /* Copy the existing Primary Pointer Table into the buffer */ + + (void) _fmemcpy((struct pcx_ppt _far *) &(vsbp->pcx_ppt), + vsbp->prev_pptp, sizeof(struct pcx_ppt)); + + vsbp->pcx_ppt.dsap = dsap; /* Update the Dynamic Save Area ptr */ + + /* Update the Primary Pointer Table pointer in the Video Save Table */ + + *((struct pcx_ppt _far * _far *) 0x004000a8L) = &(vsbp->pcx_ppt); + + *vsbpp = vsbp; /* Return Video Services data save buffer ptr */ + + return (TRUE); +} + +/* + ************************************************************************* + * + * PCX_FREE_DSA - Release Dynamic Save Area + * + * Purpose: To release memory allocated to the Video Services Primary + * Pointer Table and associated Dynamic Save Area and reset + * the pointer in the Video Save Table. + * + * Setup: void pcx_free_dsa + * ( + * PCX_VSB *vsbp + * ) + * + * Where: vsbp is a pointer to a PCX_VSB structure that was + * previously allocated and initialized by "pcx_init_dsa". + * + * Note: You MUST call this function on completion of your program + * if you previously called "pcx_init_dsa". Failure to do so + * will leave the system in an unstable state. See the + * function header of "pcx_init_palette" for more + * information. + * + ************************************************************************* + */ + +void pcx_free_dsa +( + PCX_VSB *vsbp +) +{ + /* Restore the previous primary pointer table pointer */ + + *((struct pcx_ppt _far * _far *) 0x004000a8L) = vsbp->prev_pptp; + + _ffree(vsbp->pcx_ppt.dsap); /* Free the Dynamic Save Area */ + + free(vsbp); /* Free the Video Services data save buffer */ +} + +/* PRIVATE FUNCTIONS */ + +/* + ************************************************************************* + * + * PCX_WRITE_INIT - Initialize PCX Workblock For Writing + * + * Purpose: To initialize a PCX image file workblock for writing. + * + * Setup: static BOOL pcx_write_init + * ( + * PCX_WORKBLK *wbp, + * int vmode, + * int page, + * int width, + * int height + * ) + * + * Where: wbp is a PCX workblock pointer. + * vmode is the MS-DOS video mode. Valid values are: + * + * 0x04 - 320 x 200 4-color CGA + * 0x05 - 320 x 200 4-color CGA (color burst off) + * 0x06 - 640 x 200 2-color CGA + * Ox07 - 720 x 348 Hercules monochrome + * 0x0d - 320 x 200 16-color EGA/VGA + * 0x0e - 640 x 200 16-color EGA/VGA + * 0x0f - 640 x 350 2-color EGA/VGA + * 0x10 - 640 x 350 16-color EGA/VGA + * 0x11 - 640 x 480 2-color VGA + * 0x12 - 640 x 480 16-color VGA + * 0x13 - 320 x 200 256-color VGA + * + * page is the video display page number. Valid values are: + * + * Mode PCX_HERC - 0 or 1 + * Mode 0x0d - 0 to 7 + * Mode 0x0e - 0 to 3 + * Mode 0x0f - 0 or 1 + * Mode 0x10 - 0 or 1 + * All Other - 0 + * + * width is the image width in pixels. + * height is the image height in pixels. + * + * Return: TRUE if successful; otherwise FALSE. + * + ************************************************************************* + */ + +static BOOL pcx_write_init +( + PCX_WORKBLK *wbp, + int vmode, + int page, + int width, + int height +) +{ + int max_width; /* Maximum image width */ + int max_height; /* Maximum image height */ + int shift; /* Mask shift value */ + BOOL status = TRUE; /* Return status */ + PCX_HDR *hdrp; /* File header buffer pointer */ + + /* Initialize the display page address offset */ + + wbp->page_offset = (unsigned long) 0L; + + hdrp = &(wbp->header); /* Initialize the file header pointer */ + + /* Initialize the header constants */ + + hdrp->pcx_id = 0x0a; /* PCX format identifier */ + hdrp->version = 5; /* Version number */ + hdrp->encoding = 1; /* Encoding format (run-length) */ + hdrp->xul = 0; /* Upper left x-position */ + hdrp->yul = 0; /* Upper left y-position */ + hdrp->reserved = 0; /* (Used to be video mode) */ + hdrp->palette_type = 1; /* Color or b&w palette type */ + + memset(hdrp->filler, 0, sizeof(hdrp->filler)); /* Padding */ + + /* Initialize the video mode-dependent parameters */ + + switch (vmode) + { + case PCX_HERC: /* 720 x 348 Hercules monochrome */ + + max_width = min(width, 720); /* Maximum image width */ + max_height = min(height, 348); /* Maximum image height */ + + hdrp->bppixel = 1; /* Bits per pixel */ + hdrp->horz_res = 720; /* Horizontal resolution */ + hdrp->vert_res = 348; /* Vertical resolution */ + hdrp->nplanes = 1; /* Number of color planes */ + + /* Maximum two pages supported */ + + wbp->page_offset = 0x08000000L * (unsigned long) page; + + /* Calculate number of bytes to copy */ + + wbp->num_bytes = (max_width + 7) >> 3; + + shift = (max_width & 7); /* Calculate mask shift value */ + + wbp->pcx_funcp = pcx_get_herc; /* Set display capture fcn ptr */ + + break; + + case 0x04: /* 320 x 200 4-color CGA */ + case 0x05: /* 320 x 200 4-color CGA (color burst off) */ + + max_width = min(width, 320); /* Maximum image width */ + max_height = min(height, 200); /* Maximum image height */ + + hdrp->bppixel = 2; /* Bits per pixel */ + hdrp->horz_res = 320; /* Horizontal resolution */ + hdrp->vert_res = 200; /* Vertical resolution */ + hdrp->nplanes = 1; /* Number of color planes */ + + /* Calculate number of bytes to copy */ + + wbp->num_bytes = (max_width + 3) >> 2; + + shift = (max_width & 3) << 1; /* Calculate mask shift value */ + + wbp->pcx_funcp = pcx_get_cga; /* Set display capture fcn ptr */ + + break; + + case 0x06: /* 640 x 200 2-color CGA */ + + max_width = min(width, 640); /* Maximum image width */ + max_height = min(height, 200); /* Maximum image height */ + + hdrp->bppixel = 1; /* Bits per pixel */ + hdrp->horz_res = 640; /* Horizontal resolution */ + hdrp->vert_res = 200; /* Vertical resolution */ + hdrp->nplanes = 1; /* Number of color planes */ + + /* Calculate number of bytes to copy */ + + wbp->num_bytes = (max_width + 7) >> 3; + + shift = (max_width & 7); /* Calculate mask shift value */ + + wbp->pcx_funcp = pcx_get_cga; /* Set display capture fcn ptr */ + + break; + + case 0x0d: /* 320 x 200 16-color EGA/VGA */ + + max_width = min(width, 320); /* Maximum image width */ + max_height = min(height, 200); /* Maximum image height */ + + hdrp->bppixel = 1; /* Bits per pixel */ + hdrp->horz_res = 320; /* Horizontal resolution */ + hdrp->vert_res = 200; /* Vertical resolution */ + hdrp->nplanes = 4; /* Number of color planes */ + + /* Maximum eight display pages supported */ + + wbp->page_offset = 0x02000000L * (unsigned long) page; + + /* Calculate number of bytes to copy */ + + wbp->num_bytes = (max_width + 7) >> 3; + + shift = (max_width & 7); /* Calculate mask shift value */ + + wbp->pcx_funcp = pcx_get_ega; /* Set display capture fcn ptr */ + + break; + + case 0x0e: /* 640 x 200 16-color EGA/VGA */ + + max_width = min(width, 640); /* Maximum image width */ + max_height = min(height, 200); /* Maximum image height */ + + hdrp->bppixel = 1; /* Bits per pixel */ + hdrp->horz_res = 640; /* Horizontal resolution */ + hdrp->vert_res = 200; /* Vertical resolution */ + hdrp->nplanes = 4; /* Number of color planes */ + + /* Maximum four display pages supported */ + + wbp->page_offset = 0x04000000L * (unsigned long) page; + + /* Calculate number of bytes to copy */ + + wbp->num_bytes = (max_width + 7) >> 3; + + shift = (max_width & 7); /* Calculate mask shift value */ + + wbp->pcx_funcp = pcx_get_ega; /* Set display capture fcn ptr */ + + break; + + case 0x0f: /* 640 x 350 2-color EGA/VGA */ + + max_width = min(width, 640); /* Maximum image width */ + max_height = min(height, 350); /* Maximum image height */ + + hdrp->bppixel = 1; /* Bits per pixel */ + hdrp->horz_res = 640; /* Horizontal resolution */ + hdrp->vert_res = 350; /* Vertical resolution */ + hdrp->nplanes = 2; /* Number of color planes */ + + /* Maximum two display pages supported */ + + wbp->page_offset = 0x08000000L * (unsigned long) page; + + /* Calculate number of bytes to copy */ + + wbp->num_bytes = (max_width + 7) >> 3; + + shift = (max_width & 7); /* Calculate mask shift value */ + + wbp->pcx_funcp = pcx_get_ega; /* Set display capture fcn ptr */ + + break; + + case 0x10: /* 640 x 350 16-color EGA/VGA */ + + max_width = min(width, 640); /* Maximum image width */ + max_height = min(height, 350); /* Maximum image height */ + + hdrp->bppixel = 1; /* Bits per pixel */ + hdrp->horz_res = 640; /* Horizontal resolution */ + hdrp->vert_res = 350; /* Vertical resolution */ + hdrp->nplanes = 4; /* Number of color planes */ + + /* Maximum two display pages supported */ + + wbp->page_offset = 0x08000000L * (unsigned long) page; + + /* Calculate number of bytes to copy */ + + wbp->num_bytes = (max_width + 7) >> 3; + + shift = (max_width & 7); /* Calculate mask shift value */ + + wbp->pcx_funcp = pcx_get_ega; /* Set display capture fcn ptr */ + + break; + + case 0x11: /* 640 x 480 2-color VGA */ + + max_width = min(width, 640); /* Maximum image width */ + max_height = min(height, 480); /* Maximum image height */ + + hdrp->bppixel = 1; /* Bits per pixel */ + hdrp->horz_res = 640; /* Horizontal resolution */ + hdrp->vert_res = 480; /* Vertical resolution */ + hdrp->nplanes = 1; /* Number of color planes */ + + /* Calculate number of bytes to copy */ + + wbp->num_bytes = (max_width + 7) >> 3; + + shift = (max_width & 7); /* Calculate mask shift value */ + + wbp->pcx_funcp = pcx_get_ega; /* Set display capture fcn ptr */ + + break; + + case 0x12: /* 640 x 480 16-color VGA */ + + max_width = min(width, 640); /* Maximum image width */ + max_height = min(height, 480); /* Maximum image height */ + + hdrp->bppixel = 1; /* Bits per pixel */ + hdrp->horz_res = 640; /* Horizontal resolution */ + hdrp->vert_res = 480; /* Vertical resolution */ + hdrp->nplanes = 4; /* Number of color planes */ + + /* Calculate number of bytes to copy */ + + wbp->num_bytes = (max_width + 7) >> 3; + + shift = (max_width & 7); /* Calculate mask shift value */ + + wbp->pcx_funcp = pcx_get_ega; /* Set display capture fcn ptr */ + + break; + + case 0x13: /* 320 x 200 256-color VGA */ + + max_width = min(width, 320); /* Maximum image width */ + max_height = min(height, 200); /* Maximum image height */ + + hdrp->bppixel = 8; /* Bits per pixel */ + hdrp->horz_res = 320; /* Horizontal resolution */ + hdrp->vert_res = 200; /* Vertical resolution */ + hdrp->nplanes = 1; /* Number of color planes */ + + /* Calculate number of bytes to copy */ + + wbp->num_bytes = max_width; + + shift = 0; /* Dummy parameter */ + + wbp->pcx_funcp = pcx_get_vga; /* Set display capture fcn ptr */ + + break; + + default: /* Other modes not supported */ + + status = FALSE; + + break; + } + + /* Initialize common video mode-dependent parameters */ + + hdrp->xlr = max_width - 1; /* Lower right x-position */ + hdrp->ylr = max_height - 1; /* Lower right y-position */ + hdrp->scrn_width = hdrp->horz_res; /* Screen width */ + hdrp->scrn_height = hdrp->vert_res; /* Screen height */ + + /* Calculate mask for "white" data */ + + if (shift != 0) + wbp->mask = 0xff >> shift; + else + wbp->mask = 0x00; + + /* Initialize the file header palette */ + + status = pcx_init_palette(hdrp->palette, vmode); + + /* Calculate number of bytes per color plane scan line (must be an */ + /* even number of bytes) */ + + hdrp->bppscan = 2 * (((((hdrp->xlr * hdrp->bppixel) + 7) / 8) + 1) / 2); + + return (status); +} + +/* + ************************************************************************* + * + * PCX_INIT_PALETTE - Initialize File Header Palette + * + * Purpose: To initialize the file header 16-color palette. + * + * Setup: static BOOL pcx_init_palette + * ( + * PCX_PAL *palettep, + * int vmode + * ) + * + * Where: palettep is a pointer to the PCX file header buffer + * "palette" member. + * vmode is the MS-DOS video mode. Valid values are: + * + * 0x04 - 320 x 200 4-color CGA + * 0x05 - 320 x 200 4-color CGA (color burst off) + * 0x06 - 640 x 200 2-color CGA + * Ox07 - 720 x 348 Hercules monochrome + * 0x0d - 320 x 200 16-color EGA/VGA + * 0x0e - 640 x 200 16-color EGA/VGA + * 0x0f - 640 x 350 2-color EGA/VGA + * 0x10 - 640 x 350 16-color EGA/VGA + * 0x11 - 640 x 480 2-color VGA + * 0x12 - 640 x 480 16-color VGA + * 0x13 - 320 x 200 256-color VGA + * + * Return: TRUE if successful; otherwise FALSE. + * + * Note: The CGA color palette is not supported. + * + * If a VGA display adapter is present, the color palette + * registers can be read directly from the adapter using the + * BIOS routine "Read All Palette Registers" (function 0x09). + * + * Unfortunately, the EGA display adapter color palette + * registers are write-only. This means that the current + * color palette for EGA displays cannot in general be read. + * + * The BIOS routine "Set All Palette Registers" (function + * 0x02) will write the current palette register values to a + * buffer called the Dynamic Save Area. The EGA color + * palette can be read from the first 16 bytes of this 256- + * byte RAM block. + * + * The Dynamic Save Area is not statically allocated; it must + * be supplied by the user. The BIOS video services data in + * segment 0x40 includes a pointer at address 0040:00a8 that + * references the Video Services Primary Pointer Table in the + * EGA/VGA BIOS. This table contains seven pointers, the + * second of which is used by the "Set All Palette Registers" + * routine to reference the Dynamic Save Area. Since the + * Dynamic Save Area does not exist at system initialization, + * the value of this pointer is 0000:0000 (in which case the + * the updated palette register values are not saved to RAM + * when they are updated). + * + * To utilize the EGA palette register save feature, the + * user must perform the following: + * + * 1. Save a copy of the pointer at address 0040:00a8. + * 2. Allocate a buffer for a new Primary Pointer Table. + * 3. Copy the existing Primary Pointer Table to the + * allocated buffer. + * 4. Allocate a 256-byte buffer for a Dynamic Save Area. + * 5. Initialize the second pointer of the Primary Pointer + * Table to point to the Dynamic Save Area buffer. + * + * Before the program finishes, the user must also restore + * the saved Primary Pointer Table pointer to address + * 0040:00a8. Failure to do so will mean that subsequent + * calls by other programs to the "Set All Palette + * Registers" routine will result in the color palette + * registers values being written to unallocated memory (or + * memory that has been allocated for another purpose). + * + * The function "pcx_init_dsa" performs the five steps + * outlined above, while the function "pcx_free_dsa" restores + * the saved pointer on completion of your program. + * + * If the Dynamic Save Area pointer is 0000:0000 (the default + * value at system initialization), the BIOS default color + * palette settings for the appropriate mode are stored in + * the file header color palette. + * + ************************************************************************* + */ + +static BOOL pcx_init_palette +( + PCX_PAL *palettep, + int vmode +) +{ + int i; /* Scratch counter */ + int val; /* Current palette register value */ + int red; /* Temporary value */ + int green; /* Temporary value */ + int blue; /* Temporary value */ + unsigned char *ega_palp; /* EGA/VGA palette buffer pointer */ + unsigned char _far *dsap; /* Dynamic Save Area pointer */ + union REGS regs; /* 80x86 register values */ + struct SREGS sregs; /* 80x86 segment register values */ + + if (vmode < 0x0d || vmode > 0x12) + { + /* Clear the file header palette */ + + memset(palettep, 0, sizeof(PCX_PAL) * PCX_PAL_SIZE); + + return (TRUE); + } + + /* Allocate a 16-color (plus border color) EGA/VGA palette buffer */ + + if ((ega_palp = (unsigned char *) calloc(sizeof(unsigned char), + (PCX_PAL_SIZE + 1))) == (unsigned char *) NULL) + return (FALSE); + + if (pcx_isvga() == TRUE) /* Check for VGA display adapter */ + { + /* Read the EGA/VGA palette registers */ + + regs.h.ah = 0x10; /* Select "Read All Palette Registers" routine */ + regs.h.al = 0x09; + + /* Get the EGA/VGA palette buffer offset value */ + + regs.x.dx = (unsigned int) ega_palp; + + segread(&sregs); /* Get the current DS segment register value */ + + sregs.es = sregs.ds; + + int86x(0x10, ®s, ®s, &sregs); /* Call BIOS video service */ + } + else + { + /* Check for a Dynamic Save Area buffer */ + + dsap = *(*((unsigned char _far * _far * _far *) 0x004000a8L) + 1); + + if (dsap != (unsigned char _far *) NULL) + { + /* Copy the current palette into the local EGA/VGA palette buffer */ + + (void) _fmemcpy((unsigned char _far *) ega_palp, dsap, + PCX_PAL_SIZE); + } + else + { + /* Copy the appropriate default palette settings */ + + switch (vmode) + { + case 0x0d: /* 320 x 200 16-color EGA */ + case 0x0e: /* 640 x 200 16-color EGA */ + + memcpy(ega_palp, pcx_EGA_DefPal_1, PCX_PAL_SIZE); + + break; + + case 0x0f: /* 640 x 350 2-color EGA */ + + memcpy(ega_palp, pcx_EGA_DefPal_2, PCX_PAL_SIZE); + + break; + + case 0x10: /* 640 x 350 16-color EGA */ + + memcpy(ega_palp, pcx_EGA_DefPal_3, PCX_PAL_SIZE); + + break; + + default: /* (Should never reach here) */ + + break; + } + } + + /* Map the EGA/VGA palette to the PCX file header palette */ + + for (i = 0; i < PCX_PAL_SIZE; i++) + { + val = (int) ega_palp[i]; /* Get current color palette value */ + + /* Extract color values */ + + red = ((val & 0x20) >> 5) | ((val & 0x04) >> 1); + green = ((val & 0x10) >> 4) | (val & 0x02); + blue = ((val & 0x08) >> 3) | ((val & 0x01) << 1); + + /* Map each color to a 6-bit value. Only the top two bits are */ + /* significant for EGA displays. The lower four bits (which */ + /* repeat the top two bits) are significant when the image is */ + /* presented on a VGA display emulating an EGA display. */ + + palettep[i].red = (BYTE) ((red << 6) | (red << 4) | (red << 2)); + palettep[i].green = (BYTE) ((green << 6) | (green << 4) | (green << + 2)); + palettep[i].blue = (BYTE) ((blue << 6) | (blue << 4) | (blue << 2)); + } + } + + free(ega_palp); /* Free the EGA/VGA palette buffer */ + + return (TRUE); +} + +/* + ************************************************************************* + * + * PCX_WRITE_LINE - Write PCX Line + * + * Purpose: To write an image scan line to a PCX-format image file. + * + * Setup: static BOOL pcx_write_line + * ( + * unsigned char *linep, + * int buflen, + * FILE *fp + * ) + * + * Where: linep is a PCX scan line buffer pointer. + * buflen is the length of the image scan line buffer in + * bytes. + * fp is a file pointer. + * + * Return: TRUE if successful; otherwise FALSE. + * + * Note: The PCX scan line buffer is assumed to contain the color + * plane scan lines in sequence, with padding for an even + * number of bytes and trailing "white" data for each line as + * appropriate. + * + ************************************************************************* + */ + +static BOOL pcx_write_line +( + unsigned char *linep, + int buflen, + FILE *fp +) +{ + int curr_data; /* Current data byte */ + int prev_data; /* Previous data byte */ + int data_count; /* Data repeat count */ + int line_count; /* Scan line byte count */ + + prev_data = *linep++; /* Initialize the previous data byte */ + data_count = 1; + line_count = 1; + + while (line_count < buflen) /* Encode scan line */ + { + curr_data = *linep++; /* Get the current data byte */ + line_count++; /* Increment the scan line counter */ + + if (curr_data == prev_data) /* Repeating data bytes ? */ + { + data_count++; /* Increment the data repeat count */ + + /* Check for maximum allowable repeat count */ + + if (data_count == PCX_COMP_MASK) + { + /* Encode the data */ + + if (pcx_encode(prev_data, data_count, fp) == FALSE) + return (FALSE); + + data_count = 0; /* Reset the data repeat count */ + } + } + else /* End of repeating data bytes */ + { + if (data_count > 0) + { + /* Encode the data */ + + if (pcx_encode(prev_data, data_count, fp) == FALSE) + return (FALSE); + } + + prev_data = curr_data; /* Current data byte now previous */ + data_count = 1; + } + } + + if (data_count > 0) /* Any remaining data ? */ + { + /* Encode the data */ + + if (pcx_encode(prev_data, data_count, fp) == FALSE) + return (FALSE); + } + + return (TRUE); +} + +/* + ************************************************************************* + * + * PCX_ENCODE - Encode Byte Pair + * + * Purpose: To write an encoded byte pair (or a single unencoded + * byte) to a PCX-format image file. + * + * Setup: static BOOL pcx_encode + * ( + * int data, + * int count, + * FILE *fp + * ) + * + * Where: data is the data byte to be encoded (if necessary). + * count is the number of times the data byte is repeated in + * the image data. + * fp is a pointer to the PCX-format file the encoded byte + * pair or single byte is to be written to. + * + * Return: TRUE if successful; otherwise FALSE. + * + ************************************************************************* + */ + +static BOOL pcx_encode +( + int data, + int count, + FILE *fp +) +{ + if (((data & PCX_COMP_FLAG) == PCX_COMP_FLAG) || count > 1) + { + /* Write the count byte */ + + if (putc(PCX_COMP_FLAG | count, fp) == EOF) + return (FALSE); + } + + /* Write the data byte */ + + if (putc(data, fp) == EOF) + return (FALSE); + + return (TRUE); +} + +/* + ************************************************************************* + * + * PCX_WRITE_EXTPAL - Write Extended Palette + * + * Purpose: To read the current 256-color VGA palette and write an + * equivalent extended PCX palette to a PCX-format image + * file. + * + * Setup: static BOOL pcx_write_extpal + * ( + * FILE *fp + * ) + * + * Where: fp is a file pointer. + * + * Return: TRUE if successful; otherwise FALSE. + * + ************************************************************************* + */ + +static BOOL pcx_write_extpal +( + FILE *fp +) +{ + int i; /* Scratch counter */ + BOOL status = TRUE; /* Return status */ + PCX_PAL *palettep; /* Extended PCX palette buffer pointer */ + unsigned char *vga_palp; /* 256-color VGA palette buffer pointer */ + union REGS regs; /* 80x86 register values */ + struct SREGS sregs; /* 80x86 segment register values */ + + /* Allocate an extended PCX palette buffer */ + + if ((palettep = (PCX_PAL *) calloc(sizeof(PCX_PAL), PCX_EPAL_SIZE)) == + (PCX_PAL *) NULL) + return (FALSE); + + /* Allocate a 256-color VGA palette buffer */ + + if ((vga_palp = (unsigned char *) calloc(sizeof(unsigned char), 768)) + == (unsigned char *) NULL) + { + free(palettep); /* Free the extended PCX palette buffer */ + return (FALSE); + } + + /* Read the current VGA palette (DAC registers) */ + + regs.h.ah = 0x10; /* Select "Read DAC Registers" BIOS routine */ + regs.h.al = 0x17; + regs.x.bx = 0; /* Read all 256 DAC registers */ + regs.x.cx = 256; + + /* Get the VGA palette buffer offset value */ + + regs.x.dx = (unsigned int) vga_palp; + + segread(&sregs); /* Get the current DS segment register value */ + + sregs.es = sregs.ds; + + int86x(0x10, ®s, ®s, &sregs); /* Call BIOS video service */ + + /* Map the VGA palette to an extended PCX palette */ + + for (i = 0; i < PCX_EPAL_SIZE; i++) + { + palettep[i].red = (BYTE) (vga_palp[i * 3] << 2); + palettep[i].green = (BYTE) (vga_palp[i * 3 + 1] << 2); + palettep[i].blue = (BYTE) (vga_palp[i * 3 + 2] << 2); + } + + /* Write the extended PCX palette indicator byte to the file */ + + if (status == TRUE) + if (fputc(PCX_EPAL_FLAG, fp) == EOF) + status = FALSE; + + /* Write the extended PCX palette to the file */ + + if (status == TRUE) + if (fwrite(palettep, sizeof(PCX_PAL), PCX_EPAL_SIZE, fp) != + PCX_EPAL_SIZE) + status = FALSE; + + free(palettep); /* Free the extended PCX palette buffer */ + + free(vga_palp); /* Free the VGA palette buffer */ + + return (status); +} + +/* + ************************************************************************* + * + * PCX_GET_HERC - Get Hercules Scan Line + * + * Purpose: To read a Hercules monochrome graphics display adapter + * scan line into a buffer. + * + * Setup: static void pcx_get_herc + * ( + * PCX_WORKBLK *wbp, + * unsigned char _far *linep, + * int line_num + * ) + * + * Where: wbp is a PCX workblock pointer. + * linep is a pointer to where the scan line is to be + * returned. + * line_num is the scan line number. + * + ************************************************************************* + */ + +static void pcx_get_herc +( + PCX_WORKBLK *wbp, + unsigned char _far *linep, + int line_num +) +{ + unsigned char _far *displayp; /* Display buffer pointer */ + + /* Calculate Hercules display buffer pointer */ + + displayp = (unsigned char _far *) (0xb0000000L + wbp->page_offset) + + ((line_num >> 2) * 90) + 0x2000 * (line_num & 3); + + /* Copy data from the Hercules display buffer to the scan line buffer */ + + (void) _fmemcpy(linep, displayp, wbp->num_bytes); + + /* Mask off unseen pixels */ + + linep[wbp->num_bytes - 1] |= wbp->mask; + + /* Pad scan line with "white" data byte (if necessary) */ + + if (wbp->num_bytes & 1) + linep[wbp->num_bytes] = 0xff; +} + +/* + ************************************************************************* + * + * PCX_GET_CGA - Get CGA Scan Line + * + * Purpose: To read a CGA display adapter scan line into a buffer. + * + * Setup: static void pcx_get_cga + * ( + * PCX_WORKBLK *wbp, + * unsigned char _far *linep, + * int line_num + * ) + * + * Where: wbp is a PCX workblock pointer. + * linep is a pointer to where the scan line is to be + * returned. + * line_num is the scan line number. + * + ************************************************************************* + */ + +static void pcx_get_cga +( + PCX_WORKBLK *wbp, + unsigned char _far *linep, + int line_num +) +{ + unsigned char _far *displayp; /* Display buffer pointer */ + + /* Calculate CGA display buffer pointer */ + + displayp = (unsigned char _far *) 0xb8000000L + ((line_num >> 1) * 80) + + 0x2000 * (line_num & 1); + + /* Copy data from the CGA display buffer to the scan line buffer */ + + (void) _fmemcpy(linep, displayp, wbp->num_bytes); + + /* Mask off unseen pixels */ + + linep[wbp->num_bytes - 1] |= wbp->mask; + + /* Pad scan line with "white" data byte (if necessary) */ + + if (wbp->num_bytes & 1) + linep[wbp->num_bytes] = 0xff; +} + +/* + ************************************************************************* + * + * PCX_GET_EGA - Get EGA/VGA Scan Line + * + * Purpose: To read an EGA/VGA display adapter scan line into a + * buffer. + * + * Setup: static void pcx_get_ega + * ( + * PCX_WORKBLK *wbp, + * unsigned char _far *linep, + * int line_num + * ) + * + * Where: wbp is a PCX workblock pointer. + * linep is a pointer to where the scan line is to be + * returned. + * line_num is the scan line number. + * + ************************************************************************* + */ + +static void pcx_get_ega +( + PCX_WORKBLK *wbp, + unsigned char _far *linep, + int line_num +) +{ + int plane_num; /* EGA/VGA color plane number */ + unsigned char _far *displayp; /* Display buffer pointer */ + + /* Calculate buffer pointer */ + + displayp = (unsigned char _far *) (0xa0000000L + wbp->page_offset) + + line_num * 80; + + /* Copy PCX scan line data from each color plane */ + + for (plane_num = 0; plane_num < (int) wbp->header.nplanes; plane_num++) + { + /* Select the current color plane in EGA/VGA Read Mode 0 */ + + outpw(0x03ce, (plane_num << 8) | 0x04); + + /* Copy data from the EGA/VGA display to the scan line buffer */ + + (void) _fmemcpy(linep, displayp, wbp->num_bytes); + + /* Mask off unseen pixels */ + + linep[wbp->num_bytes - 1] |= wbp->mask; + + /* Pad plane scan line with "white" data byte (if necessary) */ + + if (wbp->num_bytes & 1) + linep[wbp->num_bytes] = 0xff; + + linep += wbp->header.bppscan; /* Increment plane offset */ + } + + /* Select EGA/VGA Write Mode 0 with all color planes enabled */ + + outpw(0x03c4, 0x0f02); +} + +/* + ************************************************************************* + * + * PCX_GET_VGA - Get VGA Scan Line + * + * Purpose: To read a VGA display adapter scan line into a buffer. + * + * Setup: static void pcx_get_vga + * ( + * PCX_WORKBLK *wbp, + * unsigned char _far *linep, + * int line_num + * ) + * + * Where: wbp is a PCX workblock pointer. + * linep is a pointer to where the scan line is to be + * returned. + * line_num is the scan line number. + * + ************************************************************************* + */ + +static void pcx_get_vga +( + PCX_WORKBLK *wbp, + unsigned char _far *linep, + int line_num +) +{ + unsigned char _far *displayp; /* Display buffer pointer */ + + /* Calculate buffer pointer */ + + displayp = (unsigned char _far *) 0xa0000000L + line_num * 320; + + /* Copy data from the VGA display buffer to the scan line buffer */ + + (void) _fmemcpy(linep, displayp, wbp->num_bytes); + + /* Pad scan line with "white" data byte (if necessary) */ + + if (wbp->num_bytes & 1) + linep[wbp->num_bytes] = 0xff; +} + diff --git a/16/PCX_LIB/PCX_FMT.DOC b/16/PCX_LIB/PCX_FMT.DOC new file mode 100644 index 00000000..224f58a9 --- /dev/null +++ b/16/PCX_LIB/PCX_FMT.DOC @@ -0,0 +1,941 @@ + + +Ian Ashdown +byHeart Software +620 Ballantree Road +West Vancouver, B.C. +Canada V7S 1W3 + +Issue 1: 91/02/12 +Issue 2: 91/03/27 +Issue 3: 91/08/08 +Issue 4: 91/08/11 + + + + + + + + + + + + PCX Graphics + + by + + Ian Ashdown + byHeart Software + +Looking to add monochrome or full-color bit-mapped graphics to your +application programs? If so, you might consider the PCX graphics file +format. Originally developed in 1982 by ZSoft Corporation for their PC +Paintbrush (R) products, it has become a de facto industry standard for +storing and transferring bit-mapped images on MS-DOS machines. It can +support displays of any resolution using palettes of up to 256 +simultaneous colors, and is very simple to implement. Furthermore, it's +not limited to MS-DOS and OS/2-based machines; the PCX format is +applicable to any environment supporting bit-mapped graphics. + +Today, more commercial programs support ZSoft's PCX format than any +other, including Aldus-Microsoft's Tag Image File Format (TIFF). +However, unlike TIFF with its publicly-available technical +specifications, the PCX file format has never been completely documented. +When ZSoft first created PC Paintbrush, the only video displays they had +to contend with were two monochrome adapters (Hercules and Tecmar) and +the IBM Color Graphics Adapter (CGA). They have since quietly modified +and extended their format on several occasions to support EGA, VGA and +SuperVGA displays. Documentation is scarce, incomplete and sometimes +contradictory. There's a small booklet available from ZSoft that +describes the current version (with several omissions), a sample Pascal +program from their CompuServe forum (GO WINAPB), a few magazine articles, +and chapters in a few books (see the references at the end of this +article). + +Personally, I think it's about time to remedy this situation. The +following is a complete set of technical specifications for the current +version of PCX. All of the information has been derived from printed +information provided by ZSoft and conversations with their Technical +Services department. This is it, folks! We now have formal (if not +exactly official) specifications to work with when including the PCX +graphics file format in our application programs. + +My original plan was to include sample C source code for reading and +writing PCX image files. However, both this article and the source code +grew to the extent that one had to go. If you don't want to develop your +own PCX file handling routines from scratch, PCX_LIB is available through +the CUG Library as CUG Volume #???. It includes fully commented C source +code for reading and writing PCX image files, complete with software +drivers for Hercules, CGA, EGA, and VGA display adapters. + + + + + + + + + + + + + + + + + + + + p. 1 + +PCX Specifications + +The PCX graphics file format (Version 5) is designed to store monochrome +and color bit-mapped images of any resolution with palettes of up to 256 +simultaneous colors. It was originally designed for MS-DOS +microcomputers, but is adaptable to other bit-mapped graphic +environments. A simple but effective byte-oriented, run-length encoding +scheme is used to compress the image data. + +There are two or three sections to a PCX graphics file - a 128-byte +header, the encoded image data (which can be of any length) and an +optional 256-color palette (see Figure 1). This palette is appended to +the file only if the image contains more than 16 colors. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p. 2 + +1. PCX File Header + +The file header describes the graphical environment in which the image is +to be displayed. The information contained in the header is somewhat +device-dependent in that the PCX file format implicitly assumes the +presence of a standard IBM PC-compatible display adapter. Furthermore, +the specific type and video mode of the adapter needed to display the +image correctly cannot be uniquely determined from the file header +information. It is in general the user's responsibility to ensure that +the correct video mode has been selected before displaying a PCX image. + +The file header structure is shown in Figure 2. A complete description +of each structure member is as follows: + +1.1 PCX Flag + +A constant value (0x0a) that signifies a PCX image file. + +1.2 Version + +Indicates the PCX file format version. It can be one of five values: + + 0 - Version 2.5 of PC Paintbrush. + 2 - Version 2.8 (with palette information). + 3 - Version 2.8 (without palette information). + 4 - PC Paintbrush for Windows (not 3.0). + 5 - Version 3.0 and greater of PC Paintbrush and Paintbrush Plus, + including Publisher's Paintbrush. + +Most commercial programs supporting the PCX file format conform to +Version 5. See Section 3, "Color Palettes", for further information. + +1.3 Encoding (1) + +A constant value (0x01) that indicates run-length encoding was used to +encode and compress the image data. + +1.4 Bits per Pixel + +The number of bits per pixel per color plane (typically 1, 2, 4 or 8). + +1.5 Window + +A structure with the following members: + + Name Bytes Description + + xul 2 Upper left corner horizontal position + yul 2 Upper left corner vertical position + xlr 2 Lower right corner horizontal position + ylr 2 Lower right corner vertical position + +These members describe the position and size of the image within the +display, and are measured in pixels (starting with zero). + + + + + + p. 3 + +1.6 HDPI (2) + +"Horizontal dots per inch". The value represents the horizontal +resolution of the device used to create the image. + +1.7 VDPI (2) + +"Vertical dots per inch". The value represents the vertical resolution +of the device used to create the image. + +1.8 Color Map + +The color palette to be used when displaying an image with 16 or fewer +colors. See Section 3, "Color Palettes", for further information. + +1.9 Reserved + +This member was used to indicate the appropriate MS-DOS video mode in +previous PCX file format versions. It is ignored in Version 5, but +should be set to zero. + +1.10 NPlanes + +The number of color planes used to display the image (typically 1 or 4). +See Section 3, "Color Palettes", for further information. + +1.11 Bytes per Line + +The number of bytes required for a buffer when decoding one color plane +scan line. This value should be an even number (for compatibility with +some existing commercial programs). See Section 2, "Image Encoding and +Decoding", for further information. + +1.12 Palette Info (3) + +A bit-mapped variable indicating how to interpret the color palette. +Only the lowest two bits are significant; the others are ignored. It +can have one of two possible values: + + 0x01 - color or black & white + 0x02 - grayscale + +If the variable is set to 0x02 (grayscale), the color palette must be set +to shades of gray. + +1.13 HScreen Size (4) + +Horizontal screen size in pixels. + +1.14 VScreen Size (4) + +Vertical screen size in pixels. + +1.15 Filler + +Blank space to fill out 128-byte header. All bytes within this member +should be set to zero. + + + p. 4 + +Notes + +1. ZSoft has reserved the right to change the encoding scheme for better + image compression performance in future versions. + +2. Horizontal and vertical resolution for video display adapters is + defined as the total number of displayed pixels for the current video + mode. For scanners, it is defined in terms of dots per inch. (These + values are provided for information only. They are not required for + encoding or decoding PCX image files.) + +3. The "palette info" member of the file header was used in previous + versions of the PCX file format to indicate whether the palette + represented a color or grayscale palette. If it was set to 0x02 (as a + bitmap - the upper 6 bits could be set at random), the file decoding + functions could assume a default grayscale palette if necessary. + However, the palette already had a true (and possibly nonlinear) + grayscale, so the "palette info" member was never really used by + ZSoft. The current PC Paintbrush IV and IV Plus products simply + ignore it. + +4. The "HScreen Size" and "VScreen Size" members were added to Version 5 + of the PCX format to support PC Paintbrush IV Version 1.02 and IV Plus + Version 1.0. Since earlier Version 5 PCX files may contain + uninitialized data in place of these members, ZSoft specifically + recommends that they not be used to determine the appropriate video + mode for displaying the files. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p. 5 + +2. Image Encoding and Decoding + +The PCX graphics file format considers an image to be a contiguous +sequence (block) of eight-bit bytes representing a bit-mapped raster +display. A simple byte-oriented, run-length encoding (RLE) scheme is +used to compress the display data. When the display is represented by +more than one color plane (such as color images on EGA displays), each +scan line is stored sequentially by color plane. + +The run-length encoding scheme uses a byte pair consisting of a "count" +byte and a following "data" byte to represent sequences of display bytes +with the same value. A count byte is uniquely identified by having its +two most significant bits set; its six least significant bits are used to +represent the count value (1 to 63). The following data byte is the +value that is repeated in the display data the number of times indicated +by the count value. + +Any display data byte which is not part of a sequence of bytes of the +same value and which does not have its two most significant bits set is +stored as itself in the encoded image data. Single display data bytes +with a value of 0xc0 or greater are encoded with a count value of one. + +2.1. Decoding + +Decoding display data from encoded image data is done on a line-by-line +basis. The pixel dimensions of the displayed image are calculated as: + + horz_size = Window.xlr - Window.xul + 1 + +and + + vert_size = Window.ylr - Window.yul + 1 + +The number of bytes required to buffer one complete scan line for all +color planes in sequence is: + + buffer_size = NPlanes * Bytes per Line + +Since there are always an integral number of bytes in the buffer, there +may be unused data at the end of each color plane scan line if the number +of bits per pixel is other than eight. This unused data should be masked +off when transferring the line buffer contents to the video display +adapter memory. + +In theory, each color plane scan line may contain an even or odd number +of bytes. However, some application programs expect an even number of +bytes. ZSoft ensures that their products create PCX files with an even +number of bytes per color plane scan line, and recommends that other +programs do the same for compatibility. Of course, decoding functions +should be able to read files with either an even or odd number of bytes +per color plane scan line. + +Decoding begins with the first scan line and proceeds by examining each +byte of the encoded image data. If the two most significant bits of the +byte are set, the lower six bits indicate how many times the next byte is + + + + + p. 6 + +Decoding begins with the first scan line and proceeds by examining each +byte of the encoded image data. If the two most significant bits of the +byte are set, the lower six bits indicate how many times the next byte is +to be duplicated in the line buffer. If these two bits are not set, the +byte itself is copied (once) to the line buffer. A count is kept of the +number of bytes in the line buffer. The current scan line is complete +when its value equals "buffer_size". + +If the display contains more than one color plane, each plane is decoded +in sequence. The order in which they are decoded is device-dependent. +For instance, the Enhanced Graphics Adapter has four color planes ordered +as blue, green, red and intensity. The beginning of each color plane +scan line within the line buffer is given by: + + offset = plane_number * Bytes per Line + +where "plane_number" is a number between 0 and NPlanes - 1. + +A decoding break occurs at the end of each scan line. That is, an +encoding byte pair can only represent a contiguous sequence of bytes +within the current scan line. However, this is not necessarily true for +color planes. An encoding byte pair may represent a contiguous sequence +of identical bytes that extends across two color planes for one display +image scan line. + +Decoding continues until all scan lines (as indicated by "vert_size") +have been decoded. Some older versions of PC Paintbrush padded the image +with extra (uninitialized) scan lines so that all blocks of scan lines (8 +or 16 lines) read from the file were the same size. The image data was +read until end-of-file was returned. ZSoft no longer uses this +technique, since it conflicts with the appended color palette (see +Subsection 3.3, "VGA 256-Color Palettes"). The extra data read could +also overrun the user's image buffer. + +A sample C function to decode a complete image scan line (all color planes) +from a PCX file is shown in Figure 3. + +2.2. Encoding + +Encoding display image data is also done on a line-by-line basis, +following the order of scan lines stored in the display adapter's memory +buffer. The current scan line is encoded for each color plane on a per- +byte basis. As noted above, ZSoft recommends that all color plane scan +lines be padded if necessary to ensure they contain an even number of +bytes. + +ZSoft also recommends that the data used to pad the last one or two bytes +of a scan line represent white data. Apparently, some application +programs display this data when printing or faxing the files. + +A sample C function to encode a single monochrome or color image scan +line for a PCX file is shown in Figure 4. + + + + + + + + p. 7 + +3. Color Palettes + +The PCX file format supports color palettes of up to 16 colors in the +file header. Larger palettes (up to a maximum of 256 colors) are stored +in an optional color palette that is appended to the encoded image data +portion of the file. + +The file header color palette has two different formats, both designed +for IBM PC-compatible machines. A device-specific palette is used for +Color Graphics Adapters (CGA), and a standard R-G-B palette is used for +Enhanced Graphics Adapters (EGA), Multicolor Graphics Adapters (MCGA), +Video Graphics Adapters (VGA) and extended Video Graphics Adapters +(SuperVGA). + +ZSoft's PC Paintbrush products no longer support the CGA color palette. +The following information is provided only for compatibility with older +PCX files. + +3.1. CGA Color Palettes + +The PCX format supports eight possible CGA color palettes for video modes +4 (320x200 4-color graphics) and 5 (320x200 monochrome graphics, color +burst off). Each palette consists of a background color and three +foreground colors (or shades of grey). The background can be one of 16 +colors, the value for which is stored in the first byte of the PCX file +header Color Map member. Only the upper four bits are significant; the +value must be right-shifted by four bits (or divided by 16) to determine +the appropriate CGA hardware palette register value. + +The foreground color palette is specified by the fourth byte of the Color +Map, which has the following structure: + + Name Bit Description + + Color Burst Enable 7 0 - color + 1 - monochrome + Palette 6 0 - yellow + 1 - white + Intensity 5 0 - dim + 1 - bright + +The lower five bits are ignored. + +Most published descriptions of the ROM BIOS call "Set CGA Palette" +(Interrupt 16, Function 11) document only two palettes, obtainable by +setting register BL to 0x00 or 0x01. This is equivalent to the "Palette" +bit above. However, the palette intensity (equivalent to the "Intensity" +bit above) can be selected using bit 4 of the BL register (0 = dim, 1 = +bright). + +The original CGA display adapter was designed for use with NTSC composite +video monitors and color televisions. The "color burst" is a periodic +burst of a 3.58 MHz signal superimposed on the composite video signal to +synchronize the phase of the monitor's internal 3.58 MHz oscillator. +(Without synchronization, the picture has drifting color bars.) The +presence or absence of the burst determines whether the image is +displayed in color or monochrome. + + + p. 8 + +The "Color Burst Enable" bit above actually indicates whether the MS-DOS +video mode is to be 4 (color) or 5 (monochrome). However, the color +burst signal has no meaning for RGB monitors. Video mode 5 will produce +only two distinct color palettes on CGA displays adapters with RGB +monitors, and three distinct palettes on EGA, VGA and SuperVGA display +adapters emulating a CGA display. + +Under video mode 6 (640 x 200 2-color graphics), the first byte of the +CGA color palette specifies the foreground color (i.e. - the color of +the displayed pixels). + +3.2. EGA/VGA 16-Color Palettes + +The 16-color palette for EGA, MCGA, VGA and SuperVGA displays is an array +of 16 elements, each a structure with the following members: + + Name Bytes Description + + Red 1 Red intensity + Green 1 Green intensity + Blue 1 Blue intensity + +All color map entries are stored as unsigned bytes with values ranging +between 0 and 255. Where display adapters support fewer intensity +levels, the value of each color map entry is interpreted by dividing its +value by 256/n, where n is the number of allowable intensity levels +(typically 2, 4 or 16). + +3.3. VGA 256-Color Palettes + +The 256-color palette for MCGA, VGA and SuperVGA displays is an array of +256 elements, each a structure with the same members as the EGA/VGA 16- +color palette, which is appended to the encoded image data portion of the +file (see Figure 1). It is always preceded by a constant byte flag with +the value 0x0c (12 decimal). + +Only Version 5 PCX-format files support 256-color palettes, and then only +when the image has more than 16 colors. ZSoft recommends the following +technique to determine if a 256-color palette is present: first verify +that the file version number is 5, then count back 769 bytes from the end +of the file. If the value of this byte is not 0x0c, the optional 256- +color palette is not present and the EGA/VGA 16-color file header palette +should be used. + +It is possible that a Version 5 PCX-format file with a valid file header +palette can have the value 0x0c in the 769th byte from the end of the +encoded image data. The above technique would then falsely indicate the +presence of an appended 256-color palette. To avoid this problem, it is +necessary to first decode the image and note the file position where the +encoded image data section ends before counting back 769 bytes from the +end of the file. If the supposed 256-color palette flag is located in +the image data section, then the file header palette should be used +instead. + + + + + + + p. 9 + +3.4. 24-Bit Color + +Future versions of ZSoft's Publisher's Paintbrush will support up to 16.7 +million simultaneous colors. The PCX file format will be based on three +color planes (red, green and blue), with 8 bits per pixel per plane. +There will be no color palette, since the color of each pixel will be +fully specified by the encoded image data. + +3.5. Disabling the Palette + +It is occasionally necessary to disable the color palette of a PCX file +in order to correctly display the image. In other words, the current +(default) setting of the display adapter's palette registers are used. +This can be done by changing the PCX file version number from '5' to '3' +(i.e. - PC Paintbrush Version 2.8 without palette information). The file +decoding functions must then check the file version number and ignore the +color palette if it is set to '3'. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p. 10 + +4. Other Environments + +While the PCX file format was designed for MS-DOS machines, it is +nevertheless possible to display PCX images on other machines. It will +generally be necessary to map the image representation (i.e. - window +dimensions, number of color planes, bits per pixel per plane, and the +color palette) to the capabilities of the display hardware. + +It is also necessary to remember that all information in a PCX-format +file is stored as either 8-bit bytes or 16-bit words. Words are stored +in the big-endian format characteristic of 80x86-based machines. That +is, the eight least significant bits (lower byte) are stored first, +followed by the eight most significant bits (upper byte). If PCX-format +files are transferred to little-endian machines (such as those based on +680x0 and Z8000 processors), the order of bytes within each word will +have to be reversed before they can be interpreted. (This applies to the +file header only, since the encoded image data and optional 256-color +palette are stored as bytes.) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p. 11 + +References + +Azer, S. [1988]. "Working With PCX Files", Microcornucopia, No. 42 +(July-August), p. 42. + +Lindley, C.A. [1990]. Practical Image Processing in C, John Wiley & Sons +Inc., New York, N.Y. + +Luze, M. [1991]. "Printing PCX Files", C Gazette, Vol. 5:2 (Winter 1990 - +1991), pp. 11-22. + +Phoenix Technologies Ltd. [1989]. System BIOS for IBM PC/XT/AT Computers +and Compatibles, Addison-Wesley, Reading, MA. + +Quirk, K. [1989]. "Translating PCX Files", Dr. Dobb's Journal, Vol. 14:8 +(August), pp. 30-36, 105-108. + +Rimmer, S. [1990]. Bit-Mapped Graphics, Windcrest Books, Blue Ridge +Summit, PA. + +ZSoft Corporation [1988]. PCX Technical Reference Manual Revision 4, +ZSoft Corporation, Marietta, GA. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p. 12 + +Figures + ++--------------------------------------------+ +| File Header (128 bytes) | ++--------------------------------------------+ +| Encoded Image Data (variable length) | ++--------------------------------------------+ +| Optional Color Palette (769 bytes) | ++--------------------------------------------+ + +Figure 1 - Basic PCX File Format + + +Name Bytes Description + +PCX Flag 1 Constant flag +Version 1 PCX version number +Encoding 1 Run-length encoding flag +Bits per Pixel 1 Number of bits per pixel per plane +Window 8 Window dimensions +HDPI 2 Horizontal image resolution +VDPI 2 Vertical image resolution +Color Map 48 Hardware R-G-B color palette +Reserved 1 (Used to contain video mode) +NPlanes 1 Number of color planes +Bytes per Line 2 Number of bytes per scan line +Palette Info 2 Palette interpretation +HScreen Size 2 Horizontal screen size +VScreen Size 2 Vertical screen size +Filler 54 Initialized filler bytes + +Figure 2 - PCX File Header Structure + + +/* Read an encoded scan line (all color planes) from a */ +/* PCX-format image file and write the decoded data to a scan */ +/* line buffer */ + +void pcx_read_line +( + unsigned char *linep, /* PCX scan line buffer pointer */ + FILE *fp, /* PCX image file pointer */ + int bpline /* # bytes per line (all color planes) */ +) +{ + int data; /* Image data byte */ + int count; /* Image data byte repeat count */ + int offset = 0; /* Scan line buffer offset */ + + while (offset < bpline) /* Decode current scan line */ + { + data = getc(fp); /* Get next byte */ + + /* If top two bits of byte are set, lower six bits show how */ + /* many times to duplicate next byte */ + + + + + p. 13 + + if ((data & 0xc0) == 0xc0) + { + count = data & 0x3f; /* Mask off repeat count */ + data = getc(fp); /* Get next byte */ + memset(linep, data, count); /* Duplicate byte */ + linep += count; + offset += count; + } + else + { + *linep++ = (unsigned char) data; /* Copy byte */ + offset++; + } + } +} + +Figure 3 - Decode PCX Image File Scan Line Function + + +/* Encode a scan line and write it to a PCX file (the line is */ +/* assumed to contain the color plane scan lines in sequence, */ +/* with padding for an even number of bytes and trailing white */ +/* data for each line as appropriate) */ + +void pcx_write_line +( + unsigned char *linep, /* Scan line buffer pointer */ + int length, /* Scan line buffer length (in bytes) */ + FILE *fp /* PCX file pointer */ +) +{ + int curr_data; /* Current data byte */ + int prev_data; /* Previous data byte */ + int data_count; /* Data repeat count */ + int line_count; /* Scan line byte count */ + + prev_data = *linep++; /* Initialize the previous data byte */ + data_count = 1; + line_count = 1; + + while (line_count < length) /* Encode scan line */ + { + curr_data = *linep++; /* Get the current data byte */ + line_count++; /* Increment line byte count */ + + if (curr_data == prev_data) /* Repeating data bytes ? */ + { + data_count++; /* Increment data repeat count */ + + if (data_count == 0x3f) /* Max allowable repeat count ? */ + { + pcx_encode(prev_data, data_count, fp); /* Encode data */ + data_count = 0; + } + } + + + + + p. 14 + + else /* End of repeating data bytes */ + { + if (data_count > 0) + pcx_encode(prev_data, data_count, fp); /* Encode data */ + + prev_data = curr_data; /* Current data byte now prev */ + data_count = 1; + } + } + + if (data_count > 0) /* Any remaining data ? */ + { + pcx_encode(prev_data, data_count, fp); /* Encode data */ + } +} + + +/* Write an encoded byte pair (or single byte) to a file */ + +void pcx_encode +( + int data, /* Data byte */ + int count, /* Data byte repeat count */ + FILE *fp /* PCX file pointer */ +) +{ + if (((data & 0xc0) == 0xc0) || count > 1) + { + putc(0xc0 | count, fp); /* Write count byte */ + } + + putc(data, fp); /* Write data byte */ +} + +Figure 4 - Encode Image Scan Line Functions + + + + + + + + + + + + + + + + + + + + + + + + + p. 15 + diff --git a/16/PCX_LIB/PCX_INT.H b/16/PCX_LIB/PCX_INT.H new file mode 100644 index 00000000..49117783 --- /dev/null +++ b/16/PCX_LIB/PCX_INT.H @@ -0,0 +1,195 @@ +/* + ************************************************************************* + * + * PCX_INT.H - PCX_LIB Library Internal Definitions Include File + * + * Version: 1.00B + * + * History: 91/02/14 - Created + * 91/04/01 - Release 1.00A + * 91/04/07 - Release 1.00B + * + * Compiler: Microsoft C V6.0 + * + * Author: Ian Ashdown, P.Eng. + * byHeart Software + * 620 Ballantree Road + * West Vancouver, B.C. + * Canada V7S 1W3 + * Tel. (604) 922-6148 + * Fax. (604) 987-7621 + * + * Copyright: Public Domain + * + ************************************************************************* + */ + +/* DEFINITIONS */ + +#define _PCX_INT_H 1 + +#ifndef _PCX_EXT_H +#include "PCX_EXT.H" /* Get external PCX definitions, etc. */ +#endif + +#define PCX_HERC 0xff /* Hercules 720 x 348 monochrome mode */ + +#define PCX_COMP_FLAG 0xc0 /* Compressed data flag mask */ +#define PCX_COMP_MASK 0x3f /* Data repeat count mask */ + +#define PCX_PAL_MASK 0x03 /* Palette interpretation mask */ +#define PCX_EPAL_FLAG 0x0c /* Extended palette flag */ + +#define PCX_PAL_SIZE 16 /* File header palette size */ +#define PCX_EPAL_SIZE 256 /* Extended palette size */ + +#define PCX_MAXLINESZ 640 /* Maximum PCX line buffer size */ + +/* Color graphics adapter color palette macros */ + +#define PCX_CGA_BKGND(x) (x[0].red >> 4) /* Background color */ +#define PCX_CGA_BURST(x) (x[1].red & 0x80) /* Color burst */ +#define PCX_CGA_SELECT(x) (x[1].red & 0x40) /* Palette selector */ +#define PCX_CGA_INTENSITY(x) (x[1].red & 0x20) /* Intensity */ + +typedef unsigned char BYTE; /* 8-bit data type */ +typedef unsigned int WORD; /* 16-bit data type */ + +/* STRUCTURE DECLARATIONS */ + +typedef struct pcx_pal /* PCX palette array element */ +{ + BYTE red; /* Red intensity */ + BYTE green; /* Green intensity */ + BYTE blue; /* Blue intensity */ +} +PCX_PAL; + +typedef struct pcx_hdr /* PCX file header (Version 5) */ +{ + BYTE pcx_id; /* Always 0x0a for PCX files */ + BYTE version; /* Version number */ + BYTE encoding; /* 1 = PCX run length encoding */ + BYTE bppixel; /* Number of bits/pixel per color plane */ + WORD xul; /* X-position of upper left corner */ + WORD yul; /* Y-position of upper left corner */ + WORD xlr; /* X-position of lower right corner */ + WORD ylr; /* Y-position of lower right corner */ + WORD horz_res; /* Horizontal resolution */ + WORD vert_res; /* Vertical resolution */ + PCX_PAL palette[PCX_PAL_SIZE]; /* Hardware R-G-B palette */ + BYTE reserved; /* Unused in Version 5 */ + BYTE nplanes; /* Number of color planes */ + WORD bppscan; /* Number of bytes per plane scan line */ + WORD palette_type; /* Palette interpretation */ + WORD scrn_width; /* Horizontal screen size in pixels */ + WORD scrn_height; /* Vertical screen size in pixels */ + BYTE filler[54]; /* Padding to fill out 128-byte header */ + + /* Notes: */ + /* */ + /* 1. The "version" member may be one of the following: */ + /* */ + /* 0 - PC Paintbrush Version 2.5 */ + /* 2 - PC Paintbrush Version 2.8 (with palette information) */ + /* 3 - PC Paintbrush Version 2.8 (w/o palette information) */ + /* 4 - PC Paintbrush for Windows (PC Paintbrush Plus for */ + /* Windows and Windows 3.0 Paintbrush use Version 5) */ + /* 5 - PC Paintbrush 3.0 and greater (including PC Paintbrush */ + /* Plus and Publisher's Paintbrush) */ + /* */ + /* 2. ZSoft Corporation has reserved the right to change the */ + /* encoding method in future versions for better image */ + /* compression performance. The "encoding" member value may */ + /* change accordingly. */ + /* */ + /* 3. The value of the "bppixel" member depends on the type of */ + /* video display adapter and its video mode. Typical values */ + /* are 1, 2, 4 and 8. */ + /* */ + /* 4. The "xul", "yul", "xlr" and "ylr" members are zero-based and */ + /* and inclusive values indicating the position of the image on */ + /* the screen. The display functions can ignore this */ + /* information if desired. */ + /* */ + /* 5. The "horz_res" and "vert_res" members refer to the "dots per */ + /* inch" resolution of the scanning device used to create the */ + /* image. For images created on video display adapters, these */ + /* values typically refer to the horizontal and vertical */ + /* resolutions in pixels (e.g. - 640 x 350 for an EGA display). */ + /* */ + /* The display function ignore these members, as some programs */ + /* programs do not bother to initialize them when creating PCX */ + /* image files. */ + /* */ + /* 6. The "palette" member is typically left uninitialized if an */ + /* extended 256-color palette is appended to the PCX image */ + /* file. */ + /* */ + /* 7. The "reserved" member used to contain the MS-DOS video mode */ + /* that the PCX image was intended to be displayed under. This */ + /* member is ignored in Version 5. ZSoft recommends that it be */ + /* set to zero. */ + /* */ + /* 8. The value of the "nplanes" member depends on the type of */ + /* video display adapter and its video mode. Typical values */ + /* are 1, 2, 3 and 4. */ + /* */ + /* 9. The value of the "bppscan" member should be an even number */ + /* (for compatibility with some existing commercial programs.) */ + /* It indicates the number of bytes required to buffer a */ + /* decoded scan line for one color plane. */ + /* */ + /* 10. The "palette_type" member indicates whether the palette */ + /* represents a color or grayscale palette. It is a bit-mapped */ + /* variable (only the lowest two bits are significant; the */ + /* others are ignored) with two possible values: */ + /* */ + /* 0x01 - color or black & white */ + /* 0x02 - grayscale */ + /* */ + /* If "grayscale" is indicated, the file color palette must be */ + /* set to shades of gray. The file decoding functions can then */ + /* either use this palette or assume a default grayscale */ + /* palette if necessary. */ + /* */ + /* PC Paintbrush IV and IV Plus ignore this member. */ + /* */ + /* 11. The "scrn_width" and "scrn_height" members were added for */ + /* PC Paintbrush IV Version 1.02 and IV Plus Version 1.0. They */ + /* may not be initialized in some older Version 5 PCX files, or */ + /* the "scrn_width" member may be initialized with the screen */ + /* height and the "scrn_height" member uninitialized. ZSoft */ + /* recommends that this information be ignored. */ + /* */ + /* 12. ZSoft recommends that the "filler" bytes be set to zero. */ +} +PCX_HDR; + +typedef struct pcx_workblk /* PCX image file workblock */ +{ + /* File header */ + + FILE *fp; /* PCX image file pointer */ + PCX_HDR header; /* PCX image file header */ + PCX_PAL *palettep; /* Color palette pointer */ + BOOL epal_flag; /* Extended color palette flag */ + + /* Image manipulation variables */ + + int num_bytes; /* Number of bytes to display */ + int mask; /* Unseen pixels mask */ + unsigned long page_offset; /* Display page address offset */ + + /* Image manipulation function pointer */ + + void (*pcx_funcp)(struct pcx_workblk *, unsigned char _far *, int); +} +PCX_WORKBLK; + +/* FUNCTIONS PROTOTYPES */ + +extern BOOL pcx_close(PCX_WORKBLK *); + +extern PCX_WORKBLK *pcx_open(char *, BOOL); + diff --git a/16/PCX_LIB/PCX_LIB.BAT b/16/PCX_LIB/PCX_LIB.BAT new file mode 100644 index 00000000..8c6dec6e --- /dev/null +++ b/16/PCX_LIB/PCX_LIB.BAT @@ -0,0 +1,13 @@ +ECHO OFF +REM Batch File To Compile PCX_LIB Demonstration Programs +REM Compiler: Microsoft C V6.0 +ECHO byHeart Software's PCX_LIB Demonstration Programs +ECHO Now compiling source code files ... +cl /c /W4 pcx_comm.c pcx_disp.c pcx_exam.c pcx_file.c rd_demo.c wr_demo.c +ECHO Now linking PCX_EXAM ... +link pcx_exam; +ECHO Now linking RD_DEMO ... +link rd_demo pcx_disp pcx_comm; +ECHO Now linking WR_DEMO ... +link wr_demo pcx_disp pcx_file pcx_comm; + diff --git a/16/PCX_LIB/PCX_LIB.DOC b/16/PCX_LIB/PCX_LIB.DOC new file mode 100644 index 00000000..c6e3e9e5 --- /dev/null +++ b/16/PCX_LIB/PCX_LIB.DOC @@ -0,0 +1,387 @@ +byHeart Software +620 Ballantree Road +West Vancouver, B.C. +Canada V7S 1W3 + +Tel. (604) 922-6148 +Fax. (604) 987-7621 + + + + + + + + + + + + + PCX_LIB Documentation + --------------------- + Version 1.00B + + + by Ian Ashdown, P.Eng. + + + + + + + + + + + + + + + + + + + + + + + + Released into the Public Domain 91/04/01 + +1. Introduction + + PCX_LIB is a library of functions for displaying and storing ZSoft's + Paintbrush (R) PCX-format image files. It was developed expressly + for release into the Public Domain. Fully commented ANSI C source + code is provided for all functions, along with complete technical + specifications for ZSoft's PCX image file format. + + Version 1.00B supports the display and storage of images on MS-DOS + systems equipped with the following display adapters: + + Hercules - monochrome + CGA - Color Graphics Adapter + EGA - Enhanced Graphics Adapter + MCGA - MultiColor Graphics Adapter + VGA - Video Graphics Adapter + + All valid MS-DOS graphic modes are supported. + + SuperVGA and XGA display adapters are not supported in this release. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p. 1 + +2. DISCLAIMER: + + IN NO EVENT SHALL BYHEART SOFTWARE BE LIABLE FOR ANY DAMAGES + WHATSOEVER INCLUDING, WITHOUT LIMITATION, PERSONAL DAMAGES, DAMAGES + FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS + INFORMATION, OR OTHER PECUNIARY LOSS, ARISING OUT OF THE USE OR + INABILITY TO USE THIS PRODUCT, EVEN IF BYHEART SOFTWARE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p. 2 + +3. Disk Contents + + The disk includes the following files: + + +3.1. Documentation + + PCX_LIB.DOC - PCX_LIB documentation (this file) + PCX_FMT.DOC - PCX image file format specifications + + +3.2. ANSI C Source Code + + PCX_COMM.C - PCX image file common functions + PCX_DISP.C - PCX image file display functions + PCX_EXAM.C - PCX image file header examination utility + PCX_FILE.C - PCX image capture functions + RD_DEMO.C - PCX image file display demonstration program + WR_DEMO.C - PCX image file capture demonstration program + + PCX_EXT.H - PCX_LIB external definitions include file + PCX_INT.H - PCX_LIB internal definitions include file + + +3.3. MS-DOS Executables + + PCX_EXAM.EXE - PCX image file header examination utility + RD_DEMO.EXE - PCX image file display demonstration program + WR_DEMO.EXE - PCX image file capture demonstration program + + +3.4. Sample PCX Image Files + + TEST_04.PCX - 320 x 200 4-color CGA test image (mode 4) + TEST_06.PCX - 640 x 200 2-color CGA test image (mode 6) + TEST_16.PCX - 640 x 350 16-color EGA test image (mode 16) + TEST_19.PCX - 320 x 200 256-color VGA test image (mode 19) + + +3.5. Miscellaneous + + PCX_LIB.BAT - Microsoft C V6.0 program build batch file + + + + + + + + + + + + + p. 3 + +4. Trying It Out + + Four test images are included on the disk, one each for MS-DOS video + modes 4, 6, 16 and 19. + + +4.1. PCX_EXAM + + PCX_EXAM reads a PCX-format image file and displays a summary of + the information contained in the file header. A full explanation + of this information is presented in PCX_FMT.DOC. + + To run PCX_EXAM with a file (e.g. - "MY_PICT.PCX"), enter: + + PCX_EXAM my_pict.pcx + + +4.2. RD_DEMO + + To display any of these images, enter: + + RD_DEMO test_xx.pcx xx + + where "xx" is the video mode (e.g. - "RD_DEMO test_06.pcx 6"). + Your display adapter must be capable of emulating the specified + video mode in order to display the image. + + Once the image is displayed, press any key to clear the screen and + return to DOS. + + RD_DEMO will also display a PCX-format image if your display + adapter supports its appropriate video mode. For example, to + display a PCX-format image file "MY_PICT.PCX" that was created for + display on 320 x 200 256-color VGA displays, enter: + + RD_DEMO my_pict.pcx 19 + + +4.3. WR_DEMO + + The demonstration program WR_DEMO will first display a PCX-format + image file, then capture the image directly from the display + adapter's memory and create a PCX-format image file called + "PCX_DEMO.PCX". + + To run WR_DEMO, enter: + + WR_DEMO test_xx.pcx xx + + where "xx" is the video mode (e.g. - "WR_DEMO test_06.pcx 6"). + Your display adapter must be capable of emulating the specified + video mode in order to display and capture the image. + + + p. 4 + + Once the image is displayed, WR_DEMO will automatically capture + it and create the file "PCX_DEMO.PCX" before clearing the screen + and returning to DOS. + + WR_DEMO will also display and capture a PCX-format image if your + display adapter supports its appropriate video mode. For example, + to capture a PCX-format image file "MY_PICT.PCX" that was created + for display on 320 x 200 256-color VGA displays, enter: + + WR_DEMO my_pict.pcx 19 + + WR_DEMO captures the entire screen and all color planes, so the + size of the resultant PCX_DEMO.PCX file may be different than the + file it displayed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p. 5 + +5. Using The Library + + The public functions in PCX_LIB (i.e. - those meant to be called by + application programs) are: + + pcx_read - display a PCX-format image file + pcx_write - capture a displayed image to a PCX-format file + + pcx_isvga - determine whether a display adapter supports + VGA BIOS calls + + pcx_init_dsa - set up BIOS to capture EGA color palette + register updates + pcx_free_dsa - reset BIOS to state before call to + "pcx_inst_dsa" + + All functions are fully and exhaustively documented in the source + code files. Example calls to the public functions may be found in + the source code files RD_DEMO.C and WR_DEMO.C. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p. 6 + diff --git a/16/PCX_LIB/RD_DEMO.C b/16/PCX_LIB/RD_DEMO.C new file mode 100644 index 00000000..72fce199 --- /dev/null +++ b/16/PCX_LIB/RD_DEMO.C @@ -0,0 +1,169 @@ +/* + ************************************************************************* + * + * RD_DEMO.C - PCX_LIB PCX Image File Read Demonstration Program + * + * Version: 1.00B + * + * History: 91/02/14 - Created + * 91/04/01 - Release 1.00A + * 91/04/06 - Release 1.00B + * + * Compiler: Microsoft C V6.0 + * + * Author: Ian Ashdown, P.Eng. + * byHeart Software + * 620 Ballantree Road + * West Vancouver, B.C. + * Canada V7S 1W3 + * Tel. (604) 922-6148 + * Fax. (604) 987-7621 + * + * Copyright: Public Domain + * + ************************************************************************* + */ + +/* INCLUDE FILES */ + +#include +#include +#include +#include +#include "pcx_ext.h" + +/* FORWARD REFERENCES */ + +/* GLOBALS */ + +static char *use_msg[] = /* Program usage message */ +{ + " Synopsis: This public domain program displays a Paintbrush (R) PCX", + "-format\n image file.\n\n Usage: RD_DEMO filename vi", + "deo_mode\n\n where \"filename\" is the name of a PCX-form", + "at image file and\n \"video_mode\" is an MS-DOS video mod", + "e. Valid values are:\n\n 4 - 320 x 200 4-color CGA", + "\n 5 - 320 x 200 4-color CGA (color burst off)\n ", + " 6 - 640 x 200 2-color CGA\n 13 - 320 x ", + "200 16-color EGA/VGA\n 14 - 640 x 200 16-color EGA/VG", + "A\n 15 - 640 x 350 2-color EGA/VGA\n 16", + " - 640 x 350 16-color EGA/VGA\n 17 - 640 x 480 2-co", + "lor VGA\n 18 - 640 x 480 16-color VGA\n ", + " 19 - 320 x 200 256-color VGA\n\n The file must be comp", + "atible with the indicated video mode.\n", + (unsigned char *) NULL +}; + +/* PUBLIC FUNCTIONS */ + +/* + ************************************************************************* + * + * MAIN - Executive Function + * + * Purpose: To read and display a PCX-format image file. + * + * Setup: int main + * ( + * int argc, + * char **argv + * ) + * + * Where: argc is the number of command-line arguments. + * argv is a pointer to an array of command-line argument + * strings. + * + * Return: 0 if successful; otherwise 2. + * + * Note: Usage is: + * + * RD_DEMO filename video_mode + * + * where: + * + * filename is the name of a PCX-format image file. + * video_mode is the MS-DOS video mode. Valid values are: + * + * 4 - 320 x 200 4-color CGA + * 5 - 320 x 200 4-color CGA (color burst off) + * 6 - 640 x 200 2-color CGA + * 13 - 320 x 200 16-color EGA/VGA + * 14 - 640 x 200 16-color EGA/VGA + * 15 - 640 x 350 2-color EGA/VGA + * 16 - 640 x 350 16-color EGA/VGA + * 17 - 640 x 480 2-color VGA + * 18 - 640 x 480 16-color VGA + * 19 - 320 x 200 256-color VGA + * + ************************************************************************* + */ + +int main +( + int argc, + char **argv +) +{ + int i; /* Scratch counter */ + int vmode; /* Video mode */ + BOOL status = FALSE; /* Return status */ + + /* Display program title */ + + puts("\nRD_DEMO - PCX Image File Display Demonstration Program\n"); + + if (argc == 3) /* Check for filename and video mode parameters */ + { + vmode = atoi(argv[2]); /* Get the video mode */ + + /* Validate the video mode (must be valid MS-DOS graphics mode) */ + + if ((vmode >= 4 && vmode <= 6) || (vmode >= 13 && vmode <= 19)) + status = TRUE; + } + + if (status == TRUE) + { + if (_setvideomode(vmode) == 0) /* Set the video mode */ + { + /* Report error */ + + fprintf(stderr, + "ERROR: could not set display adapter to mode %d.\n", vmode); + + return (2); + } + + /* Read and display the file (assume video page zero) */ + + if ((status = pcx_read(argv[1], vmode, 0)) == TRUE) + { + while (!kbhit()) /* Wait for a keystroke */ + ; + + (void) getch(); /* Clear the keyboard buffer */ + } + + (void) _setvideomode(_DEFAULTMODE); /* Reset the video mode */ + + if (status == FALSE) + { + /* Report error */ + + fprintf(stderr, "\nRD_DEMO - PCX Image File Display Demonstration"); + fprintf(stderr, " Program\n\nERROR: Could not read file %s.\n", + argv[1]); + } + } + else /* Display usage information */ + { + while (use_msg[i] != (unsigned char *) NULL) + fputs(use_msg[i++], stderr); + } + + if (status == TRUE) + return (0); + else + return (2); +} + diff --git a/16/PCX_LIB/RD_DEMO.EXE b/16/PCX_LIB/RD_DEMO.EXE new file mode 100644 index 0000000000000000000000000000000000000000..02bbae17dc9b575f7af6618394d8558ecbda4ce4 GIT binary patch literal 26804 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 F{RhdM1hxPG literal 0 HcmV?d00001 diff --git a/16/PCX_LIB/TEST_06.PCX b/16/PCX_LIB/TEST_06.PCX new file mode 100644 index 0000000000000000000000000000000000000000..0d1068cfb58f94c8a8a58d29b4028521f62922b4 GIT binary patch literal 3962 zcmeHJO>7%Q6dtFFPy$i}Qbcb-a6s|_IC0>TqNu8nKu)or3@B10PDtE(=+(VZap7cf zOjSU}V~JdPH{;FjdYy(O{z>A9s!%CyG0>z&mKrPR@ZQYqdN;8*J@mkVMApuG-}~O1 zdGluGO^zoL4F7UtF1v;Q_$Q^DU~}&={4Koyapr@$4=<({=I1_H$XrZk7T2<~?*sE9m8N159FMP>fVOQB}_`6lep3k1Y#>Uw-HaYS2 zg!R(x!cSj(d*$<~AKsL56XR{lJ5n66+yQ+n{44rS!{r0{E2=G?+n1IU2OI31E5&0A zW|Z9B;3br67B48dw*hHa<}FBv;H1Ti0qUT)70BcskvpQJqHpuEl8KIT&xQ*-Y%65Z zvH9}06i=1TShZ}(20HD@;iW*Mt@1Xc1C=&P+PoO3$jU~?4rBrynW65;<+-hJOw=8_ zFwhyhzRSxe?RqXO20CNcb@@`DGjaD^NCi4$*KzrBpfh$Y7qWrQ*wtKK2z1&m??O6I zX|pOX1sZMS0V!6c_}OMtD}It~nRI#4Aa`-8`wBWi835#c1^sy3=hVm**^{~o8DAgx zI!y^6Lp$~$*V2> z0~q&dG&k?S;%I8p;mcue*W*he$B+tBdmbzfz_X~4s7SrA#c&Vr3OS7UyF#$IPR7$f z93>KG&x6!(O2^~NL!&$!<^L#y!}44+Min=7U#QxKZ)KPg*_UUdoT@QLw(j69KB6=o z*;JQ4!gxuB>yu6)a$z`^jxgRAPg`8$CyJZM2p_i~ho2#_PxB+e=>m!6)BO_@|4csK zlsNIw^dsTv!bEuV^iRA8suEa-`f(g%yiT+*u+ z%crL>$`6MZ^m@kf>B)`qBk_A!fU$gf+N1nPeCh^b`P4#0`H}e4bzt{2V&fc1oeJWi zni+(5B(*kiY;1<2sG-tapH15z(~Ke$>#4eNdLQks62Y|yJ}avvB-cfJoaTerg~P&*)HRkaPchR3)g z*6VL?Vkn1~g*?EvIAOtjVguVB2XaF0OYvmV;V-V^*JgXtk{a|kc}Wd=bx_}0o#*OklCQ%oeUo)wuFF4gG7U)8jvpQbKr<P293 zIx5MyTu7m$QXgP?M|@0glm;!@zjA}p1SxC|%(nWV=&$o)GeC72XmEw9qiis2c1_Xv zpm?IHN%^%+jcE+8;Crk5=9czKkDD$@jp8No(BnUDYt;2iSc7=b`q)Ljv7=Eu9Qq8j YQKk%e=*(hMyBdCIwDiT*{b$5~0msyU1poj5 literal 0 HcmV?d00001 diff --git a/16/PCX_LIB/TEST_16.PCX b/16/PCX_LIB/TEST_16.PCX new file mode 100644 index 0000000000000000000000000000000000000000..dabf401d229afd1845df8cf23e4ae99d3e919bf9 GIT binary patch literal 32097 zcmeI4U92R>b>C}vNsq+H93v1D!C^Qu5+DHs!%lz%0%GiJ0wc&%pa%_Z5G1}zfB*)P z2g48ci@}*hNeIM%`49*4gMko+V+pfH_C*hQP;{r~e(pDy+`CKagWF3jX>s-8iHxUuC4UvXQ;Au?c%+lu-4VLaqEq2xb;?+ zOmDc(L;xOKcq1EKh)X<;H7*~ATW`?K)?3-3>+I3|&{^w~ZHiC&wc0YOI4n7QJ2Ttp(ro4ix3l4%YhAKW zvFq!sdbA=B`I$K2P}EcUQ7~*Hg>UF2#ISiwo+nW>=hXD@u&p z%-zadmo`kM?iIi?r{H$lzXiypVo!}Vq*q*fUub-Zv6{ASWy8)%w&%94F&ukL?&Q&h zTj;J@=II#J`8C(u6BA!zOwz4ev~BYNk^y`c#^>QSB`5l*6bI_Jvf(w?GFG9)co`dC zFmY|nDV4)X9$bXY1ArytxHwQV#IqZ&I}xr>Bxb`7^uh@$O;Y1@vP0oRR23Bl!aLdU zhHHsSC@>~n=x41r`9Shb0D)(;OW~sn)xx2tyba||*G6D5E%6B@4>IZ2sSTgZJ6XGC1a54Qpijz2jQ?Wvrt0{J>DB5@ zKRh{$4?M%$nPb9BKb=E_9@w8L=xzfrQ~+^m+(Znk>6@-oyc?f+iy6~{96d1ylJv-R z`Lht!h1;ksRKZDQo*e6Y)3u7%Dx=hG!C+=n3X)UsBqsty#fhMM9x$ArxZ>4#%(kSy z?oIRnh|6LG!6R@a4*)``F$iSRzi|lfo<$qtR2~+^;O3L*71!Gro6~J-9`1x1&&U&_ za?i)V8lR~>cc5nNI>@fd+Y8G@VY%pwZ>uB_%2C`_cfz}8(t&y^CM=_1!QBt`)ac<( zj)e-(#*@Nk>e={rW0Tr5YtK+!NygXYd*SlnB3vE;hH_&P2w^h512G?F!QcUtzog zDF!e52K=o@DAN4wqHtWI*-lwy(YuRg8T*SWl1K)}_od z_JtpaF5Q>HlRyUp7H{4cughVS0v_xlU?I@dn}ECf*>2eo0b>@OOW->&?CV5~rP=9C z*GnP^Wf#WoEtS^=9J%%tt%1_a68E8%v{*EyYy1lfnQvJ zHII(crpHBiHGH7Tn=FB`~fFvx#ZM)`Rs`jf~R+$I`$QT?3cq1c92l z5od44zN(4y@W58m*%^$dsDOo{rd`-h-B%mbd*BGN>1QL_o*bT5&=d!pEN+)vgSYEj zUCh@v(PTVuTbIR|bzj_lMKtqr4MD_`a1I~FFvlTMB z48{yUW}d{aoJo2d56KP`r`w`{1#xlrxE%0&B|~$pS1mLr1xm2QdET+wQY&g-)d*s# ztkDF5^3sK25$quE(M37U|iTNOjKFOQf%eMNX}#gUA_MQ|;HQsyJ=494!+ z*SyRbn=6HkM19cQ^^0#{b3J3;`-qZ1NDSo_i9TABM9n8Hc}QfUloD-UGj`91Ud~!9 zx0hV2BG7X|1T7g9UoVNiB9=I_qAn7rnqnxlLl@Y}mJ(}yoNCe%jk21QeGF`nfzi-O zU(ai(sEG8@F(OmVH}>9I*B7zKQ|;U6g>CNKOQ=e=lXg(M-)xo=Jr`P{9mOxco_Al-C~&NZK@MN^?BF#1 zv0Uw%>1aQ6bljDJ!5$1a7Sz)qo_ejhvRutnh#E00oHk2W*#-iEnWrYq_(QgyJkqd7 z`C?@9N50=f#P8dJM${6^_Ph{-Y{s3*mzds7w6Bc2?{|sg%jOplGo(idW1!^7*h2>Z z`|R-8{ft|ENGGfS$7qQZ3%y_9PAs&&>nBmk(zjKoApOY1!UXL?Eo?8zQmGEOgMGh& z^=J$ceV{d?C^SSP1)9;W&^$FVG;RPIC44*@{y--*5knSIuSd9Si4}&Z{y`k}%@P|y zu|0VSh3UD++Ciu#C>TfqB{|se5>0?<(0i|GAKtVif(NLRL7(yE|0d*uw zPpC}YGxv62pROe|TG0wDql<#_tklA=FWeZlG?pp=}Mf<$tNXSciEVFcGY<-jMD5Bd-?>Qmvs4$K)? zqREg%+&m8XLN>a%YFr)cX4=sCj5drS6h1*7P*})|naeQDMCZV=5%q@bZhYk_9Tr29MeJ>D1vR_V)R81B(-_yfnZuJ zyFnij%M!{|Ap=l|l#+1=ET!BSO*niBXyh0$DE(2auK_L5oc5JtJnf$kaJq~R&~2Jo zEj43ehxXI0?tVvF*zDEsri=L ziCT^(W?AAHoAsc1@XVAijL8Z_hw_9r&s+IQy%y4BBug!76by_;dJJ?Za2d)ohuM>S^Lpwt8alzgOy4Z14N0@YB% zr|=F?^A;+v(#5EX1KR=>0~b&!3m2n$G`a|?2cy>ls-B@zFDjs_EQQ&8lzp6uErXxb6tX`K`7AGsSA7x z^|b%v;6$vk6Otbm+E_ zJhs4zp?K=!b*RHCQmk*A1}Brgss7^?tPCP&fWZP4f-Uo|KxNHiLCk?Rkw-`s@(!?B zvNl9g^0Lnkk&b%Gkw0{wjn$ewn2fX$o{TQa&Yq<&(dg3>fBIQMrvmW`85Pj%0H7y! zFe_Esu@P5{Tqlhnhp_9Bf8<||>UutO=PS^$*=^c9ob-2uofZ{U1D-gSO>P8!g_s(8 zId+_Nj($a>0{*cMR`JuUgi`gM`@28&*UnQE>77Rs(Gh&wj1)-hjnv(JYeIkZqKQYO zLlaz31b>y75`2&5jJ;OvnZchEjWlD6z}xw6 zT~Ocm)vVeL#`b#Ai`9aBCweeR%~mczU(J<3Xzdos~5)pC#O^`g##kL%qblL_Fmr5t|{i!>BO>#vKqZ(HB@R zbH=U#+H;>z{x~@eS|+kkk?r6PZQqh_f}kIHVMZU++XW~?-9z;Jda)N;=1t3#?IRtX z+3M}Ry#aOITT4(Pl*#n6DF9THUwqBO%%e+S+BtNwQ>0wZ`b29!y1|6XhxD-p^Y^xP1;YuEXWdRLL-1HLmG-m(So|?TLhpAa_~1jDT%}zP8IPo-e4JmTFUV3C56}} z2P(f{?pRPu+9jYL`|NWs|4$EeWGl}S`zU_ zegsk1;l~R0;!GMgLWp6(onZ?Q3(^|MJ@?u_Vq~s*jFw_na!Mnx?_`#Bi2I>|M>rQk ze;s&PgAwllkUvV`38ze-u|<*)Mx-@>6ZhtV^1alTs?85EEL$ugwBnIwPpi(XG!TG*jiPlk(W+A_)j$N{K49Inp+PYP3| zyM-rZs0%2$#2OZslKcOl|68=;(1Cy2`&SOd3mF$GkFLjDlH3ob zoeNt+(fvC=E4%R^l-{Y{1}IR7t^g6;2B@P5{0syWYiL2Y3N?w zPu8|_!EG63z@t1DS(+bXrSdnSswx6h&KEYi=_T!ShH^z}aUb3hO%2tad;Y&F+pDqC z>ab{rv@bI6Q0;0Bc%EBbQWCT9o(CZ-n7v}c)m_9QfrUUHHpC{HD?d!;Bk#yA0_OAU1_kOeGq zw?t5@v3QOLI$Z?GbTHK76eIBjOGrM6090c4$&&F(B%eIA)ebU67Tm&HsT46JvB7YF zW5xntC|KbZUL&esLa_zCU~qMX&(y=1Eh}Ve==A}e$06o~wn({KHCynBCrD_4r5FsI z@XkC8tF7ViX@6a9k&&zbacJ3o7Ka`Ph$dDd@Z7Y4WX`Zn6H??)CEwT8#G^8>Vh`Fx z>52=z!ol&0A?1^oo2U#0-dHDt$;Sj=gZEK`9)kt|Ru)?^IVAym0nhRpFv6 zg|mUQ-qQtPSS#FinJlgB!H2PIazdr(DbGsVvAt#&RTT|kkbIaCRH6w{AvawscV=Tr zat6VdqCTgG*)G#*ik!UTkZSAJ6Jt9>jI>^m3oL`n@hbNVJP4gB-S@?fV@~o*21hdA z+no)AANG45#VkSrH8#xZ&{I&tSX9+ev?zci>7kNmB1Rirk6(#J_dHNP+kSvB`(%Z| z{tC819e4;$C14B`#9@zT!XO^+i6PYBz=7Uhr4u}siS|J7LQ2f61TwTsEB@4y)anLE zIK(&pP%}MTj+%KlCQzBN!tJkgO0+X)x_OfrxDB;0UVSF z2(H1B7b|rFHAq-34N3PbBuAMUA3!v3()B?27K*lQ>Mq&gGjKrcjSf037qp6IO<`5R zSi#I*gCNN?yuVf-+&>ZoRt)o)KJm0#A&@fE>pEM)grDS~kx3nNA(KL+ge5TIt*F*a5VSg$dQW9=4urqm~+YJJ5WNj8jJG3)_m<kX21qu;d&2(^>&y=9zibnWZJYo!Om4a5^A_LjtRRHU`6%~{>4XNCJav%%VM;Yg=AwwWYZ+9 zrvpmFiIBK~vnr_W#sZPV1#1c9yWsEnmqMT_nUYcOv_Oj={-?*EMYB+)v_vIhtnOu{ z;zU}JZ227&s4ud=ujyId!bJ;g&MR^mA)Q|5$K;xMg-ThzwA+wGk!d{b9*~G@A{8TQ z(DXI@_i0s=n#NMKXV8xUH1-h#8q-+g-O2@uvLa6hI!E3}_yvJK@Nb27apP<^%3jhR zd}@!IPIC)YLd;fn6PW@`JJF#6zJN%rQP<__3s@3wzl4Bfy~mRAu@%V-mH&~3#@=cT zfdP_5S4g%1uOe9oQimql|CYnI{Cgo;L&P#$Skz_REV8?w&0R*Ykn4LJ1CX(kkk;&! zqApi~Cf~)hU!p*)USqM!fktAL{t7>n(b!|#R3O*rOmYv&=$+?^WKO5qmD6wkOBx^8 zYa|#?Sdq(-fvE8sE96?}u0gjh4{e$maZRjJ1l+OZE)MJU2beUkgsL4nl+ zg6a%X4^fzgLm^qJxioH+suL8sS^GT`#Ogg3n^wgt1|pSfUlwWXFgWmE=J9+OHbXRh z*LJ7UW2}VuK*o~Vt?38;J(A7v#y!@OYrhz?O0F~}$7dJ!Pw}7@iq(bU0l5dSACy6& zUJ8kt2jo`@tKu7Lw!PJ7C8E}7YVwS2(jpbFSEZ~ARTNLq;C~hexq4qCSGd^7u|`!l z6{TRjKP=?=s+1MM+?>Yfbd{eucbI+KUSqNE#NE}!2L-J}jFp%*7OJxX{7{v!CQ~M& zFViUoK1Qg$M^ay`3N4RFF$XC$S_m+Eb{%qj4*f9EPZ6%gCG3vjDE z$th@#*J`yW<~;oaJm*!OqGA7}AEv7D)IdmLwHA8Ceb#gT0MBWaCuWJ-$W>Q)vh356 zD~z>D{k9Mczw7_NF0Halm-uLX8Qd+4;W_p!{9kyC&*Y(TtMcGZm0%#BzpRR9ve1ZC zSxf^9`+JS8Pd8CPKIG@}Ze~nCH2QcA7}m#YKq#_N1H}-o_lFt3f@Xi^ z9X4-Dw%(fBUz(!pF5i%p(>Fz=xVs|dYKrhB1Zy(8?`8bLo`3L-*)wDK*0f9%TRUEX zid*VhBmY1nEJS(xMcypRZCg9N(@>^p4gG^}s0{r4mh0Zrm?kfrE* z4B3zaLHX`mu4Ci~Y#X^A_Bf*wu|6TaCmM~ke*BNE*mui^TJ210A=@3JC||B-@49xu zV(QqTvrX(6RrFRROHq((8%_RLB^X<_W6LOt=L(5VK$Em3isG?Kpj6Pz6XcH-0-tJj z;!r$R36$?#c!K;fR*HV?kZ8gUzLQ0dbqY@Thk+tI)+pvG#*pBVKWfbHX|OdiDz|NS zpvj->L^G@C8l&PFqV%5Y6`W=Y`qMy^KW|Djz2^o6r>V8>n7HB@PP2RN-5mE+$>nLF z$)BN_b8>ek(Sp71dZKGt>e^?K4DY(mSv1M`uIrvjl-_l{Gl`~m-QY~3`8%%l%|b~{ zie$N1yyLbCqQ-G!f&YfO0~a@lTgWM6mf zf?%<1`Z%xg*Ic(GS)M$Vo-TtRn!7^JGg>5ffTWRsdBjy0fW&=n2#TdX8e2_sXBfov)*jxr4+K? z<}9FHbgd}12k|XRxZJEP@trd{7A>j|6=u~cDQA}HCtDuwc!>g@Qo2m168)&mgMe){ zuBAZb@ZHt}#VP@42>?tg3Ga75tEDu-Aw(YCL<-egSp4 zabA&&rg>fzHJ`rEPq#IQro19K&_ylN_btV+EI6--1m{JYHoq2kx}ov-eO)SQfSp%F zvh$)yc3!lka8*=f=agmRVedX(wA&;-sw(A2g%J~0X#7qi6JHgh7?#wJ!$RC69Dg<@ zKT;g*7E`|6nPl%~Y}j>n#WPzp4_&pa+-%O|y^G>^y$3Je3np2nw9zUa^6N#LKO>JP zIHda@@wnL8ht1sYA)Sz{X^gvKHb^NE+*ejW-Aah5UvBU z>4+U?uOxe>0s9VAH+h&Wnh`Y6tpo5lTIlkPti|PQ2TOm{;~KzXr*RaP$<_hbTmv0M z&M#*_gZSwnIbEfIWwLeRAE*Bv`akpiPXV!F0G6oMiQl~U?c|TRfskqV*9c#tS||K* z`u<-?Do%RIyZpJ6yvOfL{5nquGKF`gik;+t50Y=~{*KU@FOR3?hHYg`KddJ{&i);^ zrb+g~x%O}?S$t~ng6t&`#_n%)|I>?~7*M|q@yu2nhphznIC@MD2Ebdqxcf?Sk4Zd# z`71ps(F5%4y!w@MjVe65*@vUOB<&fzuHa3RS+aPcCzDIi+DYj<9$EzEmj_bg9xxwajoqD2GVe8Oa-*gnk~ZgjR})AJQ|I?dH2u?o znImO#;7Qhbg+I+WH*32N=;n5LDcklygINmn%rvTjN25U9`CPIv@8j``xdl+yH*LEP z>ZX41Qua9mno6S+4>Pw<)9AF5j0aqQU7F+9H*2{L%a6@j9@ZYc%;lDt$4xQ5$+$Y047|e)m=8QddiElTtTr{9(=f9uo)u zc`i59L9kP47`;xqJLi5sd9>Sr^;))J+jUSk)#@?Az6sFzIa4d1bnsi|NKqqp`eL`! z`xqW-1KbogQZj*1iwS+>`ElM@oE$Hh-bJ)BXLIo0Yjq!*w7x*JLNTf+nwe zO@j5gUwcmGiA|a&C!H65uE{p9Wt%iy2k~+A*d{ERe)%UahGqSwWbypA-zh9!{PFD{ z`|?jVxTI^@nXNvI8GfAoL^qk8+j_1wJip6#LO$1J6E(*Dv|F$I?5|nqQFlSt&S!4H7`<#U8hC*YrGP1I;%VUdDv8+&Op@=Ik z71wU@#o|bPFqC1D0y~{(yLj3mfjr2Igd{v75K#l#1eE|uK;ZVj5Mzh|f}ksoxsyA| z|9|KE&-wmy?zy?Zq>$(sdaWf1F%CN9I0+*iVqhCqVdx$8tGC!&HoUPhJSuF%+fnR| z;q3SP1DB)ESZL%iEVp#QOBiV#iG+zT65>!F#xMrvmD0B$4f}iPZp;%)!(K&iPHBX9 zg!hLS1^WyHC?3?I`C+K{gt|fA^T%a|xr^}ymt)PN{^=sQ z-PfoI_-u43cVVE(!odIy6;{;A9iGtdN zC^R03pEIWRSww`gkH|Zeh8ZB4pbHv(WFzd7PHNV80eBYBjDnaA{G2JbWfmMNHV)FU z>pIGX>6cWoLGqy18WuurC()%)%#x)bN4?<%$Gp~~ccxou%VHmBcx5c}*UTsp=HA)} zGIy)S$>+bK0SpTt&8V&}K`Er-3DWlRogmIN9pgKlE0yN<5bYbSwV2^eik>p+f58vRWOCG(>*(0(57`hhS6 zM1KH&2&nbY5~qFvbw`0FyHrH>6FNJq*<+Uy2jeE<#_l1m-cN<89F(6Lizye3qftSJ zfLqw6nc+;x!ya1<^?tVXY#atKZ~EU9b2zksE1N;+cER-cqjIFD1icA=CbG!mppiEx zb7Q-L;&x`l{p5ZyVVtO{Hh4bAiP&l#G$6hc5A5}Jo!uWHko+oPD%YPoe>?=FBkaxaC-Wg41u~`28zu4ioa8D?CPXu{SJlWIJ zbH$3a@BR4Y)Hf-qQIynO6mM_ufPnSy|MaWr+bQX>l=Rs62-L!&qTEP+8nl)>JgCh=a{MOlI+Sx4H**scMP*7;- zJAe7LSMl#@#fNCcr)a^!!C_(Vo(TDN*&pd;x%9F#^sun7@bK8vTVJWlq*r}Huev~w zh=|y}{WoXdTy*Im{n82gr4o8{bo7oLyNcQ0xst=UQoy)U&WMkXkB&|%i})`02!s1K z2KRGDVq#)UOmbD^_k^D?gclgX%Z%jYVYXH=TLsMQ?ChkZ{rrT*y7L}7j)zX_k(-;FoP1D{_z0xBuFE1tKBW2R-hEfm1e?1J%9{KtCX=%C5$v^1*2dlT1Wol;?78W{<6crU^ zX6Ci-`%&-bUcG!TQ-@b+X=!%$r)`;mCeC7$XmQ`Q#g&znxw+>$4sGcBw_l&cum8Fq zhr`LsE9w0BjeZF1mj@2q46LrM&d;y7acuiQP0)Zc$gB^lsi`R}v7wg3LpKf&-OKIj>f&-c2WrmTZ##Lv z>*RgYNu$vy6yCB3iifYA8@_#RxbM8lWRl754aq7-ZkCN0%SHw+TCG-<$}+6}*XS+I g=v~gJJN~+*E@Paxoko#0kCr4}>L=NdN!< literal 0 HcmV?d00001 diff --git a/16/PCX_LIB/WR_DEMO.C b/16/PCX_LIB/WR_DEMO.C new file mode 100644 index 00000000..9ea6e668 --- /dev/null +++ b/16/PCX_LIB/WR_DEMO.C @@ -0,0 +1,209 @@ +/* + ************************************************************************* + * + * WR_DEMO.C - PCX_LIB PCX Image File Write Demonstration Program + * + * Version: 1.00B + * + * History: 91/02/14 - Created + * 91/04/01 - Release 1.00A + * 91/04/06 - Release 1.00B + * + * Compiler: Microsoft C V6.0 + * + * Author: Ian Ashdown, P.Eng. + * byHeart Software + * 620 Ballantree Road + * West Vancouver, B.C. + * Canada V7S 1W3 + * Tel. (604) 922-6148 + * Fax. (604) 987-7621 + * + * Copyright: Public Domain + * + ************************************************************************* + */ + +/* INCLUDE FILES */ + +#include +#include +#include +#include +#include "pcx_ext.h" + +/* FORWARD REFERENCES */ + +/* GLOBALS */ + +static char *use_msg[] = /* Program usage message */ +{ + " Synopsis: This public domain program displays a Paintbrush (R) PCX", + "-format\n image file, then captures the image directly fr", + "om the display\n and writes it to the file PCX_DEMO.PCX.", + "\n\n Usage: WR_DEMO filename video_mode\n\n where \"", + "filename\" is the name of the PCX-format image file to be\n ", + " written and \"video_mode\" is an MS-DOS video mode. Valid values", + "\n are:\n\n 4 - 320 x 200 4-color CGA\n ", + " 5 - 320 x 200 4-color CGA (color burst off)\n ", + " 6 - 640 x 200 2-color CGA\n 13 - 320 x 200", + " 16-color EGA/VGA\n 14 - 640 x 200 16-color EGA/VGA\n", + " 15 - 640 x 350 2-color EGA/VGA\n 16 ", + "- 640 x 350 16-color EGA/VGA\n 17 - 640 x 480 2-color", + " VGA\n 18 - 640 x 480 16-color VGA\n 19", + " - 320 x 200 256-color VGA\n", + (unsigned char *) NULL +}; + +/* PUBLIC FUNCTIONS */ + +/* + ************************************************************************* + * + * MAIN - Executive Function + * + * Purpose: To write a PCX-format image file. + * + * Setup: int main + * ( + * int argc, + * char **argv + * ) + * + * Where: argc is the number of command-line arguments. + * argv is a pointer to an array of command-line argument + * strings. + * + * Return: 0 if successful; otherwise 2. + * + * Note: Usage is: + * + * WR_DEMO filename video_mode + * + * where: + * + * filename is the name of a PCX-format image file. + * video_mode is the MS-DOS video mode. Valid values are: + * + * 4 - 320 x 200 4-color CGA + * 5 - 320 x 200 4-color CGA (color burst off) + * 6 - 640 x 200 2-color CGA + * 13 - 320 x 200 16-color EGA/VGA + * 14 - 640 x 200 16-color EGA/VGA + * 15 - 640 x 350 2-color EGA/VGA + * 16 - 640 x 350 16-color EGA/VGA + * 17 - 640 x 480 2-color VGA + * 18 - 640 x 480 16-color VGA + * 19 - 320 x 200 256-color VGA + * + ************************************************************************* + */ + +int main +( + int argc, + char **argv +) +{ + int i; /* Scratch counter */ + int vmode; /* Video mode */ + BOOL status = FALSE; /* Return status */ + PCX_VSB *vsbp; /* Video services data save buffer ptr */ + + vsbp = (PCX_VSB *) NULL; /* Initialize video services buffer ptr */ + + /* Display program title */ + + puts("\nWR_DEMO - PCX Image File Write Demonstration Program\n"); + + if (argc == 3) /* Check for filename and video mode parameters */ + { + vmode = atoi(argv[2]); /* Get the video mode */ + + /* Validate the video mode (must be valid MS-DOS graphics mode) */ + + if ((vmode >= 4 && vmode <= 6) || (vmode >= 13 && vmode <= 19)) + status = TRUE; + } + + if (status == TRUE) + { + if (_setvideomode(vmode) == 0) /* Set the video mode */ + { + /* Report error */ + + fprintf(stderr, + "ERROR: could not set display adapter to mode %d.\n", vmode); + + return (2); + } + + if (vmode >= 13 && vmode <= 18) /* EGA-compatible video mode ? */ + { + if (pcx_isvga() == TRUE) /* Is a VGA display present ? */ + { + /* An EGA display adapter is present - instantiate a Dynamic */ + /* Save Area buffer to capture the color palette settings each */ + /* time the palette is updated */ + + status = pcx_init_dsa(&vsbp); + } + } + + if (status == TRUE) + { + /* Read and display the file (assume video page zero) */ + + if ((status = pcx_read(argv[1], vmode, 0)) == TRUE) + { + /* Capture the entire screen as a PCX-format file */ + + status = pcx_write("PCX_DEMO.PCX", vmode, 0, 640, 480); + + (void) _setvideomode(_DEFAULTMODE); /* Reset the video mode */ + + if (status == FALSE) + { + /* Report error */ + + fprintf(stderr, + "\nWR_DEMO - PCX Image File Write Demonstration"); + fprintf(stderr, + " Program\n\nERROR: Could not write file %s.\n", argv[1]); + } + } + else + { + (void) _setvideomode(_DEFAULTMODE); /* Reset the video mode */ + + /* Report error */ + + fprintf(stderr, "\nWR_DEMO - PCX Image File Write Demonstration"); + fprintf(stderr, " Program\n\nERROR: Could not read file %s.\n", + argv[1]); + } + + /* Free the Dynamic Save Area (if necessary) */ + + if (vsbp != (PCX_VSB *) NULL) + pcx_free_dsa(vsbp); + } + else + { + (void) _setvideomode(_DEFAULTMODE); /* Reset the video mode */ + + fputs("ERROR: out of memory.\n", stderr); /* Report error */ + } + } + else /* Display usage information */ + { + while (use_msg[i] != (unsigned char *) NULL) + fputs(use_msg[i++], stderr); + } + + if (status == TRUE) + return (0); + else + return (2); +} + diff --git a/16/PCX_LIB/WR_DEMO.EXE b/16/PCX_LIB/WR_DEMO.EXE new file mode 100644 index 0000000000000000000000000000000000000000..8c74b5fd0f77e054018a791e15008e3b060f35af GIT binary patch literal 30472 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 byIvHWEh#Bk{!mX-7!4|h|Nr_QlED84HeWIk literal 0 HcmV?d00001 diff --git a/16/modex105.zip b/16/modex105.zip new file mode 100644 index 0000000000000000000000000000000000000000..9457bd98ecabf87d3e5eb233b115e1edc76cfca7 GIT binary patch literal 264999 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

RuOR|xlwa%V{n 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 F{{R{PXgUA@ literal 0 HcmV?d00001 diff --git a/16/modex105/ASM.BAT b/16/modex105/ASM.BAT new file mode 100644 index 00000000..2e5785f9 --- /dev/null +++ b/16/modex105/ASM.BAT @@ -0,0 +1 @@ +MASM modex,modex,modex,nul \ No newline at end of file diff --git a/16/modex105/DEMOS/BASIC7/CHARDEMO.BAS b/16/modex105/DEMOS/BASIC7/CHARDEMO.BAS new file mode 100644 index 00000000..627e3278 --- /dev/null +++ b/16/modex105/DEMOS/BASIC7/CHARDEMO.BAS @@ -0,0 +1,164 @@ +DEFINT A-Z +DECLARE SUB PRINT.STRING (Text$, Xpos%, Ypos%, Colour%) +DECLARE FUNCTION MakePal$ (Red%, Green%, Blue%) +DECLARE SUB LOAD.FONT (FontFile$, FontNum%) +DECLARE SUB ERROR.OUT (Text$) + + REM $INCLUDE: 'MODEX.BI' + + REM $INCLUDE: 'UTILS.BI' + +TYPE FONT + SetData AS STRING * 1024 +END TYPE + + +TYPE VGAPalette + PalData AS STRING * 768 +END TYPE + + + ' Alternate form of LOAD_DAC_REGISTERS so we can pass an offset into + ' a String instead of the Address of the String + +DECLARE SUB LOAD.DACS ALIAS "LOAD_DAC_REGISTERS" (BYVAL Addr&, BYVAL StartReg%, BYVAL EndReg%, BYVAL VSync%) + + + ' + 'MODE X DEMO of Multiple Character Sets and Block Color Cycling + ' + 'By Matt Pritchard + ' + +COMMON SHARED CharSet() AS FONT + +DIM Pal AS VGAPalette + + REM $DYNAMIC + +DIM SHARED CharSet(0 TO 3) AS FONT + + + LOAD.FONT "SYSTEM.FNT", 0 + LOAD.FONT "ROM_8x8.FNT", 1 + LOAD.FONT "SPACEAGE.FNT", 2 + + + IF SET.MODEX(Mode320x240) = False THEN + ERROR.OUT "ERROR SETTING MODE X" + END IF + + + A$ = "": B$ = "" + FOR X = 0 TO 31: A$ = A$ + MakePal$(31 - X, X, 0): NEXT X + FOR X = 0 TO 31: A$ = A$ + MakePal$(0, 31 - X, X): NEXT X + FOR X = 0 TO 31: A$ = A$ + MakePal$(X, 0, 31 - X): NEXT X + + FOR X = 0 TO 31: B$ = B$ + MakePal$(31 - X, X, X): NEXT X + FOR X = 0 TO 31: B$ = B$ + MakePal$(X, 31 - X, X): NEXT X + FOR X = 0 TO 31: B$ = B$ + MakePal$(X, X, 31 - X): NEXT X + + Black$ = STRING$(192, 0) + White$ = STRING$(128 * 3, 48) + + Pal1$ = Black$ + A$ + A$ + B$ + B$ + A$ + + LOAD.DACS SSEGADD(Black$), 64, 127, 1 + LOAD.DACS SSEGADD(Black$), 20, 63, 0 + + LOAD.DACS SSEGADD(White$), 128, 255, 0 + + '*** Background *** + + FOR X = 0 TO 319 + FOR Y = 0 TO 239 + IF ((X + Y) AND 1) = 1 THEN SET.POINT X, Y, 64 + X \ 5 ELSE SET.POINT X, Y, 20 + Y \ 6 + NEXT Y + NEXT X + + '*** Draw Font Displays *** + + PRINT.STRING "FONT: SYSTEM.FNT", 11, 7, 15 + PRINT.STRING "FONT: ROM_8x8.FNT", 11, 17, 15 + PRINT.STRING "FONT: SPACEAGE.FNT", 11, 27, 15 + PRINT.STRING "PRESS ANY KEY TO CONTINUE", 8, 29, 14 + + + FOR F = 0 TO 2 + SET.DISPLAY.FONT CharSet(F), 1 + Yp = F * 80 + 10 + FOR Y = 0 TO 96 STEP 32 + FOR X = 0 TO 31 + TGPRINTC 128 + Y + X, X * 10 + 1, Yp, 128 + Y + NEXT X + Yp = Yp + 10 + NEXT Y + NEXT F + + DO + LOOP UNTIL SCAN.KEYBOARD + + Offset = 0 + Restart = 192 + MaxOfs = 192 + 96 * 6 + + Delay = 100 + + Offset2 = 0 + Offset2Dir = 3 + Offset2Min = 192 + Offset2Max = Offset2Min + 192 * 6 + + DO + LOAD.DACS SSEGADD(Pal1$) + Offset, 64, 127, 1 + Offset = Offset + 3 + IF Offset >= MaxOfs THEN Offset = Restart + IF Delay THEN + Delay = Delay - 1 + ELSE + LOAD.DACS SSEGADD(Pal1$) + Offset2, 20, 60, 0 + IF Offset2 = Offset2Max THEN Offset2Dir = -3 + IF Offset2 = Offset2Min THEN Offset2Dir = 3 + Offset2 = Offset2 + Offset2Dir + END IF + + LOOP UNTIL SCAN.KEYBOARD + + ERROR.OUT "DEMO OVER" + +REM $STATIC +SUB ERROR.OUT (Text$) + + SET.VIDEO.MODE 3 + + DOS.PRINT Text$ + + END + +END SUB + +SUB LOAD.FONT (FontFile$, FontNum) STATIC + + IF LEN(DIR$(FontFile$)) = 0 THEN ERROR.OUT "FILE NOT FOUND: " + FontFile$ + + OPEN FontFile$ FOR BINARY AS #1 + + SEEK #1, 1 + GET #1, , CharSet(FontNum) + + CLOSE #1 + +END SUB + +FUNCTION MakePal$ (Red, Green, Blue) STATIC + + MakePal$ = CHR$(Red) + CHR$(Green) + CHR$(Blue) + +END FUNCTION + +SUB PRINT.STRING (Text$, Xpos, Ypos, Colour) + + TPRINT.STR SSEG(Text$), SADD(Text$), LEN(Text$), Xpos * 8, Ypos * 8, Colour + +END SUB + diff --git a/16/modex105/DEMOS/BASIC7/MAKE-LIB.BAT b/16/modex105/DEMOS/BASIC7/MAKE-LIB.BAT new file mode 100644 index 00000000..fc0b3b5c --- /dev/null +++ b/16/modex105/DEMOS/BASIC7/MAKE-LIB.BAT @@ -0,0 +1,5 @@ +ECHO ... Building MODEX.QLB for BASIC PDS 7.1 +LIB MODEX -+MODEX,, +LIB MODEX -+UTILS,, +DEL MODEX.BAK +LINK /Q MODEX+UTILS, MODEX.QLB, NUL, C:\BC7\LIB\QBXQLB.LIB; diff --git a/16/modex105/DEMOS/BASIC7/MODEX.BI b/16/modex105/DEMOS/BASIC7/MODEX.BI new file mode 100644 index 00000000..6b1d7afe --- /dev/null +++ b/16/modex105/DEMOS/BASIC7/MODEX.BI @@ -0,0 +1,63 @@ + + ' ===== SCREEN RESOLUTIONS ===== + +CONST Mode320x200 = 0, Mode320x400 = 1 +CONST Mode360x200 = 2, Mode360x400 = 3 +CONST Mode320x240 = 4, Mode320x480 = 5 +CONST Mode360x240 = 6, Mode360x480 = 7 + + ' ===== MODE X SETUP ROUTINES ===== + +DECLARE FUNCTION SET.VGA.MODEX% ALIAS "SET_VGA_MODEX" (BYVAL ModeType%, BYVAL MaxXpos%, BYVAL MaxYpos%, BYVAL Pages%) +DECLARE FUNCTION SET.MODEX% ALIAS "SET_MODEX" (BYVAL Mode%) + + ' ===== BASIC GRAPHICS PRIMITIVES ===== + +DECLARE SUB CLEAR.VGA.SCREEN ALIAS "CLEAR_VGA_SCREEN" (BYVAL ColorNum%) +DECLARE SUB SET.POINT ALIAS "SET_POINT" (BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorNum%) +DECLARE FUNCTION READ.POINT% ALIAS "READ_POINT" (BYVAL Xpos%, BYVAL Ypos%) +DECLARE SUB FILL.BLOCK ALIAS "FILL_BLOCK" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) +DECLARE SUB DRAW.LINE ALIAS "DRAW_LINE" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) + + ' ===== DAC COLOR REGISTER ROUTINES ===== + +DECLARE SUB SET.DAC.REGISTER ALIAS "SET_DAC_REGISTER" (BYVAL RegNo%, BYVAL Red%, BYVAL Green%, BYVAL Blue%) +DECLARE SUB GET.DAC.REGISTER ALIAS "GET_DAC_REGISTER" (BYVAL RegNo%, Red%, Green%, Blue%) +DECLARE SUB LOAD.DAC.REGISTERS ALIAS "LOAD_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%, BYVAL VSync%) +DECLARE SUB READ.DAC.REGISTERS ALIAS "READ_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%) + + + ' ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== + +DECLARE SUB SET.ACTIVE.PAGE ALIAS "SET_ACTIVE_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.ACTIVE.PAGE% ALIAS "GET_ACTIVE_PAGE" +DECLARE SUB SET.DISPLAY.PAGE ALIAS "SET_DISPLAY_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.DISPLAY.PAGE% ALIAS "GET_DISPLAY_PAGE" +DECLARE SUB SET.WINDOW ALIAS "SET_WINDOW" (BYVAL DisplayPage%, BYVAL XOffset%, BYVAL YOffset%) +DECLARE FUNCTION GET.X.OFFSET% ALIAS "GET_X_OFFSET" () +DECLARE FUNCTION GET.Y.OFFSET% ALIAS "GET_Y_OFFSET" () +DECLARE SUB SYNC.DISPLAY ALIAS "SYNC_DISPLAY" + + ' ===== TEXT DISPLAY ROUTINES ===== + +DECLARE SUB GPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TGPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB PRINT.STR ALIAS "PRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TPRINT.STR ALIAS "TPRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB SET.DISPLAY.FONT ALIAS "SET_DISPLAY_FONT" (SEG FontData AS ANY, BYVAL FontNumber%) + + ' ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== + +DECLARE SUB DRAW.BITMAP ALIAS "DRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) +DECLARE SUB TDRAW.BITMAP ALIAS "TDRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) + + ' ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== + +DECLARE SUB COPY.PAGE ALIAS "COPY_PAGE" (BYVAL SourcePage%, BYVAL DestPage%) +DECLARE SUB COPY.BITMAP ALIAS "COPY_BITMAP" (BYVAL SourcePage%, BYVAL X1%, BYVAL Y1%, BYVAL X2%, BYVAL Y2%, BYVAL DestPage%, BYVAL DestX1%, BYVAL DestY1%) + + + + + + diff --git a/16/modex105/DEMOS/BASIC7/MODEX.LIB b/16/modex105/DEMOS/BASIC7/MODEX.LIB new file mode 100644 index 0000000000000000000000000000000000000000..0a0364a32d1d28549fa263da9c503a29079be2ea GIT binary patch literal 7189 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 literal 0 HcmV?d00001 diff --git a/16/modex105/DEMOS/BASIC7/TEST6.BAS b/16/modex105/DEMOS/BASIC7/TEST6.BAS new file mode 100644 index 00000000..220a67ba --- /dev/null +++ b/16/modex105/DEMOS/BASIC7/TEST6.BAS @@ -0,0 +1,562 @@ +'File: TEST6.BAS +'Descp.: A Mode "X" demonstration +'Author: Matt Pritchard +'Date: 14 April, 1993 +' +DECLARE SUB DEMO.RES (Mode%, Xmax%, Ymax%) +DECLARE SUB ERROR.OUT (Message$) +DECLARE FUNCTION GET.KEY% () +DECLARE SUB LOAD.SHAPES () +DECLARE SUB PAGE.DEMO () +DECLARE SUB PRINT.TEXT (Text$, Xpos%, Ypos%, ColorF%, ColorB%) +DECLARE SUB TPRINT.TEXT (Text$, Xpos%, Ypos%, ColorF%) +DEFINT A-Z + + +TYPE ShapeType + ImgData AS STRING * 512 + xWidth AS INTEGER + yWidth AS INTEGER +END TYPE + +TYPE Sprite + Xpos AS INTEGER + Ypos AS INTEGER + XDir AS INTEGER + YDir AS INTEGER + Shape AS INTEGER +END TYPE + + +CONST MaxShapes = 32 + + REM $INCLUDE: 'UTILS.BI' + REM $INCLUDE: 'MODEX.BI' + +DIM SHARED Img(32) AS ShapeType +COMMON SHARED Img() AS ShapeType + + + CALL INIT.RANDOM + + CALL LOAD.SHAPES + + CALL DEMO.RES(Mode320x200, 320, 200) + CALL DEMO.RES(Mode320x400, 320, 400) + + CALL DEMO.RES(Mode360x200, 360, 200) + CALL DEMO.RES(Mode360x400, 360, 400) + + CALL DEMO.RES(Mode320x240, 320, 240) + CALL DEMO.RES(Mode320x480, 320, 480) + + CALL DEMO.RES(Mode360x240, 360, 240) + CALL DEMO.RES(Mode360x480, 360, 480) + + CALL PAGE.DEMO + + SET.VIDEO.MODE 3 + DOS.PRINT "THIS MODE X DEMO IS FINISHED" + END + +SUB DEMO.RES (Mode, Xmax, Ymax) + + IF SET.MODEX%(Mode) = 0 THEN + ERROR.OUT "Unable to SET_MODEX" + STR$(Mode) + END IF + + XCenter = Xmax \ 2 + + X1 = 10 + Y1 = 10 + X2 = Xmax - 1 + Y2 = Ymax - 1 + + FOR Z = 0 TO 3 + Colr = 31 - Z * 2 + DRAW.LINE X1 + Z, Y1 + Z, X2 - Z, Y1 + Z, Colr + DRAW.LINE X1 + Z, Y1 + Z, X1 + Z, Y2 - Z, Colr + DRAW.LINE X1 + Z, Y2 - Z, X2 - Z, Y2 - Z, Colr + DRAW.LINE X2 - Z, Y1 + Z, X2 - Z, Y2 - Z, Colr + NEXT Z + + XChars = Xmax \ 10 + YChars = Ymax \ 10 + + FOR X = 0 TO XChars - 1 + TGPRINTC 48 + ((X + 1) MOD 10), X * 10 + 1, 1, 9 + ((X \ 8) MOD 7) + DRAW.LINE X * 10 + 9, 0, X * 10 + 9, 3, 15 + NEXT X + + FOR Y = 0 TO YChars - 1 + TGPRINTC 48 + ((Y + 1) MOD 10), 1, Y * 10 + 1, 9 + ((Y \ 10) MOD 7) + DRAW.LINE 0, Y * 10 + 9, 3, Y * 10 + 9, 15 + NEXT Y + + ' Draw Lines + + FOR X = 0 TO 63 + N = 15 + X * .75 + SET.DAC.REGISTER 64 + X, N, N, N + SET.DAC.REGISTER 128 + X, 0, N, N + + DRAW.LINE 103 - X, 60, 40 + X, 123, 64 + X + DRAW.LINE 40, 60 + X, 103, 123 - X, 128 + X + + NEXT X + TPRINT.TEXT "LINE TEST", 37, 130, c.BLUE + + Y = 60: Gap = 0 + FOR X = 0 TO 9 + FILL.BLOCK 120, Y, 120 + X, Y + Gap, 64 + X + FILL.BLOCK 140 - (15 - X), Y, 150 + X, Y + Gap, 230 + X + FILL.BLOCK 170 - (15 - X), Y, 170, Y + Gap, 128 + X + Y = Y + Gap + 2 + Gap = Gap + 1 + NEXT X + TPRINT.TEXT "FILL TEST", 110, 46, c.GREEN + + + FOR X = 190 TO 250 STEP 2 + FOR Y = 60 TO 122 STEP 2 + SET.POINT X, Y, X + Y + X + Y + NEXT Y + NEXT X + + TPRINT.TEXT "PIXEL TEST", 182, 130, c.RED + + FOR X = 190 TO 250 STEP 2 + FOR Y = 60 TO 122 STEP 2 + IF READ.POINT(X, Y) <> ((X + Y + X + Y) AND 255) THEN + ERROR.OUT "READ.PIXEL Failure" + END IF + NEXT Y + NEXT X + + + + Msg$ = " This is a MODE X demo " + PRINT.TEXT Msg$, XCenter - (LEN(Msg$) * 4), 20, c.bRED, c.BLUE + Msg$ = "Screen Resolution is by " + Xp = XCenter - (LEN(Msg$) * 4) + PRINT.TEXT Msg$, Xp, 30, c.bGREEN, c.BLACK + + PRINT.TEXT LTRIM$(STR$(Xmax)), Xp + 8 * 21, 30, c.bPURPLE, c.BLACK + PRINT.TEXT LTRIM$(STR$(Ymax)), Xp + 8 * 28, 30, c.bWHITE, c.BLACK + + FOR X = 0 TO 15 + SET.DAC.REGISTER 230 + X, 63 - X * 4, 0, 15 + X * 3 + DRAW.LINE 30 + X, Ymax - 6 - X, Xmax - 20 - X, Ymax - 6 - X, 230 + X + NEXT X + TPRINT.TEXT "Press to Continue", XCenter - (26 * 4), Ymax - 18, c.YELLOW + + X = GET.KEY% + IF X = KyESC THEN ERROR.OUT "ABORT" + +END SUB + +SUB ERROR.OUT (Message$) + + SET.VIDEO.MODE 3 + DOS.PRINT Message$ + END + +END SUB + +FUNCTION GET.KEY% + + DO + X = SCAN.KEYBOARD + LOOP UNTIL X + + GET.KEY% = X + +END FUNCTION + +SUB LOAD.SHAPES + +DIM Grid(1 TO 32, 1 TO 32) + + FOR Shape = 0 TO MaxShapes - 1 + + FOR Y = 1 TO 32 + FOR X = 1 TO 32 + Grid(X, Y) = 0 + NEXT X + NEXT Y + + Style = RANDOM.INT(6) + Colour = 1 + RANDOM.INT(15) + + SELECT CASE Style + + CASE 0: ' Solid Box + + DO + xWidth = 3 + RANDOM.INT(30) + yWidth = 3 + RANDOM.INT(30) + LOOP UNTIL ((xWidth * yWidth) <= 512) + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + Grid(X, Y) = Colour + NEXT X + NEXT Y + + CASE 1: ' Hollow Box + + DO + xWidth = 5 + RANDOM.INT(28) + yWidth = 5 + RANDOM.INT(28) + LOOP UNTIL ((xWidth * yWidth) <= 512) + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + Grid(X, Y) = Colour + NEXT X + NEXT Y + + HollowX = 1 + RANDOM.INT(xWidth \ 2 - 1) + HollowY = 1 + RANDOM.INT(yWidth \ 2 - 1) + + FOR Y = HollowY + 1 TO yWidth - HollowY + FOR X = HollowX + 1 TO xWidth - HollowX + Grid(X, Y) = nil + NEXT X + NEXT Y + + CASE 2: ' Solid Diamond + + xWidth = 3 + 2 * RANDOM.INT(10) + yWidth = xWidth + Centre = xWidth \ 2 + + FOR Y = 0 TO Centre + FOR X = 0 TO Y + Grid(Centre - X + 1, Y + 1) = Colour + Grid(Centre + X + 1, Y + 1) = Colour + Grid(Centre - X + 1, yWidth - Y) = Colour + Grid(Centre + X + 1, yWidth - Y) = Colour + NEXT X + NEXT Y + + + CASE 3: ' Hollow Diamond + + + xWidth = 3 + 2 * RANDOM.INT(10) + yWidth = xWidth + Centre = xWidth \ 2 + sWidth = RANDOM.INT(Centre) + + FOR Y = 0 TO Centre + FOR X = 0 TO Y + IF X + (Centre - Y) >= sWidth THEN + Grid(Centre - X + 1, Y + 1) = Colour + Grid(Centre + X + 1, Y + 1) = Colour + Grid(Centre - X + 1, yWidth - Y) = Colour + Grid(Centre + X + 1, yWidth - Y) = Colour + END IF + NEXT X + NEXT Y + + CASE 4: ' Ball + + xWidth = 7 + 2 * RANDOM.INT(8) + yWidth = xWidth + Centre = 1 + xWidth \ 2 + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + D = SQR(((Centre - X) * (Centre - X)) + ((Centre - Y) * (Centre - Y))) + IF D < Centre THEN Grid(X, Y) = 150 + Colour * 2 + D * 3 + NEXT X + NEXT Y + + CASE 5: ' Ball + + + xWidth = 7 + 2 * RANDOM.INT(8) + yWidth = xWidth + Centre = 1 + xWidth \ 2 + sWidth = RANDOM.INT(xWidth) + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + D = SQR(((Centre - X) * (Centre - X)) + ((Centre - Y) * (Centre - Y))) + IF D < Centre AND D >= sWidth THEN Grid(X, Y) = 150 + Colour * 2 + D * 3 + NEXT X + NEXT Y + + END SELECT + + Img(Shape).xWidth = xWidth + Img(Shape).yWidth = yWidth + + A$ = STRING$(xWidth * yWidth, nil) + + c = 1 + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + MID$(A$, c, 1) = CHR$(Grid(X, Y)) + c = c + 1 + NEXT X + NEXT Y + + Img(Shape).ImgData = A$ + + + NEXT Shape + +END SUB + +SUB PAGE.DEMO + +CONST MaxSprites = 64 + +DIM Obj(MaxSprites) AS Sprite +DIM LastX(MaxSprites, 1), LastY(MaxSprites, 1) +DIM LastObjects(1) + + ScreenX = 360: ScreenY = 240 + + IF SET.VGA.MODEX%(Mode320x200, ScreenX, ScreenY, 3) = 0 THEN + ERROR.OUT "Unable to SET_VGA_MODEX" + STR$(Mode) + END IF + + SET.ACTIVE.PAGE 0 + + CLEAR.VGA.SCREEN c.BLACK + + PRINT.TEXT "This is a Test of the Following Functions:", 10, 9, c.bWHITE, c.BLACK + + DRAW.LINE 10, 18, 350, 18, c.YELLOW + PRINT.TEXT "SET_ACTIVE_PAGE", 10, 20, c.bBLUE, c.BLACK + PRINT.TEXT "SET_DISPLAY_PAGE", 10, 30, c.GREEN, c.BLACK + PRINT.TEXT "SET_DAC_REGISTER", 10, 40, c.RED, c.BLACK + PRINT.TEXT "CLEAR_VGA_SCREEN", 10, 50, c.CYAN, c.BLACK + + PRINT.TEXT "TDRAW_BITMAP", 10, 60, c.PURPLE, c.BLACK + PRINT.TEXT "COPY_PAGE", 10, 70, c.GREEN, c.BLACK + PRINT.TEXT "COPY_BITMAP", 10, 80, c.CYAN, c.BLACK + + PRINT.TEXT "GPRINTC", 10, 90, c.BLUE, c.BLACK + PRINT.TEXT "TGPRINTC", 10, 100, c.GREEN, c.BLACK + PRINT.TEXT "SET_WINDOW", 10, 110, c.RED, c.BLACK + + PRINT.TEXT "VIRTUAL SCREEN SIZES", 190, 20, c.bBLUE, c.BLACK + PRINT.TEXT " SMOOTH SCROLLING", 190, 30, c.GREEN, c.BLACK + PRINT.TEXT " SPRITE ANIMATION", 190, 40, c.CYAN, c.BLACK + PRINT.TEXT " PAGE FLIPPING", 190, 50, c.RED, c.BLACK + PRINT.TEXT " COLOR CYCLING", 190, 60, c.PURPLE, c.BLACK + + + FOR X = 0 TO 60 + SET.DAC.REGISTER 50 + X, 3 + X, 0, 60 - X + SET.DAC.REGISTER 150 + X, 3 + X, 0, 60 - X + NEXT X + + c = 0: DC = 1 + FOR X = 0 TO ScreenX \ 2 + DRAW.LINE ScreenX \ 2 - 1, ScreenY \ 4, X, ScreenY - 1, c + 50 + DRAW.LINE ScreenX \ 2, ScreenY \ 4, ScreenX - X - 1, ScreenY - 1, c + 50 + c = c + DC + IF c = 0 OR c = 60 THEN DC = -DC + NEXT X + + TPRINT.TEXT "Press to Continue", 72, 190, c.bWHITE + TPRINT.TEXT "< > = Faster < > = Slower", 72, 204, c.bGREEN + TPRINT.TEXT "< > = Fewer Shapes < > = More Shapes", 32, 218, c.bCYAN + + TGPRINTC 43, 80, 204, c.YELLOW + TGPRINTC 45, 200, 204, c.YELLOW + + TGPRINTC 25, 40, 218, c.YELLOW + TGPRINTC 24, 200, 218, c.YELLOW + + COPY.PAGE 0, 1 + COPY.PAGE 0, 2 + + FOR X = 1 TO MaxSprites + DO + Obj(X).XDir = RANDOM.INT(7) - 3 + Obj(X).YDir = RANDOM.INT(7) - 3 + LOOP WHILE (Obj(X).XDir = 0 AND Obj(X).YDir = 0) + + Obj(X).Shape = X MOD MaxShapes + + SpriteX = Img(Obj(X).Shape).xWidth + SpriteY = Img(Obj(X).Shape).yWidth + + Obj(X).Xpos = 1 + RANDOM.INT(ScreenX - SpriteX - 2) + Obj(X).Ypos = 1 + RANDOM.INT(ScreenY - SpriteY - 2) + + LastX(X, 0) = Obj(X).Xpos + LastX(X, 1) = Obj(X).Xpos + LastY(X, 0) = Obj(X).Ypos + LastY(X, 1) = Obj(X).Ypos + NEXT X + + CurrentPage = 0 + + 'View Shift... + + ViewX = 0 + ViewY = 0 + ViewMax = 3 + ViewCnt = 0 + ViewXD = 1 + ViewYD = 1 + + SetColor = 3: SDir = 1 + PrevColor = 0: PDir = 1 + + VisObjects = MaxSprites \ 2 + LastObjects(0) = 0 + LastObjects(1) = 0 + +DRAW.LOOP: + + + SET.ACTIVE.PAGE CurrentPage + + ' Erase Old Images + + FOR X = 1 TO LastObjects(CurrentPage) + + X1 = LastX(X, CurrentPage) AND &HFFFC + Y1 = LastY(X, CurrentPage) + X2 = ((LastX(X, CurrentPage) + Img(Obj(X).Shape).xWidth)) OR 3 + Y2 = Y1 + Img(Obj(X).Shape).yWidth - 1 + + COPY.BITMAP 2, X1, Y1, X2, Y2, CurrentPage, X1, Y1 + + NEXT X + + ' Draw new images + + FOR X = 1 TO VisObjects + + SpriteX = Img(Obj(X).Shape).xWidth + SpriteY = Img(Obj(X).Shape).yWidth + + ' Move Sprite + +REDOX: + NewX = Obj(X).Xpos + Obj(X).XDir + IF NewX < 0 OR NewX + SpriteX > ScreenX THEN + Obj(X).XDir = -Obj(X).XDir + IF RANDOM.INT(20) = 1 THEN + DO + Obj(X).XDir = RANDOM.INT(7) - 3 + Obj(X).YDir = RANDOM.INT(7) - 3 + LOOP WHILE (Obj(X).XDir = 0 AND Obj(X).YDir = 0) + GOTO REDOX + END IF + END IF + Obj(X).Xpos = Obj(X).Xpos + Obj(X).XDir + +REDOY: + NewY = Obj(X).Ypos + Obj(X).YDir + IF NewY < 0 OR NewY + SpriteY > ScreenY THEN + Obj(X).YDir = -Obj(X).YDir + IF RANDOM.INT(20) = 1 THEN + DO + Obj(X).XDir = RANDOM.INT(7) - 3 + Obj(X).YDir = RANDOM.INT(7) - 3 + LOOP WHILE (Obj(X).XDir = 0 AND Obj(X).YDir = 0) + GOTO REDOY + END IF + END IF + Obj(X).Ypos = Obj(X).Ypos + Obj(X).YDir + + 'Draw Sprite + + TDRAW.BITMAP Img(Obj(X).Shape), Obj(X).Xpos, Obj(X).Ypos, SpriteX, SpriteY + + LastX(X, CurrentPage) = Obj(X).Xpos + LastY(X, CurrentPage) = Obj(X).Ypos + + NEXT X + + LastObjects(CurrentPage) = VisObjects + + ' Pan Screen Back & Forth + + ViewCnt = ViewCnt + 1 + IF ViewCnt >= ViewMax THEN + ViewX = ViewX + ViewXD + IF ViewX = 0 OR ViewX = 39 THEN ViewXD = -ViewXD + IF ViewXD < 0 THEN + ViewY = ViewY + ViewYD + IF ViewY = 0 OR ViewY = 39 THEN ViewYD = -ViewYD + END IF + + SET.WINDOW CurrentPage, ViewX, ViewY + + ViewCnt = 0 + ELSE + SET.DISPLAY.PAGE CurrentPage + END IF + + ' Cycle Colors + + SET.DAC.REGISTER 50 + PrevColor, 3 + PrevColor, 0, 60 - PrevColor + SET.DAC.REGISTER 50 + SetColor, SetColor, 10, 63 - SetColor + + SET.DAC.REGISTER 150 + PrevColor, 3 + PrevColor, 0, 60 - PrevColor + SET.DAC.REGISTER 150 + SetColor, 63, 63, SetColor + + SetColor = SetColor + SDir + IF SetColor = 60 OR SetColor = 0 THEN SDir = -SDir + + PrevColor = PrevColor + PDir + IF PrevColor = 60 OR PrevColor = 0 THEN PDir = -PDir + + CurrentPage = 1 - CurrentPage + + Code = SCAN.KEYBOARD + + IF Code = False THEN GOTO DRAW.LOOP + + IF Code = KyPlus THEN + IF ViewMax < 12 THEN ViewMax = ViewMax + 1 + GOTO DRAW.LOOP + END IF + + IF Code = KyMinus THEN + IF ViewMax > 1 THEN ViewMax = ViewMax - 1 + IF ViewCnt >= ViewMax THEN ViewCnt = 0 + GOTO DRAW.LOOP + END IF + + IF Code = KyUp THEN + IF VisObjects < MaxSprites THEN VisObjects = VisObjects + 1 + GOTO DRAW.LOOP + END IF + + IF Code = KyDown THEN + IF VisObjects > 1 THEN VisObjects = VisObjects - 1 + GOTO DRAW.LOOP + END IF + + +END SUB + +SUB PRINT.TEXT (Text$, Xpos, Ypos, ColorF, ColorB) + + IF LEN(Text$) = 0 THEN EXIT SUB + + PRINT.STR SSEG(Text$), SADD(Text$), LEN(Text$), Xpos, Ypos, ColorF, ColorB + + +END SUB + +SUB TPRINT.TEXT (Text$, Xpos, Ypos, ColorF) + + IF LEN(Text$) = 0 THEN EXIT SUB + + TPRINT.STR SSEG(Text$), SADD(Text$), LEN(Text$), Xpos, Ypos, ColorF + +END SUB + diff --git a/16/modex105/DEMOS/BASIC7/UASM-BC7.BAT b/16/modex105/DEMOS/BASIC7/UASM-BC7.BAT new file mode 100644 index 00000000..5ad67fb5 --- /dev/null +++ b/16/modex105/DEMOS/BASIC7/UASM-BC7.BAT @@ -0,0 +1 @@ +MASM /DFARSTRINGS utils, utils, utils, nul; \ No newline at end of file diff --git a/16/modex105/DEMOS/BASIC7/UTILS.ASM b/16/modex105/DEMOS/BASIC7/UTILS.ASM new file mode 100644 index 00000000..811b8f8e --- /dev/null +++ b/16/modex105/DEMOS/BASIC7/UTILS.ASM @@ -0,0 +1,406 @@ +;======================================================= +;=== UTILS.ASM - Asm Utilities for QuickBasic/BC7 === +;======================================================= + + PAGE 255, 132 + + .MODEL Medium + .286 + + ; ==== MACROS ==== + + ; macros to PUSH and POP multiple registers + +PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + push R1 ; Save R1 + PUSHx R2, R3, R4, R5, R6, R7, R8 + ENDIF +ENDM + +POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + pop R1 ; Restore R1 + POPx R2, R3, R4, R5, R6, R7, R8 + ENDIF +ENDM + + ; Macro to Clear a Register to 0 + +CLR MACRO Register + xor Register, Register ; Set Register = 0 +ENDM + + ; Macros to Decrement Counter & Jump on Condition + +LOOPx MACRO Register, Destination + dec Register ; Counter-- + jnz Destination ; Jump if not 0 +ENDM + +LOOPjz MACRO Register, Destination + dec Register ; Counter-- + jz Destination ; Jump if 0 +ENDM + + + ; ==== General Constants ==== + + False EQU 0 + True EQU -1 + nil EQU 0 + + b EQU BYTE PTR + w EQU WORD PTR + d EQU DWORD PTR + o EQU OFFSET + f EQU FAR PTR + s EQU SHORT + ?x4 EQU + ?x3 EQU + + +IFDEF FARSTRINGS + + EXTRN stringaddress:far + EXTRN stringlength:far + +ENDIF + + + .Data + + EVEN + +RND_Seed DW 7397, 29447, 802 +RND_Mult DW 179, 183, 182 +RND_ModV DW 32771, 32779, 32783 + +CR_LF DB 13, 10 ; the CRLF data + + .Code + +;================= +;DOS_PRINT (Text$) +;================= +; +; Prints Text Directly to DOS console w/ CR/LF +; + + PUBLIC DOS_PRINT + +DP_Stack STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + DP_Text DW ? ; Address of Text$ Descriptor +DP_Stack ENDS + + +DOS_PRINT PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + mov SI, [BP].DP_Text ; Get Addr of Text$ descriptor + +IFDEF FARSTRINGS + push SI ; Push Addr of BC7 Decriptor Ptr + call stringaddress ; Get Address + Len of string!!! + ; DX:AX = Addr CX = Len + mov DS, DX ; DS = DX = Segment of string + mov DX, AX ; DX = AX = Offset of String +ELSE + mov CX, [SI] ; put its length into CX + mov DX, [SI+02] ; now DS:DX points to the String +ENDIF + + jcxz @No_Print ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@No_Print: + mov AX, SEG DGROUP ; Restore DGroup + mov DS, AX + + mov DX, o CR_LF ; Get Addr of CR/LF pair + mov CX, 2 ; 2 Characters to Write + mov BX, 1 ; 1= DOS Handle for Display + + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +DOS_PRINT ENDP + + +;================== +;DOS_PRINTS (Text$) +;================== +; +; Print Text$ Directly to DOS console +; without a trailing CR/LF +; + + PUBLIC DOS_PRINTS + +DOS_PRINTS PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + mov SI, [BP].DP_Text ; Get Addr of Text$ descriptor + +IFDEF FARSTRINGS + push SI ; Push Addr of BC7 Decriptor Ptr + call stringaddress ; Get Address + Len of string!!! + ; DX:AX = Addr CX = Len + mov DS, DX ; DS = DX = Segment of string + mov DX, AX ; DX = AX = Offset of String +ELSE + mov CX, [SI] ; put its length into CX + mov DX, [SI+02] ; now DS:DX points to the String +ENDIF + + jcxz @DPS_Exit ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@DPS_Exit: + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +DOS_PRINTS ENDP + + +;====================== +;SET_VIDEO_MODE (Mode%) +;====================== +; +; Sets the Video Mode through the BIOS +; + + PUBLIC SET_VIDEO_MODE + +SVM_Stack STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + SVM_Mode DB ?,? ; Desired Video Mode +SVM_Stack ENDS + + +SET_VIDEO_MODE PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + CLR AH ; Function 0 + mov AL, [BP].SVM_Mode ; Get Mode # + + int 10H ; Change Video Modes + +@SVM_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +SET_VIDEO_MODE ENDP + + +;============== +;SCAN_KEYBOARD% +;============== +; +; Function to scan keyboard for a pressed key +; + + PUBLIC SCAN_KEYBOARD + +SCAN_KEYBOARD PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + + mov AH, 01H ; Function #1 + int 16H ; Call Keyboard Driver + jz @SK_NO_KEY ; Exit if Zero flag set + + mov AH, 00H ; Remove Key from Buffer + int 16H ; Get Keycode in AX + + or AL, AL ; Low Byte Set (Ascii?) + jz @SK_Exit ; if not, it's a F-Key + + CLR AH ; Clear ScanCode if Ascii + jmp s @SK_Exit ; Return Key in AX + +@SK_NO_KEY: + CLR AX ; Return Nil (no Keypress) + +@SK_Exit: + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret ; Exit & Clean Up Stack + +SCAN_KEYBOARD ENDP + + +;==================== +;RANDOM_INT (MaxInt%) +;==================== +; +; Returns a pseudo-random number in the range of (0.. MaxInt-1) +; + + + PUBLIC RANDOM_INT + +RI_Stack STRUC + DW ? ; BP + DD ? ; Caller + RI_MaxVal DW ? ; Maximum Value to Return + 1 +RI_Stack ENDS + + +RANDOM_INT PROC FAR + + push BP ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + CLR BX ; BX is the data index + CLR CX ; CX is the accumulator + +REPT 3 + mov AX, RND_Seed[BX] ; load the initial seed + mul RND_Mult[BX] ; multiply it + div RND_ModV[BX] ; and obtain the Mod value + mov RND_Seed[BX], DX ; save that for the next time + + add CX, DX ; add it into the accumulator + inc BX + inc BX ; point to the next set of values +ENDM + + mov AX, CX ; AX = Random # + CLR DX ; DX = 0 + div [BP].RI_MaxVal ; DX = DX:AX / MAxVal Remainder + + mov AX, DX + + pop BP ; Restore BP + ret 2 ; back to BASIC with AX holding the result + +RANDOM_INT ENDP + + +;=========== +;INIT_RANDOM +;=========== +; +; Scrambles the psuedo-random number sequence +; (XOR's the seed value with the timer) +; + + PUBLIC INIT_RANDOM + +INIT_RANDOM PROC FAR + + clr AX ; Segment = 0000 + mov ES, AX + mov AX, ES:[046Ch] ; Get Timer Lo Word + + xor RND_Seed, AX ; Scramble 1st Seed + + ret ; Exit & Clean Up Stack + +INIT_RANDOM ENDP + + +;==================== +;INT_SQR (X%, Round%) +;==================== +; +; Returns the Integer Square Root of (X) +; Round allows the return value to be rounded to the +; nearest integer value by passing 0x80. Passing 0 +; return the Integer Portion only. The rounding amound is +; a number from 0 to 1 multiplied by 256, thus +; 0.5 * 0x100 = 0x80! +; + +ISQ_Stack STRUC + DW ?,? ; BP, DI + DD ? ; Caller + ISQ_Round DW ? ; Amount to Round Result * 256 + ISQ_X DW ? ; "X" +ISQ_Stack ENDS + + PUBLIC INT_SQR + +INT_SQR PROC FAR + + PUSHx BP, DI ; Save BP + mov BP, SP ; Set up Stack Frame + + xor AX, AX ; {xor eax,eax} + xor DX, DX ; {xor edx,edx} + mov DI, [BP].ISQ_X ; {mov edi,x} + + mov CX, 16 ; {mov cx, 32} + +@ISQ_L: + + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl AX, 1 ; {shl eax,1} + mov BX, AX ; {mov ebx,eax} + shl BX, 1 ; {shl ebx,1} + inc BX ; {inc ebx} + cmp DX, BX ; {cmp edx,ebx} + jl @ISQ_S + + sub DX, BX ; {sub edx,ebx} + inc AX ; {inc eax} + +@ISQ_S: + loop @ISQ_L + + add ax, [BP].ISQ_Round ; {add eax,$00008000} + ; {*round* result in hi word: ie. +0.5} + shr ax, 8 ; {shr eax,16} {to ax (result)} + + POPx DI, BP ; Restore Registers + ret 4 ; Exit + +INT_SQR ENDP + + +;============ +;TIMER_COUNT& +;============ +; +; Returns the current timer value as an integer/long integer +; + + + PUBLIC TIMER_COUNT + +TIMER_COUNT PROC FAR + + clr AX ; Segment = 0000 + mov ES, AX ; use ES to get at data + mov AX, ES:[046Ch] ; Get Timer Lo Word + mov DX, ES:[046Eh] ; Get Timer Hi Word + ret ; Exit & Return value in DX:AX + +TIMER_COUNT ENDP + + + END diff --git a/16/modex105/DEMOS/BASIC7/UTILS.BI b/16/modex105/DEMOS/BASIC7/UTILS.BI new file mode 100644 index 00000000..aeafeef4 --- /dev/null +++ b/16/modex105/DEMOS/BASIC7/UTILS.BI @@ -0,0 +1,51 @@ + + ' Misc Constants + +CONST True = -1, False = 0, nil = 0 + + ' Keyboard Codes: Extended + +CONST KyF1 = &H3B00, KyF2 = &H3C00, KyF3 = &H3D00, KyF4 = &H3E00, KyF5 = &H3F00 +CONST KyF6 = &H4000, KyF7 = &H4100, KyF8 = &H4200, KyF9 = &H4300, KyF10 = &H4400 + +CONST KyUp = &H4800, KyLeft = &H4B00, KyRight = &H4D00, KyDown = &H5000 +CONST KySLeft = &HCB00, KySRight = &HCD00, KySUp = &HC800, KySDown = &HD000 + +CONST KyHome = &H4700, KyPgUp = &H4900, KyEnd = &H4F00, KyPgDn = &H5100 +CONST KySHome = &HC700, KySPgUp = &HC900, KySEnd = &HCF00, KySPgDn = &HD100 + +CONST KyIns = &H5200, KyDel = &H5300, KyRvsTab = &H8F00 +CONST KySIns = &HC200, KySDel = &HC300 + +CONST KyAltA = &H1E00, KyAltB = &H3000, KyAltC = &H2E00, KyAltD = &H2000 +CONST KyAltE = &H1200, KyAltF = &H2100, KyAltG = &H2200, KyAltH = &H2300 +CONST KyAltI = &H1700, KyAltJ = &H2400, KyAltK = &H2500, KyAltL = &H2600 +CONST KyAltM = &H3200, KyAltN = &H3100, KyAltO = &H1800, KyAltP = &H1900 +CONST KyAltQ = &H1000, KyAltR = &H1300, KyAltS = &H1F00, KyAltT = &H1400 +CONST KyAltU = &H1600, KyAltV = &H2F00, KyAltW = &H1100, KyAltX = &H2D00 +CONST KyAltY = &H1500, KyAltZ = &H2C00 + + ' Keyboard Codes: Ascii + +CONST KyBS = 8, KyTab = 9, KyCR = 13, KyESC = &H1B, KyClr = &H7F +CONST KyPlus = 45, KyMinus = 43 + + ' Color Constants + +CONST c.BLACK = 0, c.BLUE = 1, c.GREEN = 2, c.CYAN = 3 +CONST c.RED = 4, c.PURPLE = 5, c.BROWN = 6, c.WHITE = 7 +CONST c.GREY = 8, c.bBLUE = 9, c.bGREEN = 10, c.bCYAN = 11 +CONST c.bRED = 12, c.bPURPLE = 13, c.YELLOW = 14, c.bWHITE = 15 +CONST c.BRIGHT = 8 + + ' From UTILS.ASM + +DECLARE SUB DOS.PRINT ALIAS "DOS_PRINT" (Text$) +DECLARE SUB DOS.PRINTS ALIAS "DOS_PRINTS" (Text$) +DECLARE SUB SET.VIDEO.MODE ALIAS "SET_VIDEO_MODE" (BYVAL Mode%) +DECLARE FUNCTION SCAN.KEYBOARD% ALIAS "SCAN_KEYBOARD" +DECLARE FUNCTION RANDOM.INT ALIAS "RANDOM_INT" (BYVAL MaxInt%) +DECLARE SUB INIT.RANDOM ALIAS "INIT_RANDOM" +DECLARE FUNCTION TIMER.COUNT& ALIAS "TIMER_COUNT" +DECLARE FUNCTION INT.SQR ALIAS "INT_SQR" (BYVAL X%, BYVAL Round%) + diff --git a/16/modex105/DEMOS/C/C_UTILS.ASM b/16/modex105/DEMOS/C/C_UTILS.ASM new file mode 100644 index 00000000..8302561a --- /dev/null +++ b/16/modex105/DEMOS/C/C_UTILS.ASM @@ -0,0 +1,405 @@ +;======================================================= +;=== C_UTILS.ASM - Asm Utilities for C/C++ === +;======================================================= + + PAGE 255, 132 + + .MODEL Medium + .286 + + ; ==== MACROS ==== + + ; macros to PUSH and POP multiple registers + +PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + push R1 ; Save R1 + PUSHx R2, R3, R4, R5, R6, R7, R8 + ENDIF +ENDM + +POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + pop R1 ; Restore R1 + POPx R2, R3, R4, R5, R6, R7, R8 + ENDIF +ENDM + + ; Macro to Clear a Register to 0 + +CLR MACRO Register + xor Register, Register ; Set Register = 0 +ENDM + + ; Macros to Decrement Counter & Jump on Condition + +LOOPx MACRO Register, Destination + dec Register ; Counter-- + jnz Destination ; Jump if not 0 +ENDM + +LOOPjz MACRO Register, Destination + dec Register ; Counter-- + jz Destination ; Jump if 0 +ENDM + + + ; ==== General Constants ==== + + False EQU 0 + True EQU -1 + nil EQU 0 + + b EQU BYTE PTR + w EQU WORD PTR + d EQU DWORD PTR + o EQU OFFSET + f EQU FAR PTR + s EQU SHORT + ?x4 EQU + ?x3 EQU + + + .Data + + EVEN + +RND_Seed DW 7397, 29447, 802 +RND_Mult DW 179, 183, 182 +RND_ModV DW 32771, 32779, 32783 + +CR_LF DB 13, 10 ; the CRLF data + + .Code + +;=========================================== +;void far pascal dos_print (far char *Text) +;=========================================== +; +; - Print Text Directly to DOS console w/ CR/LF +; + + PUBLIC DOS_PRINT + +DP_Stack STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + DP_Text DD ? ; Far Address of Text to print +DP_Stack ENDS + + +DOS_PRINT PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + lds DX, [BP].DP_Text ; Get Addr of Text$ descriptor + + ; Compute Length of string + + CLR CX ; Length = 0 + mov SI, DX ; DS:SI = String data + +@@DP_Scan_it: + + cmp b [SI], 0 ; Null Byte found? + je @@DP_Got_Len ; exit loop if so + + inc CX ; Len++ + inc SI ; Point to next char + jmp s @@DP_Scan_it ; check again... + +@@DP_Got_len: + + jcxz @No_Print ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@No_Print: + mov AX, SEG DGROUP ; Restore DGroup + mov DS, AX + + mov DX, o CR_LF ; Get Addr of CR/LF pair + mov CX, 2 ; 2 Characters to Write + mov BX, 1 ; 1= DOS Handle for Display + + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 4 ; Exit & Clean Up Stack + +DOS_PRINT ENDP + + +;=========================================== +;void far pascal dos_prints (char far *Text) +;=========================================== +; +; Print Text Directly to DOS console +; without a trailing CR/LF +; + + PUBLIC DOS_PRINTS + +DOS_PRINTS PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + lds DX, [BP].DP_Text ; Get Addr of Text$ descriptor + + ; Compute Length of string + + CLR CX ; Length = 0 + mov SI, DX ; DS:SI = String data + +@@DPS_Scan_it: + + cmp b [SI], 0 ; Null Byte found? + je @@DPS_Got_Len ; exit loop if so + + inc CX ; Len++ + inc SI ; Point to next char + jmp s @@DPS_Scan_it ; check again... + +@@DPS_Got_len: + + jcxz @DPS_Exit ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@DPS_Exit: + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +DOS_PRINTS ENDP + + +;========================================= +;void far pascal set_video_mode (int Mode) +;========================================= +; +; Sets the Video Mode through the BIOS +; + + PUBLIC SET_VIDEO_MODE + +SVM_Stack STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + SVM_Mode DB ?,? ; Desired Video Mode +SVM_Stack ENDS + + +SET_VIDEO_MODE PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + CLR AH ; Function 0 + mov AL, [BP].SVM_Mode ; Get Mode # + + int 10H ; Change Video Modes + +@SVM_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +SET_VIDEO_MODE ENDP + + +;=================================== +;int far pascal scan_keyboard (void) +;=================================== +; +; Function to scan keyboard for a pressed key +; + + PUBLIC SCAN_KEYBOARD + +SCAN_KEYBOARD PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + + mov AH, 01H ; Function #1 + INT 16H ; Call Keyboard Driver + JZ @SK_NO_KEY ; Exit if Zero flag set + + mov AH, 00H ; Remove Key from Buffer + INT 16H ; Get Keycode in AX + + OR AL, AL ; Low Byte Set (Ascii?) + JZ @SK_Exit ; if not, it's a F-Key + + CLR AH ; Clear ScanCode if Ascii + JMP s @SK_Exit ; Return Key in AX + +@SK_NO_KEY: + CLR AX ; Return Nil (no Keypress) + +@SK_Exit: + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret ; Exit & Clean Up Stack + +SCAN_KEYBOARD ENDP + + +;======================================== +;int far pascal random_int (int MaxValue) +;======================================== +; +; Returns a pseudo-random number in the range of (0.. MaxInt-1) +; + + + PUBLIC RANDOM_INT + +RI_Stack STRUC + DW ? ; BP + DD ? ; Caller + RI_MaxVal DW ? ; Maximum Value to Return + 1 +RI_Stack ENDS + + +RANDOM_INT PROC FAR + + push BP ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + CLR BX ; BX is the data index + CLR CX ; CX is the accumulator + +REPT 3 + mov AX, RND_Seed[BX] ; load the initial seed + mul RND_Mult[BX] ; multiply it + div RND_ModV[BX] ; and obtain the Mod value + mov RND_Seed[BX], DX ; save that for the next time + + add CX, DX ; add it into the accumulator + inc BX + inc BX ; point to the next set of values +ENDM + + mov AX, CX ; AX = Random # + CLR DX ; DX = 0 + div [BP].RI_MaxVal ; DX = DX:AX / MAxVal Remainder + + mov AX, DX + + pop BP ; Restore BP + ret 2 ; back to BASIC with AX holding the result + +RANDOM_INT ENDP + + +;================================== +;void far pascal init_random (void) +;================================== +; +; Scrambles the psuedo-random number sequence +; (XOR's the seed value with the timer) +; + + PUBLIC INIT_RANDOM + +INIT_RANDOM PROC FAR + + CLR AX ; Segment = 0000 + mov ES, AX + mov AX, ES:[046Ch] ; Get Timer Lo Word + + xor RND_Seed, AX ; Scramble 1st Seed + + ret ; Exit & Clean Up Stack + +INIT_RANDOM ENDP + +;========================================= +;int far pascal int_sqr (int X, int Round) +;========================================= +; +; Returns the Integer Square Root of (X) +; Round allows the return value to be rounded to the +; nearest integer value by passing 0x80. Passing 0 +; return the Integer Portion only. The rounding amound is +; a number from 0 to 1 multiplied by 256, thus +; 0.5 * 0x100 = 0x80! +; + +ISQ_Stack STRUC + DW ?,? ; BP, DI + DD ? ; Caller + ISQ_Round DW ? ; Amount to Round Result * 256 + ISQ_X DW ? ; "X" +ISQ_Stack ENDS + + PUBLIC INT_SQR + +INT_SQR PROC FAR + + PUSHx BP, DI ; Save BP + mov BP, SP ; Set up Stack Frame + + xor AX, AX ; {xor eax,eax} + xor DX, DX ; {xor edx,edx} + mov DI, [BP].ISQ_X ; {mov edi,x} + + mov CX, 16 ; {mov cx, 32} + +@ISQ_L: + + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl AX, 1 ; {shl eax,1} + mov BX, AX ; {mov ebx,eax} + shl BX, 1 ; {shl ebx,1} + inc BX ; {inc ebx} + cmp DX, BX ; {cmp edx,ebx} + jl @ISQ_S + + sub DX, BX ; {sub edx,ebx} + inc AX ; {inc eax} + +@ISQ_S: + loop @ISQ_L + + add ax, [BP].ISQ_Round ; {add eax,$00008000} + ; {*round* result in hi word: ie. +0.5} + shr ax, 8 ; {shr eax,16} {to ax (result)} + + POPx DI, BP ; Restore Registers + ret 4 ; Exit + +INT_SQR ENDP + +;================================= +;int far pascal timer_count (void) +;================================= +; +; Returns the current timer value as an integer/long integer +; + + PUBLIC TIMER_COUNT + +TIMER_COUNT PROC FAR + + CLR AX ; Segment = 0000 + mov ES, AX + mov AX, ES:[046Ch] ; Get Timer Lo Word + mov DX, ES:[046Eh] ; Get Timer Hi Word + ret ; Exit & Clean Up Stack + +TIMER_COUNT ENDP + + + END diff --git a/16/modex105/DEMOS/C/C_UTILS.H b/16/modex105/DEMOS/C/C_UTILS.H new file mode 100644 index 00000000..ed0e188f --- /dev/null +++ b/16/modex105/DEMOS/C/C_UTILS.H @@ -0,0 +1,117 @@ + +#ifndef __C_UTILS_H +#define __C_UTILS_H + + + /* Misc Constants */ + +#define True -1 +#define False 0 +#define nil 0 + + /* Color Constants */ + +#define c_BLACK 0 +#define c_BLUE 1 +#define c_GREEN 2 +#define c_CYAN 3 +#define c_RED 4 +#define c_PURPLE 5 +#define c_BROWN 6 +#define c_WHITE 7 +#define c_GREY 8 +#define c_bBLUE 9 +#define c_bGREEN 10 +#define c_bCYAN 11 +#define c_bRED 12 +#define c_bPURPLE 13 +#define c_YELLOW 14 +#define c_bWHITE 15 +#define c_BRIGHT 16 + + +#define Ky_F1 0x3B00 +#define Ky_F2 0x3C00 +#define Ky_F3 0x3D00 +#define Ky_F4 0x3E00 +#define Ky_F5 0x3F00 +#define Ky_F6 0x4000 +#define Ky_F7 0x4100 +#define Ky_F8 0x4200 +#define Ky_F9 0x4300 +#define Ky_F10 0x4400 + +#define Ky_Up 0x4800 +#define Ky_Left 0x4B00 +#define Ky_Right 0x4D00 +#define Ky_Down 0x5000 +#define Ky_SUp 0xC800 +#define Ky_SLeft 0xCB00 +#define Ky_SRight 0xCD00 +#define Ky_SDown 0xD000 + +#define Ky_Home 0x4700 +#define Ky_End 0x4F00 +#define Ky_PgUp 0x4900 +#define Ky_PgDn 0x5100 +#define Ky_SHome 0xC700 +#define Ky_SEnd 0xCF00 +#define Ky_SPgUp 0xC900 +#define Ky_SPgDn 0xD100 + +#define Ky_Ins 0x5200 +#define Ky_Del 0x5300 +#define Ky_SIns 0xC200 +#define Ky_SDel 0xC300 + +#define Ky_Tab 0x0009 +#define Ky_RvsTab 0x8F00 +#define Ky_STab 0x8F00 + +#define Ky_BS 0x0008 +#define Ky_CR 0x000D +#define Ky_ESC 0x001B +#define Ky_Clr 0x007F + +#define Ky_Plus 0x002D +#define Ky_Minus 0x002B + +#define Ky_AltA 0x1E00 +#define Ky_AltB 0x3000 +#define Ky_AltC 0x2E00 +#define Ky_AltD 0x2000 +#define Ky_AltE 0x1200 +#define Ky_AltF 0x2100 +#define Ky_AltG 0x2200 +#define Ky_AltH 0x2300 +#define Ky_AltI 0x1700 +#define Ky_AltJ 0x2400 +#define Ky_AltK 0x2500 +#define Ky_AltL 0x2600 +#define Ky_AltM 0x3200 +#define Ky_AltN 0x3100 +#define Ky_AltO 0x1800 +#define Ky_AltP 0x1900 +#define Ky_AltQ 0x1000 +#define Ky_AltR 0x1300 +#define Ky_AltS 0x1F00 +#define Ky_AltT 0x1400 +#define Ky_AltU 0x1600 +#define Ky_AltV 0x2F00 +#define Ky_AltW 0x1100 +#define Ky_AltX 0x2D00 +#define Ky_AltY 0x1500 +#define Ky_AltZ 0x2C00 + + /* .ASM Functions From C_UTILS.ASM */ + +void far pascal dos_print (char far *Text); +void far pascal dos_prints (char far *Text); +void far pascal set_video_mode (int Mode); +int far pascal scan_keyboard (void); +int far pascal random_int (int MaxValue); +void far pascal init_random (void); +int far pascal int_sqr (int X, int Round); +int far pascal timer_count (void); + +#endif \ No newline at end of file diff --git a/16/modex105/DEMOS/C/MODEX.H b/16/modex105/DEMOS/C/MODEX.H new file mode 100644 index 00000000..7de25a63 --- /dev/null +++ b/16/modex105/DEMOS/C/MODEX.H @@ -0,0 +1,76 @@ + +#ifndef __MODEX_H +#define __MODEX_H + + /* ===== SCREEN RESOLUTIONS ===== */ + +#define Mode_320x200 0 +#define Mode_320x400 1 +#define Mode_360x200 2 +#define Mode_360x400 3 +#define Mode_320x240 4 +#define Mode_320x480 5 +#define Mode_360x240 6 +#define Mode_360x480 7 + + /* ===== MODE X SETUP ROUTINES ===== */ + +int far pascal set_vga_modex (int Mode, int MaxXpos, int MaxYpos, int Pages); +int far pascal set_modex (int Mode); + + /* ===== BASIC GRAPHICS PRIMITIVES ===== */ + +void far pascal clear_vga_screen (int Color); +void far pascal set_point (int Xpos, int Ypos, int Color); +int far pascal read_point (int Xpos, int Ypos); +void far pascal fill_block (int Xpos1, int Ypos1, int Xpos2, int Ypos2, + int Color); +void far pascal draw_line (int Xpos1, int Ypos1, int Xpos2, int Ypos2, + int Color); + + /* ===== DAC COLOR REGISTER ROUTINES ===== */ + +void far pascal set_dac_register (int RegNo, int Red, int Green, int Blue); +void far pascal get_dac_register (int RegNo, int* Red, int* Green, int* Blue); +void far pascal load_dac_registers (char far *PalData, int StartReg, + int EndReg, int VSync); +void far pascal readd_dac_registers (char far *PalData, int StartReg, + int EndReg); + + /* ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== */ + +void far pascal set_active_page (int PageNo); +int far pascal get_active_page (void); +void far pascal set_display_page (int PageNo); +int far pascal get_display_page (void); +void far pascal set_window (int DisplayPage, int XOffset, int YOffset); +int far pascal get_x_offset (void); +int far pascal get_y_offset (void); +void far pascal sync_display (void); + + /* ===== TEXT DISPLAY ROUTINES ===== */ + +void far pascal gprintc (int CharNum, int Xpos, int Ypos, int ColorF, + int ColorB); +void far pascal tgprintc (int CharNum, int Xpos, int Ypos, int ColorF); +void far pascal print_str (char far *Text, int MaxLen, int Xpos, int Ypos, + int ColorF, int ColorB); +void far pascal tprint_str (char far *Text, int MaxLen, int Xpos, int Ypos, + int ColorF); +void far pascal set_display_font (char far *FontData, int FontNumber); + + /* ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== */ + +void far pascal draw_bitmap (char far *Image, int Xpos, int Ypos, + int Width, int Height); +void far pascal tdraw_bitmap (char far *Image, int Xpos, int Ypos, + int Width, int Height); + + /* ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== */ + +void far pascal copy_page (int SourcePage, int DestPage); +void far pascal copy_bitmap (int SourcePage, int X1, int Y1, int X2, int Y2, + int DestPage, int DestX1, int DestY1); + + +#endif diff --git a/16/modex105/DEMOS/C/UTLS-ASM.BAT b/16/modex105/DEMOS/C/UTLS-ASM.BAT new file mode 100644 index 00000000..d996978f --- /dev/null +++ b/16/modex105/DEMOS/C/UTLS-ASM.BAT @@ -0,0 +1 @@ +MASM c_utils, c_utils, c_utils, nul; \ No newline at end of file diff --git a/16/modex105/DEMOS/C/X-DEMO.C b/16/modex105/DEMOS/C/X-DEMO.C new file mode 100644 index 00000000..a5ac59b1 --- /dev/null +++ b/16/modex105/DEMOS/C/X-DEMO.C @@ -0,0 +1,780 @@ +/* X-DEMO.C - a Mode "X" Demo */ +/* By Matt Pritchard, 14 Apr, 1993 */ + +#include +#include + +#include "modex.h" +#include "c_utils.h" + +#define MAX_SHAPES 32 +#define MAX_SPRITES 64 + + /* routines in this file */ + +void demo_res (int, int, int); +int get_key (void); +void error_out (char*); +void load_shapes (void); +int int_sqrt (int, int); +void page_demo (void); + + /* Structures for Sprites */ + +struct Shape +{ + unsigned char Image[512]; + int X_Width; + int Y_Width; +} Img [MAX_SHAPES]; + +struct Sprite +{ + int X_pos; + int Y_pos; + int X_Dir; + int Y_Dir; + int Shape; + int Last_X [2]; + int Last_Y [2]; +} Obj [MAX_SPRITES]; + + + /* MAIN */ + + +int main(int argc, char *argv[]) +{ + + /* if (argc > 0) + { + while (argc > 0) + { + dos_print ("Unknown Argument: "); + dos_print (makefp argv[argc]); + argc--; + } + return (0); + + } + */ + + init_random (); + + load_shapes (); + + demo_res ( Mode_320x200, 320, 200 ); + demo_res ( Mode_320x400, 320, 400 ); + + demo_res ( Mode_360x200, 360, 200 ); + demo_res ( Mode_360x400, 360, 400 ); + + demo_res ( Mode_320x240, 320, 240 ); + demo_res ( Mode_320x480, 320, 480 ); + + demo_res ( Mode_360x240, 360, 240 ); + demo_res ( Mode_360x480, 360, 480 ); + + page_demo (); + + set_video_mode (3); + dos_print ("This Mode X Demo is Finished"); + return (0); + +} + + + /* Demonstrate a given resolution */ + + +void demo_res (int Screen_Mode, int X_max, int Y_max) +{ + +char *Error1 = "Failure while calling SET_MODEX"; +char *Error2 = "Failure during READ_PIXEL test"; + +char *Abort_Msg = "Demo aborted by User"; + +char *Demo_Msg = " This is a MODE X demo "; +char *Scrn_Msg = "Screen Resolution is by "; +char *Cont_Msg = "Press to Continue"; + +char *Line_Msg = "LINE TEST"; +char *Fill_Msg = "FILL TEST"; +char *Pixel_Msg = "PIXEL TEST"; + +char Text[10]; + +int x1, y1, x2, y2 = 0; +int x, y, z = 0; +int X_Center, gap = 0; + + + if (set_modex (Screen_Mode) == 0) + { + error_out (Error1); + } + + X_Center = X_max / 2; + + x1 = 10; + y1 = 10; + x2 = X_max - 1; + y2 = Y_max - 1; + + for (z = 0; z <= 3; z++) + { + y = 31 - z -z; + draw_line (x1+z, y1+z, x2-z, y1+z, y); + draw_line (x1+z, y1+z, x1+z, y2-z, y); + draw_line (x1+z, y2-z, x2-z, y2-z, y); + draw_line (x2-z, y1+z, x2-z, y2-z, y); + } + + for (x = 0; x < (X_max / 10); x++) + { + tgprintc (48 + ((x+1) % 10), x*10+1, 1, 9 + ((x/8) % 7) ); + draw_line (x*10+9, 0, x*10+9, 3, c_bWHITE); + } + + for (y = 0; y < (Y_max / 10); y++) + { + tgprintc (48 + ((y+1) % 10), 1, y*10+1, 9 + ((y/10) % 7) ); + draw_line (0, y*10+9, 3, y*10+9, c_bWHITE); + } + + for (x = 0; x <= 63; x++) + { + z = 15 + (x * 3 / 4); + set_dac_register (64+x, z, z, z); + set_dac_register (128+x, 0, z, z); + + draw_line (103-x, 60, 40+x, 123, 64+x); + draw_line (40, 60+x, 103, 123-x, 128+x); + + } + + tprint_str (Line_Msg, 9, 37, 130, c_BLUE); + + y = 60; + gap = 0; + for (x = 0; x <= 9; x++) + { + fill_block (120, y, 120+x, y+gap, 64+x); + fill_block (140 - (15-x), y, 150+x, y+gap, 230+x); + fill_block (170 - (15-x), y, 170, y+gap, 128+x); + y = y + gap + 2; + gap++; + } + + tprint_str (Fill_Msg, 9, 110, 46, c_GREEN); + + for (x = 190; x <= 250; x+=2) + { + for (y = 60; y <= 122; y+=2) + { + z = (x+x+y+y) & 0xff; + set_point (x, y, z); + } + } + + tprint_str (Pixel_Msg, 10, 182, 130, c_RED); + + for (x = 190; x <= 250; x+=2) + { + for (y = 60; y <= 122; y+=2) + { + z = (x+x+y+y) & 0xff; + if (read_point(x, y) != z) + { + error_out (Error2); + } + } + } + + print_str (Demo_Msg, 23, X_Center - 92, 20, c_bRED, c_BLUE); + + x = X_Center - 124; + print_str (Scrn_Msg, 28, x, 30, c_bGREEN, c_BLACK); + + sprintf (Text, "%3d", X_max); + print_str (Text, 3, x+168, 30, c_bPURPLE, c_BLACK); + + sprintf (Text, "%3d", Y_max); + print_str (Text, 3, x + 224, 30, c_bWHITE, c_BLACK); + + for (x = 0; x <= 15; x++) + { + set_dac_register (230+x, 63-x*4, 0, 15+x*3); + draw_line (30+x, Y_max-6-x, X_max-20-x, Y_max-6-x, 230+x); + } + + tprint_str (Cont_Msg, 27, X_Center - 103, Y_max-18, c_YELLOW); + + if (get_key () == Ky_ESC) + { + error_out (Abort_Msg); + } + + return ; + +} + + + /* Wait for a Keystroke */ + + +int get_key(void) +{ + +int c = 0; + + while (c == 0) + { + c = scan_keyboard (); + } + + return (c); + +} + + + /* Error Handling Routine */ + + +void error_out (char * text) +{ + + set_video_mode (3); + dos_print (text); + exit (EXIT_SUCCESS); + +} + + + /* Routine to generate random sprites */ + + +void load_shapes () +{ + +unsigned char Grid[33][33]; + +char *Error1 = "Bad Shape Selected Error"; + +int Shape; +int x, y, z; +int Style, Color; +int X_Width, Y_Width, Center, S_Width; +int Hollow_X, Hollow_Y; + + for (Shape = 0; Shape < MAX_SHAPES; Shape++) + { + for (y = 0; y <= 32; y++) + { + for (x = 0; x <= 32; x++) + { + Grid[x][y] = c_BLACK; + } + } + + Style = random_int (6); + Color = 1 + random_int (15); + + switch (Style) + + { + /* SOLID BOXES */ + + case 0: + + { + do + { + X_Width = 3 + random_int(30); + Y_Width = 3 + random_int(30); + + } while ( (X_Width * Y_Width) >= 512); + + for (x = 1; x <= X_Width; x++) + { + for (y = 1; y <= Y_Width; y++) + { + Grid[x][y] = Color; + } + } + + break; + + } + /* HOLLOW BOXES */ + + case 1: + + { + do { + X_Width = 6 + random_int(27); + Y_Width = 6 + random_int(27); + } while ( (X_Width * Y_Width) >= 512); + + for (y = 1; y <= Y_Width; y++) + { + for (x = 1; x <= X_Width; x++) + { + Grid[x][y] = Color; + } + } + + Hollow_X = 1 + random_int ((X_Width / 2) -1); + Hollow_Y = 1 + random_int ((Y_Width / 2) -1); + + for (y = Hollow_Y+1; y <= Y_Width-Hollow_Y; y++) + { + for (x = Hollow_X+1; x <= X_Width-Hollow_X; x++) + { + Grid[x][y] = c_BLACK; + } + } + + break; + + } + + /* SOLID DIAMOND */ + + case 2: + + { + + X_Width = 3 + 2 * random_int(10); + Y_Width = X_Width; + Center = X_Width / 2; + + for (y = 0; y <= Center; y++) + { + for (x = 0; x <= y; x++) + { + Grid [Center-x+1][y+1] = Color; + Grid [Center+x+1][y+1] = Color; + Grid [Center-x+1][Y_Width-y] = Color; + Grid [Center+x+1][Y_Width-y] = Color; + } + } + + break; + + } + + /* HOLLOW DIAMOND */ + + case 3: + + { + + X_Width = 3 + 2 * random_int(10); + Y_Width = X_Width; + Center = X_Width / 2; + S_Width = random_int (Center); + + for (y = 0; y <= Center; y++) + { + for (x = 0; x <= y; x++) + { + if ( x+(Center-y) >= S_Width ) + { + Grid [Center-x+1][y+1] = Color; + Grid [Center+x+1][y+1] = Color; + Grid [Center-x+1][Y_Width-y] = Color; + Grid [Center+x+1][Y_Width-y] = Color; + } + } + } + + break; + + } + + /* BALL */ + + case 4: + + { + + X_Width = 7 + 2 * random_int (8); + Y_Width = X_Width; + Center = 1 + X_Width / 2; + + for (y = 1; y <= Y_Width; y++) + { + for (x = 1; x <= X_Width; x++) + { + z = int_sqrt(Center-x, Center-y); + if (z < Center) + { + Grid[x][y] = 150 + Color * 2 + z * 3; + } + } + } + + break; + } + + /* HOLLOW BALLS */ + + case 5: + + { + X_Width = 7 + 2 * random_int (8); + Y_Width = X_Width; + Center = 1 + X_Width / 2; + S_Width = random_int (X_Width); + + for (y = 1; y <= Y_Width; y++) + { + for (x = 1; x <= X_Width; x++) + { + z = int_sqrt(Center-x, Center-y); + if ( (z < Center) && (z >= S_Width) ) + { + Grid[x][y] = 150 + Color * 2 + z * 3; + } + } + } + + + break; + } + + default: + + { + error_out (Error1); + break; + + } + + } + + z = 0; + for (y = 1; y <= Y_Width; y++) + { + for (x = 1; x <= X_Width; x++) + { + Img[Shape].Image[z] = Grid[x][y]; + z++; + } + } + + Img[Shape].X_Width = X_Width; + Img[Shape].Y_Width = Y_Width; + + } + + return; +} + + + /* Quickie Psuedo Integer Square Root Routine */ + + +int int_sqrt ( int x, int y ) +{ + +int Sqr_Table[12] = {1, 4, 9, 6, 25, 36, 49, 64, 81, 100, 121, 144}; + +int r, d; + + d = (x * x) + (y * y); + r = 0; + + while ( d >= Sqr_Table[r] ) + { + r++; + } + + return (r); + +} + + + /* The Bit Sprite Demo */ + + +void page_demo () +{ + +char *Error1 = "Failure during SET_VGA_MODEX (0, 360, 240, 3) call"; + +int Last_Objects[2], Visible_Objects; + +int Screen_X = 360; +int Screen_Y = 240; + +int x, y, z; +int c, dc; +int x1, y1, x2, y2; + +int Sprite_X, Sprite_Y; +int Current_Page; +int New_X, New_Y; + +int View_X, View_Y, View_Max, View_Cnt, View_XD, View_YD; +int Set_Color, Prev_Color, S_Dir, P_Dir; + +int Demo_Running = True; +int redo, code; + + if (set_vga_modex(Mode_320x200, Screen_X, Screen_Y, 3) == 0) + { + error_out (Error1); + } + + set_active_page (0); + clear_vga_screen (c_BLACK); + + print_str ("This is a Test of the Following Functions:", 99, 10, 9, c_bWHITE, c_BLACK); + + draw_line (10, 18, 350, 18, c_YELLOW); + print_str ("SET_ACTIVE_PAGE", 99, 10, 20, c_bBLUE, c_BLACK); + print_str ("SET_DISPLAY_PAGE", 99, 10, 30, c_GREEN, c_BLACK); + print_str ("SET_DAC_REGISTER", 99, 10, 40, c_RED, c_BLACK); + print_str ("CLEAR_VGA_SCREEN", 99, 10, 50, c_CYAN, c_BLACK); + + print_str ("TDRAW_BITMAP", 99, 10, 60, c_PURPLE, c_BLACK); + print_str ("COPY_PAGE", 99, 10, 70, c_GREEN, c_BLACK); + print_str ("COPY_BITMAP", 99, 10, 80, c_CYAN, c_BLACK); + + print_str ("GPRINTC", 99, 10, 90, c_BLUE, c_BLACK); + print_str ("TGPRINTC", 99, 10, 100, c_GREEN, c_BLACK); + print_str ("SET_WINDOW", 99, 10, 110, c_RED, c_BLACK); + + print_str ("VIRTUAL SCREEN SIZES", 20, 190, 20, c_bBLUE, c_BLACK); + print_str (" SMOOTH SCROLLING", 20, 190, 30, c_GREEN, c_BLACK); + print_str (" SPRITE ANIMATION", 20, 190, 40, c_CYAN, c_BLACK); + print_str (" PAGE FLIPPING", 20, 190, 50, c_RED, c_BLACK); + print_str (" COLOR CYCLING", 20, 190, 60, c_PURPLE, c_BLACK); + + for (x = 0; x <=60; x++) + { + set_dac_register (50 + x, 3 + x, 0, 60 - x); + set_dac_register (150 + x, 3 + x, 0, 60 - x); + } + + c = 0; + dc = 1; + for (x = 0; x <= (Screen_X / 2); x++) + { + draw_line (Screen_X / 2 - 1, Screen_Y / 4, x, Screen_Y - 1, c + 50); + draw_line (Screen_X / 2, Screen_Y / 4, Screen_X - x - 1, Screen_Y - 1, c + 50); + c+= dc; + if ((c == 0) || (c == 60) ) { dc = -dc;} + } + + tprint_str ("Press to Continue", 99, 72, 190, c_bWHITE); + tprint_str ("< > = Faster < > = Slower", 99, 72, 204, c_bGREEN); + tprint_str ("< > = Fewer Shapes < > = More Shapes", 99, 32, 218, c_bCYAN); + + tgprintc (43, 80, 204, c_YELLOW); + tgprintc (45, 200, 204, c_YELLOW); + + tgprintc (25, 40, 218, c_YELLOW); + tgprintc (24, 200, 218, c_YELLOW); + + copy_page (0, 1); + copy_page (0, 2); + + for (x = 0; x < MAX_SPRITES; x++) + { + do { + Obj[x].X_Dir = random_int(7) - 3; + Obj[x].Y_Dir = random_int(7) - 3; + } while ( (Obj[x].X_Dir == 0) && (Obj[x].Y_Dir == 0) ); + + Obj[x].Shape = x % MAX_SHAPES; + + Sprite_X = Img[Obj[x].Shape].X_Width; + Sprite_Y = Img[Obj[x].Shape].Y_Width; + + Obj[x].X_pos = 1 + random_int(Screen_X - Sprite_X - 2); + Obj[x].Y_pos = 1 + random_int(Screen_Y - Sprite_Y - 2); + + Obj[x].Last_X[0] = Obj[x].X_pos; + Obj[x].Last_X[1] = Obj[x].X_pos; + Obj[x].Last_Y[0] = Obj[x].Y_pos; + Obj[x].Last_Y[1] = Obj[x].Y_pos; + + } + + Current_Page = 0; + + View_X = 0; + View_Y = 0; + View_Max = 3; + View_Cnt = 0; + View_XD = 1; + View_YD = 1; + + Set_Color = 3; + S_Dir = 1; + Prev_Color = 0; + P_Dir = 1; + + Visible_Objects = MAX_SPRITES / 2; + Last_Objects[0] = 0; + Last_Objects[1] = 0; + + while (Demo_Running) + { + + set_active_page (Current_Page); + + /* Erase Old Images */ + + for (x = 0; x <= Last_Objects[Current_Page]; x++) + { + z = 2; + y = Obj[x].Shape; + x1 = Obj[x].Last_X[Current_Page]; + y1 = Obj[x].Last_Y[Current_Page]; + x2 = x1 + Img[y].X_Width -1; + y2 = y1 + Img[y].Y_Width -1; + + x1 = x1 & 0xfffc; + x2 = x2 | 0x0003; + + copy_bitmap (z, x1, y1, x2, y2, Current_Page, x1, y1); + } + + /* Draw new images */ + + for (x = 0; x <= Visible_Objects; x++) + { + Sprite_X = Img[Obj[x].Shape].X_Width; + Sprite_Y = Img[Obj[x].Shape].Y_Width; + + /* Move Sprite */ + + do + { + redo = False; + New_X = Obj[x].X_pos + Obj[x].X_Dir; + + if (( New_X < 0 ) || (New_X + Sprite_X > Screen_X) ) + { + Obj[x].X_Dir = -Obj[x].X_Dir; + if (random_int(20) == 1) + { + do + { + Obj[x].X_Dir = random_int(7) - 3; + Obj[x].Y_Dir = random_int(7) - 3; + } while ( (Obj[x].X_Dir == 0) && (Obj[x].Y_Dir == 0) ); + redo = True; + } + } + } while (redo); + Obj[x].X_pos = Obj[x].X_pos + Obj[x].X_Dir; + + + do + { + redo = False; + New_Y = Obj[x].Y_pos + Obj[x].Y_Dir; + + if ( (New_Y < 0) || (New_Y + Sprite_Y > Screen_Y) ) + { + Obj[x].Y_Dir = -Obj[x].Y_Dir; + if (random_int(20) == 1) + { + do + { + Obj[x].X_Dir = random_int(7) - 3; + Obj[x].Y_Dir = random_int(7) - 3; + } while ( (Obj[x].X_Dir == 0) && (Obj[x].Y_Dir == 0) ); + redo = True; + } + } + } while (redo); + + Obj[x].Y_pos = Obj[x].Y_pos + Obj[x].Y_Dir; + + /* Draw Sprite */ + + tdraw_bitmap ((char far*) &Img[Obj[x].Shape], Obj[x].X_pos, Obj[x].Y_pos, Sprite_X, Sprite_Y); + + Obj[x].Last_X[Current_Page] = Obj[x].X_pos; + Obj[x].Last_Y[Current_Page] = Obj[x].Y_pos; + + } + + Last_Objects[Current_Page] = Visible_Objects; + + + /* Pan Screen Back & Forth */ + + View_Cnt++; + if (View_Cnt >= View_Max) + { + View_X+= View_XD; + if ( (View_X == 0) || (View_X == 39) ) {View_XD = -View_XD;} + if (View_XD < 0) + { + View_Y+= View_YD; + if ( (View_Y == 0) || (View_Y == 39) ) {View_YD = -View_YD;} + } + + set_window (Current_Page, View_X, View_Y); + + View_Cnt = 0; + } + else + { + set_display_page (Current_Page); + } + + /* Cycle Colors */ + + set_dac_register (50 + Prev_Color, 3 + Prev_Color, 0, 60 - Prev_Color); + set_dac_register (50 + Set_Color, Set_Color, 10, 63 - Set_Color); + + set_dac_register (150 + Prev_Color, 3 + Prev_Color, 0, 60 - Prev_Color); + set_dac_register (150 + Set_Color, 63, 63, Set_Color); + + Set_Color+= S_Dir; + if ( (Set_Color == 60) || (Set_Color == 0) ) {S_Dir = -S_Dir;} + + Prev_Color+= P_Dir; + if ( (Prev_Color == 60) || (Prev_Color == 0) ) {P_Dir = -P_Dir;} + + /* Check for Keystroke */ + + Current_Page = Current_Page ^ 0x01; + + code = scan_keyboard (); + + if (code == Ky_ESC) {Demo_Running = False;} + + if (code == Ky_Plus) + { + if (View_Max < 12) {View_Max++;} + } + + if (code == Ky_Minus) + { + if (View_Max > 1) {View_Max--;} + if (View_Cnt >= View_Max) {View_Cnt = 0;} + } + + if (code == Ky_Up) + { + if (Visible_Objects < MAX_SPRITES-1) {Visible_Objects++;} + } + + if (code == Ky_Down) + { + if (Visible_Objects > 0) {Visible_Objects--;} + } + + } + +} diff --git a/16/modex105/DEMOS/C/X-DEMO.EXE b/16/modex105/DEMOS/C/X-DEMO.EXE new file mode 100644 index 0000000000000000000000000000000000000000..7742d145c591d471d2e9b79e0fe99083a3d669f2 GIT binary patch literal 41090 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 JvY09JKLIz`z5M_H literal 0 HcmV?d00001 diff --git a/16/modex105/DEMOS/C/X-DEMO.PRJ b/16/modex105/DEMOS/C/X-DEMO.PRJ new file mode 100644 index 0000000000000000000000000000000000000000..7bc4a069233a535f9a2bbb6b21436c8e018409e4 GIT binary patch literal 5188 zcmeI0*;89}6vxjm1PDtlt<^%>!cUD#+aW-ZrMO%|5-?6SlVBN3MV5fnLNGwx0b7@j zOQ+RGU)-%bT6KJIdGW=zRL7;I_0fO8U9`2=^SuFVm3SeEWybNB$tUNWdzN3$-GAYc zSZ7o^WFQvZ7U>$6O?}%V(oAC6%GH8@vTYPJeL@BjbdX7ONRtn1oYX8wG`^pQtsiLo zP~%5TL7!`$UugW2nL$UH4RnlYpegLg6-ciFuK}+EZvgKA?*c1P@_b+wLtFq{2z9lH_plI3kwCxA5Z3@} z8DbrzVn#*@R0;KB;1a+BTnb#q!RpxMEN#@%+-hKP3qx!LZUQ=iE}$ET06jo2a0`R_ zfdL>2+ij4BAdNuU0qJ%~cR;!mxC^)&xQ9V|fP0~i0%O29a38P}*u|jxAw2**2=yUg zH`IrLM}WtGy}&-;ao`ESSir~xvVd&B1e6IUcQEx~731WrZ)@}iJ$9ed(dPC!JS|RF z>WLSTq5Lm%@VFZn5uF~_3O+omY($kJlWf(T)5bz&MFmln7)wuyUz}adTi45sMqzlQrF`uU5~4EJ+9I9P;@;S_`qH2VPE>g(8Ix4v)Jkg1gKfNRj4YT&y>aY+Ee@Xm~-hX6OA?pU4aGc#NJqBZ~<-$ zb}1X!C@o%>x3tn$w_aL&{?KN7Kw1Jpzc&z;76&WdP;)6}XJcXgj%Z)E++gjJ3$Ac( z91p2tG^{5#9a(J&Tc`fnkC%{Q=L$f@t^Xw(A_^6jSWjrUuUc%*4HtR zAeGx2Nb6&+CEW=V%=_Oqf2QId{r^a*1JyLa@0jty{nQ3DM|(@y?Fm`^jn|Ra?{u}c zooSf~Sj0~*<&X($BQxX7T3UXslA|qN>rcz9|6+bK`LQjVmvDHkg--Iro4ShV<7U>_ z)LQ0rdHq%g@e6Fc)|_QACFXpwRAj`0&bTC3YXR)CM3z{s#GLs|DqED(^;?z6BtB9J zC^03fY*Qjimolu>D^jVUT#?U(%)B!64KH;apeJc3jZhD%s+sNiJg4{ge;cWx=wM-{ z#w?B58ciB=$kXvCKiHP;O# zklbpWT?S}t_cggaF6-Yngu+g@e;#|guf^k;&+c?Jh32ty9=;A@1OD9HZmXq>C=YF? X5-O&3w3gOTAr*0V3fVd{aHaSIrzdwi literal 0 HcmV?d00001 diff --git a/16/modex105/DEMOS/CHARDEMO.EXE b/16/modex105/DEMOS/CHARDEMO.EXE new file mode 100644 index 0000000000000000000000000000000000000000..4015bdf14e1d4067c4c2d9321f00accdf71fe452 GIT binary patch literal 13066 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 RBhN(+NB$^IcBSvV{T~&EV%Y!y literal 0 HcmV?d00001 diff --git a/16/modex105/DEMOS/PASCAL/TEST5.PAS b/16/modex105/DEMOS/PASCAL/TEST5.PAS new file mode 100644 index 00000000..7cc56bbb --- /dev/null +++ b/16/modex105/DEMOS/PASCAL/TEST5.PAS @@ -0,0 +1,488 @@ +{ ModeX Turbo Pascal Demo Program } +{ Converted to Turbo Pascal by Scott Wyatt } +{ Original program written in QuickBasic by Matt Prichard } +{ Released to the Public Domain } +{ } +{ Thanks to Matt Prichard for his *EXCELLENT* ModeX Library } +{ Additional Comments by Matt Pritchard } + +Uses Crt; + +{$L modex2.obj} { This file is the external ModeX Library .OBJ } +{$F+} + + { Mode Setting Routines } + +Function SET_VGA_MODEX (Mode,MaxXpos,MaxYpos,Pages : integer) : integer; external; +Function SET_MODEX (Mode:integer) : Integer; external; + + { Graphics Primitives } + +Procedure CLEAR_VGA_SCREEN (Color:integer); external; +Procedure SET_POINT (Xpos,Ypos,Color : integer); external; +Function READ_POINT (Xpos,Ypos:integer) : integer; external; +Procedure FILL_BLOCK (Xpos1,Ypos1,Xpos2,Ypos2,Color:integer); external; +Procedure DRAW_LINE (Xpos1,Ypos1,Xpos2,Ypos2,Color:integer); external; + + { VGA DAC Routines } + +Procedure SET_DAC_REGISTER (RegNo,Red,Green,Blue:integer); external; +Procedure GET_DAC_REGISTER (RegNo,Red,Green,Blue:integer); external; + + { Page and Window Control Routines } + +Procedure SET_ACTIVE_PAGE (PageNo:integer); external; +Function GET_ACTIVE_PAGE : integer; external; +Procedure SET_DISPLAY_PAGE (PageNo:integer); external; +Function GET_DISPLAY_PAGE : integer; external; +Procedure SET_WINDOW (DisplayPage,XOffset,YOffset : integer); external; +Function GET_X_OFFSET : integer; external; +Function GET_Y_OFFSET : integer; external; +Procedure SYNC_DISPLAY; external; + + { Text Display Routines } + +Procedure GPRINTC (CharNum,Xpos,Ypos,ColorF,ColorB:integer); external; +Procedure TGPRINTC ( CharNum,Xpos,Ypos,ColorF : integer); external; +Procedure PRINT_STR (Var Text;MaxLen,Xpos,Ypos,ColorF,ColorB:integer); external; +Procedure TPRINT_STR (Var Text;MaxLen,Xpos,Ypos,ColorF:integer); external; +Procedure SET_DISPLAY_FONT (Var FontData;FontNumber:integer); external; + + { Sprite and VGA memory -> Vga memory Copy Routines } + +Procedure DRAW_BITMAP (Var Image;Xpos,Ypos,Width,Height:integer); external; +Procedure TDRAW_BITMAP (Var Image;Xpos,Ypos,Width,Height:integer); external; +Procedure COPY_PAGE (SourcePage,DestPage:integer); external; +Procedure COPY_BITMAP (SourcePage,X1,Y1,X2,Y2,DestPage,DestX1,DestY1:integer); external; + +{$F-} + + +TYPE Sprite = Record + Xpos : INTEGER; + Ypos : INTEGER; + XDir : INTEGER; + YDir : INTEGER; + Shape : INTEGER; + LastX : INTEGER; + LastY : INTEGER; + END; + + +CONST MaxShapes = 32; + Circle_16 : Array[1..16,1..16] of byte = + (( 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0), + ( 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0), + ( 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0), + ( 0, 0, 20, 20, 20, 20, 0, 0, 0, 0, 20, 20, 20, 20, 0, 0), + ( 0, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 0), + ( 0, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 0), + ( 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20), + ( 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20), + ( 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20), + ( 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20), + ( 0, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 0), + ( 0, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 0), + ( 0, 0, 20, 20, 20, 20, 0, 0, 0, 0, 20, 20, 20, 20, 0, 0), + ( 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0), + ( 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0), + ( 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0)); + Square_16 : Array[1..16,1..16] of byte = + (( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21)); + Diamond : Array[1..8,1..8] of byte = + (( 0, 0, 0, 22, 22, 0, 0, 0), + ( 0, 0, 22, 22, 22, 22, 0, 0), + ( 0, 22, 22, 0, 0, 22, 22, 0), + ( 22, 22, 0, 0, 0, 0, 22, 22), + ( 22, 22, 0, 0, 0, 0, 22, 22), + ( 0, 22, 22, 0, 0, 22, 22, 0), + ( 0, 0, 22, 22, 22, 22, 0, 0), + ( 0, 0, 0, 22, 22, 0, 0, 0)); + Rectangle : Array[1..8,1..3] of byte = + (( 23, 23, 23), + ( 23, 23, 23), + ( 23, 23, 23), + ( 23, 23, 23), + ( 23, 23, 23), + ( 23, 23, 23), + ( 23, 23, 23), + ( 23, 23, 23)); + + { Global Variables ? } + +Var + XCenter,X1,Y1,X2,Y2,Z,Colr,XChars,YChars,X,Y,N,Gap : Integer; + s : string; + s1 : Array[1..35] of Char; + ch : Char; + obj : Array[1..64] of Sprite; + ScreenX,ScreenY : Integer; + c, dc, SpriteX, SpriteY, CurrentPage, LastPage : Integer; + SetColor, SDir, PrevColor, PDir : Byte; + XView, YView : Integer; + XView_Change, YView_Change : Integer; + Right : Boolean; + Number_Of_Shapes : Byte; + + + { Error Handler - Returns to Text Mode & Displays Error } + +Procedure ERROR_OUT(s : string); + Begin + asm + mov ah,0 + mov al,3 + int 10h + end; + WriteLn(s); + Halt(0); +END; + + { Routine to Print a PASCAL string using Print_Str } + +Procedure Print_Text(s : string; X,Y,BColor,FColor : integer); +Var + s1 : Array[1..135] of Char; + i : byte; +Begin + For i := 1 to Length(s) DO + s1[i] := s[i]; + Print_Str(s1,Length(s),X,Y,BColor,FColor); +End; + + { Routine to Transparently Print a PASCAL string using TPrint_Str } + +Procedure TPrint_Text(s : string; X,Y,Color : integer); +Var + s1 : Array[1..135] of Char; + i : byte; +Begin + For i := 1 to Length(s) DO + s1[i] := s[i]; + TPrint_Str(s1,Length(s),X,Y,Color); +End; + + { Routines to show test patterns for a given mode } + +Procedure Demo_Res(Mode, Xmax, Ymax : integer); +Begin + + Str(mode,s); + If Set_ModeX(Mode) = 0 Then + Error_Out('Unable to SET_MODEX '+s); + Clear_VGA_Screen(0); + + XCenter := Xmax div 2; + X1 := 10; + Y1 := 10; + X2 := Xmax - 1; + Y2 := Ymax - 1; + + FOR Z := 0 TO 3 DO + Begin + Colr := 31 - Z * 2; + Draw_Line(X1 + Z, Y1 + Z, X2 - Z, Y1 + Z, Colr); + Draw_Line(X1 + Z, Y1 + Z, X1 + Z, Y2 - Z, Colr); + Draw_Line(X1 + Z, Y2 - Z, X2 - Z, Y2 - Z, Colr); + Draw_Line(X2 - Z, Y1 + Z, X2 - Z, Y2 - Z, Colr); + End; + + XChars := Xmax div 10; + YChars := Ymax div 10; + + FOR X := 0 TO XChars - 1 DO + Begin + TGPRINTC(48 + ((X + 1) MOD 10), X * 10 + 1, 1, 9 + ((X div 8) MOD 7)); + DRAW_LINE(X * 10 + 9, 0, X * 10 + 9, 3, 15); + End; + FOR Y := 0 TO YChars - 1 DO + Begin + TGPRINTC(48 + ((Y + 1) MOD 10), 1, Y * 10 + 1, 9 + ((Y div 10) MOD 7)); + DRAW_LINE(0, Y * 10 + 9, 3, Y * 10 + 9, 15); + End; + + { Test Line Drawing } + + FOR X := 0 TO 63 DO + Begin + N := 15 + ((X * 3) div 4); + SET_DAC_REGISTER(64 + X, N, N, N); + SET_DAC_REGISTER(128 + X, 0, N, N); + DRAW_LINE(103 - X, 60, 40 + X, 123, 64 + X); + DRAW_LINE(40, 60 + X, 103, 123 - X, 128 + X); + End; + s := 'Line Test'; + PRINT_Text(s,37,130,1,0); + + { Test Block Fills } + + Y := 60; + Gap := 0; + FOR X := 0 TO 9 DO + Begin + FILL_BLOCK(120, Y, 120 + X, Y + Gap, 64 + X); + FILL_BLOCK(140 - (15 - X), Y, 150 + X, Y + Gap, 230 + X); + FILL_BLOCK(170 - (15 - X), Y, 170, Y + Gap, 128 + X); + Y := Y + Gap + 2; + Gap := Gap + 1; + End; + s := 'Fill Test'; + Print_Text(s,110, 46, 2,0); + + { Test Pixel Write and Read } + + FOR X := 190 TO 250 DO + FOR Y := 60 TO 122 DO + SET_POINT( X, Y, X + Y + X + Y); + + s := 'Pixel Test'; + Print_Text(s,182, 130, 3,0); + + FOR X := 190 TO 250 DO + FOR Y := 60 TO 122 DO + IF READ_POINT(X, Y) <> ((X + Y + X + Y) AND 255) THEN + WriteLn('READ_PIXEL Failure'); + + { Display rest of screen } + + s := ' This is a MODE X demo '; + Print_Text(s,XCenter - (Length(s) * 4), 20, 3, 1); + s := 'Screen Resolution is by '; + X := XCenter - (Length(s) * 4); + Print_Text(s,X,30,4,0); + Str(XMax,s); + Print_Text(s, X + 8 * 21, 30, 8, 0); + Str(YMax,s); + Print_Text(s, X + 8 * 28, 30, 15, 0); + + FOR X := 0 TO 15 DO + Begin + SET_DAC_REGISTER( 230 + X, 63 - X * 4, 0, 15 + X * 3); + DRAW_LINE(30 + X, Ymax - 6 - X, Xmax - 20 - X, Ymax - 6 - X, 230 + X); + End; + s := 'Press to Continue'; + For x := 1 to length(s) DO + s1[x] := s[x]; + TPrint_Str(s1, length(s), XCenter - (26 * 4), Ymax - 18, 5); + + Ch := ReadKey; + IF Ch = #27 Then + Error_Out('Abort'); + +End; + + + { Initialize Sprites for Sprite Demo } + +Procedure Init_Sprites; +Var i : byte; +Begin + For i := 1 to 64 DO + Begin + Obj[i].XPos := Random(300)+10; + Obj[i].YPos := Random(200)+20; + Obj[i].XDir := Random(10)-5; + Obj[i].YDir := Random(10)-5; + If (Obj[i].XDir = 0) AND (Obj[i].YDir = 0) Then + Begin + Obj[i].XDir := Random(5) + 1; + Obj[i].YDir := Random(5) + 1; + End; + Obj[i].Shape := Random(4)+1; + Obj[i].LastX := obj[i].XPos; + Obj[i].LastY := obj[i].YPos; + End; +End; + +Procedure Set_Sprites(number : byte); +Var i : Byte; +Begin + For i := 1 to number DO + Begin + obj[i].LastX := obj[i].XPos; + obj[i].LastY := obj[i].YPos; + obj[i].XPos := obj[i].XPos + obj[i].XDir; + obj[i].YPos := obj[i].YPos + obj[i].YDir; + If (obj[i].XPos > 335) OR (obj[i].XPos < 5 ) Then + obj[i].XDir := -(obj[i].XDir); + If (obj[i].YPos > 220) OR (obj[i].YPos < 5) Then + obj[i].YDir := -(obj[i].YDir); + End; + For i := 1 to number DO + Case obj[i].Shape of + 1 : TDraw_Bitmap(Circle_16,obj[i].XPos,obj[i].YPos,16,16); + 2 : TDraw_Bitmap(Square_16,obj[i].XPos,obj[i].YPos,16,16); + 3 : TDraw_Bitmap(Diamond,obj[i].XPos,obj[i].YPos,8,8); + 4 : TDraw_Bitmap(Rectangle,obj[i].XPos,obj[i].YPos,3,8); + End; +End; + +Procedure Remove_Sprites(p,number : byte); +Var i : byte; +Begin + For i := 1 to number DO + Copy_Bitmap(2,obj[i].LastX,obj[i].LastY,obj[i].LastX+16,obj[i].LastY+16,p,Obj[i].LastX,Obj[i].LastY); +End; + +Procedure Page_Demo; +Begin + Number_Of_Shapes := 64; + XView_Change := 1; + YView_Change := 1; + XView := 1; + YView := 1; + Right := TRUE; + ScreenX := 360; + ScreenY := 240; + PrevColor := 0; + SetColor := 3; + SDir := 1; + PDir := 1; + Str(0,s); + + IF SET_VGA_MODEX(0, ScreenX, ScreenY, 3) = 0 THEN + ERROR_OUT('Unable to SET_VGA_MODEX' + S); + + SET_ACTIVE_PAGE(0); + CLEAR_VGA_SCREEN(0); + PRINT_TEXT('This is a Test of the Following Functions:', 10, 9, 15, 0); + DRAW_LINE( 10, 18, 350, 18, 4); + Print_Text('SET_ACTIVE_PAGE', 10, 20, 1, 0); + Print_Text('SET_DISPLAY_PAGE', 10, 30, 3,0); + Print_Text('SET_DAC_REGISTER', 10, 40, 3, 0); + Print_Text('CLEAR_VGA_SCREEN', 10, 50, 13, 0); + Print_Text('TDRAW_BITMAP', 10, 60, 14, 0); + Print_Text('COPY_PAGE', 10, 70, 3, 0); + Print_Text('COPY_BITMAP', 10, 80, 13, 0); + Print_Text('GPRINTC', 10, 90, 1, 0); + Print_Text('TGPRINTC', 10, 100, 3, 0); + Print_Text('SYNC_DISPLAY', 10, 110, 3, 0); + Print_Text('SET_WINDOW', 10, 120, 14, 0); + Print_Text('VIRTUAL SCREEN SIZES', 190, 20, 1, 0); + Print_Text(' SMOOTH SCROLLING', 190, 30, 3, 0); + Print_Text(' SPRITE ANIMATION', 190, 40, 13, 0); + Print_Text(' PAGE FLIPPING', 190, 50, 3, 0); + Print_Text(' COLOR CYCLING', 190, 60, 14, 0); + + FOR X := 0 TO 60 DO + Begin + SET_DAC_REGISTER( 50 + X, 3 + X, 0, 60 - X); + SET_DAC_REGISTER( 150 + X, 3 + X, 0, 60 - X); + End; + + c := 0; + DC := 1; + FOR X := 0 TO ScreenX div 2 DO + Begin + DRAW_LINE( ScreenX div 2 - 1, ScreenY div 4, X, ScreenY - 1, c + 50); + DRAW_LINE( ScreenX div 2, ScreenY div 4, ScreenX - X - 1, ScreenY - 1, c + 50); + c := c + DC; + IF (c = 0) OR (c = 60) THEN DC := -DC; + End; + + TPrint_Text('Press to Continue', 82, 190, 15); + TPrint_Text('<+> = Fewer Shapes <-> = More Shapes', 32, 204, 12); + COPY_PAGE( 0, 1); + COPY_PAGE( 0, 2); + + Ch := #0; + CurrentPage := 1; + LastPage := 0; + Set_Sprites(Number_Of_Shapes); + For c := 1 to 4 DO + Set_Dac_Register(19+c,63-(c*10),0,0); + + While Ch <> #27 DO + Begin + Set_Active_Page(currentpage); + Set_Sprites(Number_Of_Shapes); + If Right Then + Begin + XView := XView + XView_Change; + If (XView > 38) OR (XView < 2) Then + Begin + XView_Change := -(XView_Change); + Right := FALSE; + End; + End + Else + Begin + YView := YView + YView_Change; + If (YView > 38) OR (YView < 2) Then + Begin + YView_Change := -(YView_Change); + Right := TRUE; + End; + End; + + Set_Window(currentpage,XView,YView); + Set_Display_Page(currentpage); + Set_Dac_Register(50 + PrevColor, 3 + PrevColor, 0, 60 - PrevColor); + Set_Dac_Register(50 + SetColor, SetColor, 10, 63 - SetColor); + Set_Dac_Register(150 + PrevColor, 3 + PrevColor, 0, 60 - PrevColor); + Set_Dac_Register(150 + SetColor, 63, 63, SetColor); + SetColor := SetColor + SDir; + IF (SetColor = 60) OR (SetColor = 0) THEN SDir := -SDir; + PrevColor := PrevColor + PDir; + IF (PrevColor = 60) OR (PrevColor = 0) THEN PDir := -PDir; + Remove_Sprites(lastpage,Number_Of_Shapes); + + If Keypressed Then + Begin + Ch := ReadKey; + Case Ch of + '-' : If Number_Of_Shapes > 1 Then + Begin + c := Number_Of_Shapes; + Copy_Bitmap(2,obj[c].XPos,obj[c].YPos,obj[c].XPos+16,obj[c].YPos+16, + currentpage,obj[c].XPos,obj[c].YPos); + Dec(Number_Of_Shapes); + End; + '+' : If Number_Of_Shapes < 64 Then Inc(Number_Of_Shapes); + End; + End; + lastpage := (lastpage+1) MOD 2; + currentpage := (currentpage+1) MOD 2; + End; +END; + + { MAIN ROUTINE - Run Through Demos and Exit } + +Begin + + Randomize; + Init_Sprites; + + Demo_Res(0, 320, 200); + Demo_Res(1, 320, 400); + Demo_Res(2, 360, 200); + Demo_Res(3, 360, 400); + Demo_Res(4, 320, 240); + Demo_Res(5, 320, 480); + Demo_Res(6, 360, 240); + Demo_Res(7, 360, 480); + Page_Demo; + + asm + mov ah,0 + mov al,3 + int 10h + end; + WriteLn('THIS MODE X DEMO IS FINISHED'); + +END. \ No newline at end of file diff --git a/16/modex105/DEMOS/QB45/MAKE-LIB.BAT b/16/modex105/DEMOS/QB45/MAKE-LIB.BAT new file mode 100644 index 00000000..b04876ad --- /dev/null +++ b/16/modex105/DEMOS/QB45/MAKE-LIB.BAT @@ -0,0 +1,5 @@ +ECHO ... Building MODEX.QLB for QUICKBASIC 4.5 +LIB MODEX -+MODEX,, +LIB MODEX -+UTILS,, +DEL MODEX.BAK +LINK /Q MODEX+UTILS, MODEX.QLB, NUL, C:\QB45\BQLB45.LIB; diff --git a/16/modex105/DEMOS/QB45/MODEX.BI b/16/modex105/DEMOS/QB45/MODEX.BI new file mode 100644 index 00000000..6b1d7afe --- /dev/null +++ b/16/modex105/DEMOS/QB45/MODEX.BI @@ -0,0 +1,63 @@ + + ' ===== SCREEN RESOLUTIONS ===== + +CONST Mode320x200 = 0, Mode320x400 = 1 +CONST Mode360x200 = 2, Mode360x400 = 3 +CONST Mode320x240 = 4, Mode320x480 = 5 +CONST Mode360x240 = 6, Mode360x480 = 7 + + ' ===== MODE X SETUP ROUTINES ===== + +DECLARE FUNCTION SET.VGA.MODEX% ALIAS "SET_VGA_MODEX" (BYVAL ModeType%, BYVAL MaxXpos%, BYVAL MaxYpos%, BYVAL Pages%) +DECLARE FUNCTION SET.MODEX% ALIAS "SET_MODEX" (BYVAL Mode%) + + ' ===== BASIC GRAPHICS PRIMITIVES ===== + +DECLARE SUB CLEAR.VGA.SCREEN ALIAS "CLEAR_VGA_SCREEN" (BYVAL ColorNum%) +DECLARE SUB SET.POINT ALIAS "SET_POINT" (BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorNum%) +DECLARE FUNCTION READ.POINT% ALIAS "READ_POINT" (BYVAL Xpos%, BYVAL Ypos%) +DECLARE SUB FILL.BLOCK ALIAS "FILL_BLOCK" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) +DECLARE SUB DRAW.LINE ALIAS "DRAW_LINE" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) + + ' ===== DAC COLOR REGISTER ROUTINES ===== + +DECLARE SUB SET.DAC.REGISTER ALIAS "SET_DAC_REGISTER" (BYVAL RegNo%, BYVAL Red%, BYVAL Green%, BYVAL Blue%) +DECLARE SUB GET.DAC.REGISTER ALIAS "GET_DAC_REGISTER" (BYVAL RegNo%, Red%, Green%, Blue%) +DECLARE SUB LOAD.DAC.REGISTERS ALIAS "LOAD_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%, BYVAL VSync%) +DECLARE SUB READ.DAC.REGISTERS ALIAS "READ_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%) + + + ' ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== + +DECLARE SUB SET.ACTIVE.PAGE ALIAS "SET_ACTIVE_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.ACTIVE.PAGE% ALIAS "GET_ACTIVE_PAGE" +DECLARE SUB SET.DISPLAY.PAGE ALIAS "SET_DISPLAY_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.DISPLAY.PAGE% ALIAS "GET_DISPLAY_PAGE" +DECLARE SUB SET.WINDOW ALIAS "SET_WINDOW" (BYVAL DisplayPage%, BYVAL XOffset%, BYVAL YOffset%) +DECLARE FUNCTION GET.X.OFFSET% ALIAS "GET_X_OFFSET" () +DECLARE FUNCTION GET.Y.OFFSET% ALIAS "GET_Y_OFFSET" () +DECLARE SUB SYNC.DISPLAY ALIAS "SYNC_DISPLAY" + + ' ===== TEXT DISPLAY ROUTINES ===== + +DECLARE SUB GPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TGPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB PRINT.STR ALIAS "PRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TPRINT.STR ALIAS "TPRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB SET.DISPLAY.FONT ALIAS "SET_DISPLAY_FONT" (SEG FontData AS ANY, BYVAL FontNumber%) + + ' ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== + +DECLARE SUB DRAW.BITMAP ALIAS "DRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) +DECLARE SUB TDRAW.BITMAP ALIAS "TDRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) + + ' ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== + +DECLARE SUB COPY.PAGE ALIAS "COPY_PAGE" (BYVAL SourcePage%, BYVAL DestPage%) +DECLARE SUB COPY.BITMAP ALIAS "COPY_BITMAP" (BYVAL SourcePage%, BYVAL X1%, BYVAL Y1%, BYVAL X2%, BYVAL Y2%, BYVAL DestPage%, BYVAL DestX1%, BYVAL DestY1%) + + + + + + diff --git a/16/modex105/DEMOS/QB45/MODEX.LIB b/16/modex105/DEMOS/QB45/MODEX.LIB new file mode 100644 index 0000000000000000000000000000000000000000..7baeb85eaf962cce04d3d3ab7c876e9eba2f744a GIT binary patch literal 7189 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 ((X + Y + X + Y) AND 255) THEN + ERROR.OUT "READ.PIXEL Failure" + END IF + NEXT Y + NEXT X + + + + Msg$ = " This is a MODE X demo " + PRINT.TEXT Msg$, XCenter - (LEN(Msg$) * 4), 20, c.bRED, c.BLUE + Msg$ = "Screen Resolution is by " + Xp = XCenter - (LEN(Msg$) * 4) + PRINT.TEXT Msg$, Xp, 30, c.bGREEN, c.BLACK + + PRINT.TEXT LTRIM$(STR$(Xmax)), Xp + 8 * 21, 30, c.bPURPLE, c.BLACK + PRINT.TEXT LTRIM$(STR$(Ymax)), Xp + 8 * 28, 30, c.bWHITE, c.BLACK + + FOR X = 0 TO 15 + SET.DAC.REGISTER 230 + X, 63 - X * 4, 0, 15 + X * 3 + DRAW.LINE 30 + X, Ymax - 6 - X, Xmax - 20 - X, Ymax - 6 - X, 230 + X + NEXT X + TPRINT.TEXT "Press to Continue", XCenter - (26 * 4), Ymax - 18, c.YELLOW + + X = GET.KEY% + IF X = KyESC THEN ERROR.OUT "ABORT" + +END SUB + +SUB ERROR.OUT (Message$) + + SET.VIDEO.MODE 3 + DOS.PRINT Message$ + END + +END SUB + +FUNCTION GET.KEY% + + DO + X = SCAN.KEYBOARD + LOOP UNTIL X + + GET.KEY% = X + +END FUNCTION + +SUB LOAD.SHAPES + +DIM Grid(1 TO 32, 1 TO 32) + + FOR Shape = 0 TO MaxShapes - 1 + + FOR Y = 1 TO 32 + FOR X = 1 TO 32 + Grid(X, Y) = 0 + NEXT X + NEXT Y + + Style = RANDOM.INT(6) + Colour = 1 + RANDOM.INT(15) + + SELECT CASE Style + + CASE 0: ' Solid Box + + DO + xWidth = 3 + RANDOM.INT(30) + yWidth = 3 + RANDOM.INT(30) + LOOP UNTIL ((xWidth * yWidth) <= 512) + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + Grid(X, Y) = Colour + NEXT X + NEXT Y + + CASE 1: ' Hollow Box + + DO + xWidth = 5 + RANDOM.INT(28) + yWidth = 5 + RANDOM.INT(28) + LOOP UNTIL ((xWidth * yWidth) <= 512) + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + Grid(X, Y) = Colour + NEXT X + NEXT Y + + HollowX = 1 + RANDOM.INT(xWidth \ 2 - 1) + HollowY = 1 + RANDOM.INT(yWidth \ 2 - 1) + + FOR Y = HollowY + 1 TO yWidth - HollowY + FOR X = HollowX + 1 TO xWidth - HollowX + Grid(X, Y) = nil + NEXT X + NEXT Y + + CASE 2: ' Solid Diamond + + xWidth = 3 + 2 * RANDOM.INT(10) + yWidth = xWidth + Centre = xWidth \ 2 + + FOR Y = 0 TO Centre + FOR X = 0 TO Y + Grid(Centre - X + 1, Y + 1) = Colour + Grid(Centre + X + 1, Y + 1) = Colour + Grid(Centre - X + 1, yWidth - Y) = Colour + Grid(Centre + X + 1, yWidth - Y) = Colour + NEXT X + NEXT Y + + + CASE 3: ' Hollow Diamond + + + xWidth = 3 + 2 * RANDOM.INT(10) + yWidth = xWidth + Centre = xWidth \ 2 + sWidth = RANDOM.INT(Centre) + + FOR Y = 0 TO Centre + FOR X = 0 TO Y + IF X + (Centre - Y) >= sWidth THEN + Grid(Centre - X + 1, Y + 1) = Colour + Grid(Centre + X + 1, Y + 1) = Colour + Grid(Centre - X + 1, yWidth - Y) = Colour + Grid(Centre + X + 1, yWidth - Y) = Colour + END IF + NEXT X + NEXT Y + + CASE 4: ' Ball + + xWidth = 7 + 2 * RANDOM.INT(8) + yWidth = xWidth + Centre = 1 + xWidth \ 2 + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + D = SQR(((Centre - X) * (Centre - X)) + ((Centre - Y) * (Centre - Y))) + IF D < Centre THEN Grid(X, Y) = 150 + Colour * 2 + D * 3 + NEXT X + NEXT Y + + CASE 5: ' Ball + + + xWidth = 7 + 2 * RANDOM.INT(8) + yWidth = xWidth + Centre = 1 + xWidth \ 2 + sWidth = RANDOM.INT(xWidth) + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + D = SQR(((Centre - X) * (Centre - X)) + ((Centre - Y) * (Centre - Y))) + IF D < Centre AND D >= sWidth THEN Grid(X, Y) = 150 + Colour * 2 + D * 3 + NEXT X + NEXT Y + + END SELECT + + Img(Shape).xWidth = xWidth + Img(Shape).yWidth = yWidth + + A$ = STRING$(xWidth * yWidth, nil) + + c = 1 + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + MID$(A$, c, 1) = CHR$(Grid(X, Y)) + c = c + 1 + NEXT X + NEXT Y + + Img(Shape).ImgData = A$ + + + NEXT Shape + +END SUB + +SUB PAGE.DEMO + +CONST MaxSprites = 64 + +DIM Obj(MaxSprites) AS Sprite +DIM LastX(MaxSprites, 1), LastY(MaxSprites, 1) +DIM LastObjects(1) + + ScreenX = 360: ScreenY = 240 + + IF SET.VGA.MODEX%(Mode320x200, ScreenX, ScreenY, 3) = 0 THEN + ERROR.OUT "Unable to SET_VGA_MODEX" + STR$(Mode) + END IF + + SET.ACTIVE.PAGE 0 + + CLEAR.VGA.SCREEN c.BLACK + + PRINT.TEXT "This is a Test of the Following Functions:", 10, 9, c.bWHITE, c.BLACK + + DRAW.LINE 10, 18, 350, 18, c.YELLOW + PRINT.TEXT "SET_ACTIVE_PAGE", 10, 20, c.bBLUE, c.BLACK + PRINT.TEXT "SET_DISPLAY_PAGE", 10, 30, c.GREEN, c.BLACK + PRINT.TEXT "SET_DAC_REGISTER", 10, 40, c.RED, c.BLACK + PRINT.TEXT "CLEAR_VGA_SCREEN", 10, 50, c.CYAN, c.BLACK + + PRINT.TEXT "TDRAW_BITMAP", 10, 60, c.PURPLE, c.BLACK + PRINT.TEXT "COPY_PAGE", 10, 70, c.GREEN, c.BLACK + PRINT.TEXT "COPY_BITMAP", 10, 80, c.CYAN, c.BLACK + + PRINT.TEXT "GPRINTC", 10, 90, c.BLUE, c.BLACK + PRINT.TEXT "TGPRINTC", 10, 100, c.GREEN, c.BLACK + PRINT.TEXT "SET_WINDOW", 10, 110, c.RED, c.BLACK + + PRINT.TEXT "VIRTUAL SCREEN SIZES", 190, 20, c.bBLUE, c.BLACK + PRINT.TEXT " SMOOTH SCROLLING", 190, 30, c.GREEN, c.BLACK + PRINT.TEXT " SPRITE ANIMATION", 190, 40, c.CYAN, c.BLACK + PRINT.TEXT " PAGE FLIPPING", 190, 50, c.RED, c.BLACK + PRINT.TEXT " COLOR CYCLING", 190, 60, c.PURPLE, c.BLACK + + + FOR X = 0 TO 60 + SET.DAC.REGISTER 50 + X, 3 + X, 0, 60 - X + SET.DAC.REGISTER 150 + X, 3 + X, 0, 60 - X + NEXT X + + c = 0: DC = 1 + FOR X = 0 TO ScreenX \ 2 + DRAW.LINE ScreenX \ 2 - 1, ScreenY \ 4, X, ScreenY - 1, c + 50 + DRAW.LINE ScreenX \ 2, ScreenY \ 4, ScreenX - X - 1, ScreenY - 1, c + 50 + c = c + DC + IF c = 0 OR c = 60 THEN DC = -DC + NEXT X + + TPRINT.TEXT "Press to Continue", 72, 190, c.bWHITE + TPRINT.TEXT "< > = Faster < > = Slower", 72, 204, c.bGREEN + TPRINT.TEXT "< > = Fewer Shapes < > = More Shapes", 32, 218, c.bCYAN + + TGPRINTC 43, 80, 204, c.YELLOW + TGPRINTC 45, 200, 204, c.YELLOW + + TGPRINTC 25, 40, 218, c.YELLOW + TGPRINTC 24, 200, 218, c.YELLOW + + COPY.PAGE 0, 1 + COPY.PAGE 0, 2 + + FOR X = 1 TO MaxSprites + DO + Obj(X).XDir = RANDOM.INT(7) - 3 + Obj(X).YDir = RANDOM.INT(7) - 3 + LOOP WHILE (Obj(X).XDir = 0 AND Obj(X).YDir = 0) + + Obj(X).Shape = X MOD MaxShapes + + SpriteX = Img(Obj(X).Shape).xWidth + SpriteY = Img(Obj(X).Shape).yWidth + + Obj(X).Xpos = 1 + RANDOM.INT(ScreenX - SpriteX - 2) + Obj(X).Ypos = 1 + RANDOM.INT(ScreenY - SpriteY - 2) + + LastX(X, 0) = Obj(X).Xpos + LastX(X, 1) = Obj(X).Xpos + LastY(X, 0) = Obj(X).Ypos + LastY(X, 1) = Obj(X).Ypos + NEXT X + + CurrentPage = 0 + + 'View Shift... + + ViewX = 0 + ViewY = 0 + ViewMax = 3 + ViewCnt = 0 + ViewXD = 1 + ViewYD = 1 + + SetColor = 3: SDir = 1 + PrevColor = 0: PDir = 1 + + VisObjects = MaxSprites \ 2 + LastObjects(0) = 0 + LastObjects(1) = 0 + +DRAW.LOOP: + + + SET.ACTIVE.PAGE CurrentPage + + ' Erase Old Images + + FOR X = 1 TO LastObjects(CurrentPage) + + X1 = LastX(X, CurrentPage) AND &HFFFC + Y1 = LastY(X, CurrentPage) + X2 = ((LastX(X, CurrentPage) + Img(Obj(X).Shape).xWidth)) OR 3 + Y2 = Y1 + Img(Obj(X).Shape).yWidth - 1 + + COPY.BITMAP 2, X1, Y1, X2, Y2, CurrentPage, X1, Y1 + + NEXT X + + ' Draw new images + + FOR X = 1 TO VisObjects + + SpriteX = Img(Obj(X).Shape).xWidth + SpriteY = Img(Obj(X).Shape).yWidth + + ' Move Sprite + +REDOX: + NewX = Obj(X).Xpos + Obj(X).XDir + IF NewX < 0 OR NewX + SpriteX > ScreenX THEN + Obj(X).XDir = -Obj(X).XDir + IF RANDOM.INT(20) = 1 THEN + DO + Obj(X).XDir = RANDOM.INT(7) - 3 + Obj(X).YDir = RANDOM.INT(7) - 3 + LOOP WHILE (Obj(X).XDir = 0 AND Obj(X).YDir = 0) + GOTO REDOX + END IF + END IF + Obj(X).Xpos = Obj(X).Xpos + Obj(X).XDir + +REDOY: + NewY = Obj(X).Ypos + Obj(X).YDir + IF NewY < 0 OR NewY + SpriteY > ScreenY THEN + Obj(X).YDir = -Obj(X).YDir + IF RANDOM.INT(20) = 1 THEN + DO + Obj(X).XDir = RANDOM.INT(7) - 3 + Obj(X).YDir = RANDOM.INT(7) - 3 + LOOP WHILE (Obj(X).XDir = 0 AND Obj(X).YDir = 0) + GOTO REDOY + END IF + END IF + Obj(X).Ypos = Obj(X).Ypos + Obj(X).YDir + + 'Draw Sprite + + TDRAW.BITMAP Img(Obj(X).Shape), Obj(X).Xpos, Obj(X).Ypos, SpriteX, SpriteY + + LastX(X, CurrentPage) = Obj(X).Xpos + LastY(X, CurrentPage) = Obj(X).Ypos + + NEXT X + + LastObjects(CurrentPage) = VisObjects + + ' Pan Screen Back & Forth + + ViewCnt = ViewCnt + 1 + IF ViewCnt >= ViewMax THEN + ViewX = ViewX + ViewXD + IF ViewX = 0 OR ViewX = 39 THEN ViewXD = -ViewXD + IF ViewXD < 0 THEN + ViewY = ViewY + ViewYD + IF ViewY = 0 OR ViewY = 39 THEN ViewYD = -ViewYD + END IF + + SET.WINDOW CurrentPage, ViewX, ViewY + + ViewCnt = 0 + ELSE + SET.DISPLAY.PAGE CurrentPage + END IF + + ' Cycle Colors + + SET.DAC.REGISTER 50 + PrevColor, 3 + PrevColor, 0, 60 - PrevColor + SET.DAC.REGISTER 50 + SetColor, SetColor, 10, 63 - SetColor + + SET.DAC.REGISTER 150 + PrevColor, 3 + PrevColor, 0, 60 - PrevColor + SET.DAC.REGISTER 150 + SetColor, 63, 63, SetColor + + SetColor = SetColor + SDir + IF SetColor = 60 OR SetColor = 0 THEN SDir = -SDir + + PrevColor = PrevColor + PDir + IF PrevColor = 60 OR PrevColor = 0 THEN PDir = -PDir + + CurrentPage = 1 - CurrentPage + + Code = SCAN.KEYBOARD + + IF Code = False THEN GOTO DRAW.LOOP + + IF Code = KyPlus THEN + IF ViewMax < 12 THEN ViewMax = ViewMax + 1 + GOTO DRAW.LOOP + END IF + + IF Code = KyMinus THEN + IF ViewMax > 1 THEN ViewMax = ViewMax - 1 + IF ViewCnt >= ViewMax THEN ViewCnt = 0 + GOTO DRAW.LOOP + END IF + + IF Code = KyUp THEN + IF VisObjects < MaxSprites THEN VisObjects = VisObjects + 1 + GOTO DRAW.LOOP + END IF + + IF Code = KyDown THEN + IF VisObjects > 1 THEN VisObjects = VisObjects - 1 + GOTO DRAW.LOOP + END IF + + +END SUB + +SUB PRINT.TEXT (Text$, Xpos, Ypos, ColorF, ColorB) + + IF LEN(Text$) = 0 THEN EXIT SUB + PRINT.STR VARSEG(Text$), SADD(Text$), LEN(Text$), Xpos, Ypos, ColorF, ColorB + + +END SUB + +SUB TPRINT.TEXT (Text$, Xpos, Ypos, ColorF) + + IF LEN(Text$) = 0 THEN EXIT SUB + + TPRINT.STR VARSEG(Text$), SADD(Text$), LEN(Text$), Xpos, Ypos, ColorF + +END SUB + diff --git a/16/modex105/DEMOS/QB45/TEST6A.EXE b/16/modex105/DEMOS/QB45/TEST6A.EXE new file mode 100644 index 0000000000000000000000000000000000000000..e61d038796159e3fdb7d12c95525a9dafb87995f GIT binary patch literal 40544 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 + push R1 ; Save R1 + PUSHx R2, R3, R4, R5, R6, R7, R8 + ENDIF +ENDM + +POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + pop R1 ; Restore R1 + POPx R2, R3, R4, R5, R6, R7, R8 + ENDIF +ENDM + + ; Macro to Clear a Register to 0 + +CLR MACRO Register + xor Register, Register ; Set Register = 0 +ENDM + + ; Macros to Decrement Counter & Jump on Condition + +LOOPx MACRO Register, Destination + dec Register ; Counter-- + jnz Destination ; Jump if not 0 +ENDM + +LOOPjz MACRO Register, Destination + dec Register ; Counter-- + jz Destination ; Jump if 0 +ENDM + + + ; ==== General Constants ==== + + False EQU 0 + True EQU -1 + nil EQU 0 + + b EQU BYTE PTR + w EQU WORD PTR + d EQU DWORD PTR + o EQU OFFSET + f EQU FAR PTR + s EQU SHORT + ?x4 EQU + ?x3 EQU + + +IFDEF FARSTRINGS + + EXTRN stringaddress:far + EXTRN stringlength:far + +ENDIF + + + .Data + + EVEN + +RND_Seed DW 7397, 29447, 802 +RND_Mult DW 179, 183, 182 +RND_ModV DW 32771, 32779, 32783 + +CR_LF DB 13, 10 ; the CRLF data + + .Code + +;================= +;DOS_PRINT (Text$) +;================= +; +; Prints Text Directly to DOS console w/ CR/LF +; + + PUBLIC DOS_PRINT + +DP_Stack STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + DP_Text DW ? ; Address of Text$ Descriptor +DP_Stack ENDS + + +DOS_PRINT PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + mov SI, [BP].DP_Text ; Get Addr of Text$ descriptor + +IFDEF FARSTRINGS + push SI ; Push Addr of BC7 Decriptor Ptr + call stringaddress ; Get Address + Len of string!!! + ; DX:AX = Addr CX = Len + mov DS, DX ; DS = DX = Segment of string + mov DX, AX ; DX = AX = Offset of String +ELSE + mov CX, [SI] ; put its length into CX + mov DX, [SI+02] ; now DS:DX points to the String +ENDIF + + jcxz @No_Print ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@No_Print: + mov AX, SEG DGROUP ; Restore DGroup + mov DS, AX + + mov DX, o CR_LF ; Get Addr of CR/LF pair + mov CX, 2 ; 2 Characters to Write + mov BX, 1 ; 1= DOS Handle for Display + + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +DOS_PRINT ENDP + + +;================== +;DOS_PRINTS (Text$) +;================== +; +; Print Text$ Directly to DOS console +; without a trailing CR/LF +; + + PUBLIC DOS_PRINTS + +DOS_PRINTS PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + mov SI, [BP].DP_Text ; Get Addr of Text$ descriptor + +IFDEF FARSTRINGS + push SI ; Push Addr of BC7 Decriptor Ptr + call stringaddress ; Get Address + Len of string!!! + ; DX:AX = Addr CX = Len + mov DS, DX ; DS = DX = Segment of string + mov DX, AX ; DX = AX = Offset of String +ELSE + mov CX, [SI] ; put its length into CX + mov DX, [SI+02] ; now DS:DX points to the String +ENDIF + + jcxz @DPS_Exit ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@DPS_Exit: + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +DOS_PRINTS ENDP + + +;====================== +;SET_VIDEO_MODE (Mode%) +;====================== +; +; Sets the Video Mode through the BIOS +; + + PUBLIC SET_VIDEO_MODE + +SVM_Stack STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + SVM_Mode DB ?,? ; Desired Video Mode +SVM_Stack ENDS + + +SET_VIDEO_MODE PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + CLR AH ; Function 0 + mov AL, [BP].SVM_Mode ; Get Mode # + + int 10H ; Change Video Modes + +@SVM_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +SET_VIDEO_MODE ENDP + + +;============== +;SCAN_KEYBOARD% +;============== +; +; Function to scan keyboard for a pressed key +; + + PUBLIC SCAN_KEYBOARD + +SCAN_KEYBOARD PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + + mov AH, 01H ; Function #1 + int 16H ; Call Keyboard Driver + jz @SK_NO_KEY ; Exit if Zero flag set + + mov AH, 00H ; Remove Key from Buffer + int 16H ; Get Keycode in AX + + or AL, AL ; Low Byte Set (Ascii?) + jz @SK_Exit ; if not, it's a F-Key + + CLR AH ; Clear ScanCode if Ascii + jmp s @SK_Exit ; Return Key in AX + +@SK_NO_KEY: + CLR AX ; Return Nil (no Keypress) + +@SK_Exit: + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret ; Exit & Clean Up Stack + +SCAN_KEYBOARD ENDP + + +;==================== +;RANDOM_INT (MaxInt%) +;==================== +; +; Returns a pseudo-random number in the range of (0.. MaxInt-1) +; + + + PUBLIC RANDOM_INT + +RI_Stack STRUC + DW ? ; BP + DD ? ; Caller + RI_MaxVal DW ? ; Maximum Value to Return + 1 +RI_Stack ENDS + + +RANDOM_INT PROC FAR + + push BP ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + CLR BX ; BX is the data index + CLR CX ; CX is the accumulator + +REPT 3 + mov AX, RND_Seed[BX] ; load the initial seed + mul RND_Mult[BX] ; multiply it + div RND_ModV[BX] ; and obtain the Mod value + mov RND_Seed[BX], DX ; save that for the next time + + add CX, DX ; add it into the accumulator + inc BX + inc BX ; point to the next set of values +ENDM + + mov AX, CX ; AX = Random # + CLR DX ; DX = 0 + div [BP].RI_MaxVal ; DX = DX:AX / MAxVal Remainder + + mov AX, DX + + pop BP ; Restore BP + ret 2 ; back to BASIC with AX holding the result + +RANDOM_INT ENDP + + +;=========== +;INIT_RANDOM +;=========== +; +; Scrambles the psuedo-random number sequence +; (XOR's the seed value with the timer) +; + + PUBLIC INIT_RANDOM + +INIT_RANDOM PROC FAR + + clr AX ; Segment = 0000 + mov ES, AX + mov AX, ES:[046Ch] ; Get Timer Lo Word + + xor RND_Seed, AX ; Scramble 1st Seed + + ret ; Exit & Clean Up Stack + +INIT_RANDOM ENDP + + +;==================== +;INT_SQR (X%, Round%) +;==================== +; +; Returns the Integer Square Root of (X) +; Round allows the return value to be rounded to the +; nearest integer value by passing 0x80. Passing 0 +; return the Integer Portion only. The rounding amound is +; a number from 0 to 1 multiplied by 256, thus +; 0.5 * 0x100 = 0x80! +; + +ISQ_Stack STRUC + DW ?,? ; BP, DI + DD ? ; Caller + ISQ_Round DW ? ; Amount to Round Result * 256 + ISQ_X DW ? ; "X" +ISQ_Stack ENDS + + PUBLIC INT_SQR + +INT_SQR PROC FAR + + PUSHx BP, DI ; Save BP + mov BP, SP ; Set up Stack Frame + + xor AX, AX ; {xor eax,eax} + xor DX, DX ; {xor edx,edx} + mov DI, [BP].ISQ_X ; {mov edi,x} + + mov CX, 16 ; {mov cx, 32} + +@ISQ_L: + + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl AX, 1 ; {shl eax,1} + mov BX, AX ; {mov ebx,eax} + shl BX, 1 ; {shl ebx,1} + inc BX ; {inc ebx} + cmp DX, BX ; {cmp edx,ebx} + jl @ISQ_S + + sub DX, BX ; {sub edx,ebx} + inc AX ; {inc eax} + +@ISQ_S: + loop @ISQ_L + + add ax, [BP].ISQ_Round ; {add eax,$00008000} + ; {*round* result in hi word: ie. +0.5} + shr ax, 8 ; {shr eax,16} {to ax (result)} + + POPx DI, BP ; Restore Registers + ret 4 ; Exit + +INT_SQR ENDP + + +;============ +;TIMER_COUNT& +;============ +; +; Returns the current timer value as an integer/long integer +; + + + PUBLIC TIMER_COUNT + +TIMER_COUNT PROC FAR + + clr AX ; Segment = 0000 + mov ES, AX ; use ES to get at data + mov AX, ES:[046Ch] ; Get Timer Lo Word + mov DX, ES:[046Eh] ; Get Timer Hi Word + ret ; Exit & Return value in DX:AX + +TIMER_COUNT ENDP + + + END diff --git a/16/modex105/DEMOS/QB45/UTILS.BI b/16/modex105/DEMOS/QB45/UTILS.BI new file mode 100644 index 00000000..aeafeef4 --- /dev/null +++ b/16/modex105/DEMOS/QB45/UTILS.BI @@ -0,0 +1,51 @@ + + ' Misc Constants + +CONST True = -1, False = 0, nil = 0 + + ' Keyboard Codes: Extended + +CONST KyF1 = &H3B00, KyF2 = &H3C00, KyF3 = &H3D00, KyF4 = &H3E00, KyF5 = &H3F00 +CONST KyF6 = &H4000, KyF7 = &H4100, KyF8 = &H4200, KyF9 = &H4300, KyF10 = &H4400 + +CONST KyUp = &H4800, KyLeft = &H4B00, KyRight = &H4D00, KyDown = &H5000 +CONST KySLeft = &HCB00, KySRight = &HCD00, KySUp = &HC800, KySDown = &HD000 + +CONST KyHome = &H4700, KyPgUp = &H4900, KyEnd = &H4F00, KyPgDn = &H5100 +CONST KySHome = &HC700, KySPgUp = &HC900, KySEnd = &HCF00, KySPgDn = &HD100 + +CONST KyIns = &H5200, KyDel = &H5300, KyRvsTab = &H8F00 +CONST KySIns = &HC200, KySDel = &HC300 + +CONST KyAltA = &H1E00, KyAltB = &H3000, KyAltC = &H2E00, KyAltD = &H2000 +CONST KyAltE = &H1200, KyAltF = &H2100, KyAltG = &H2200, KyAltH = &H2300 +CONST KyAltI = &H1700, KyAltJ = &H2400, KyAltK = &H2500, KyAltL = &H2600 +CONST KyAltM = &H3200, KyAltN = &H3100, KyAltO = &H1800, KyAltP = &H1900 +CONST KyAltQ = &H1000, KyAltR = &H1300, KyAltS = &H1F00, KyAltT = &H1400 +CONST KyAltU = &H1600, KyAltV = &H2F00, KyAltW = &H1100, KyAltX = &H2D00 +CONST KyAltY = &H1500, KyAltZ = &H2C00 + + ' Keyboard Codes: Ascii + +CONST KyBS = 8, KyTab = 9, KyCR = 13, KyESC = &H1B, KyClr = &H7F +CONST KyPlus = 45, KyMinus = 43 + + ' Color Constants + +CONST c.BLACK = 0, c.BLUE = 1, c.GREEN = 2, c.CYAN = 3 +CONST c.RED = 4, c.PURPLE = 5, c.BROWN = 6, c.WHITE = 7 +CONST c.GREY = 8, c.bBLUE = 9, c.bGREEN = 10, c.bCYAN = 11 +CONST c.bRED = 12, c.bPURPLE = 13, c.YELLOW = 14, c.bWHITE = 15 +CONST c.BRIGHT = 8 + + ' From UTILS.ASM + +DECLARE SUB DOS.PRINT ALIAS "DOS_PRINT" (Text$) +DECLARE SUB DOS.PRINTS ALIAS "DOS_PRINTS" (Text$) +DECLARE SUB SET.VIDEO.MODE ALIAS "SET_VIDEO_MODE" (BYVAL Mode%) +DECLARE FUNCTION SCAN.KEYBOARD% ALIAS "SCAN_KEYBOARD" +DECLARE FUNCTION RANDOM.INT ALIAS "RANDOM_INT" (BYVAL MaxInt%) +DECLARE SUB INIT.RANDOM ALIAS "INIT_RANDOM" +DECLARE FUNCTION TIMER.COUNT& ALIAS "TIMER_COUNT" +DECLARE FUNCTION INT.SQR ALIAS "INT_SQR" (BYVAL X%, BYVAL Round%) + diff --git a/16/modex105/DEMOS/ROM_8X8.FNT b/16/modex105/DEMOS/ROM_8X8.FNT new file mode 100644 index 0000000000000000000000000000000000000000..708a4f924815cedc3c5e179b42a7cc9d9c492625 GIT binary patch literal 1024 zcmYLIv1%hR5FJwF8j-jZ*rdt_40l(kSRBY_q!RI=OQFJ*5!~J;?(YN6A8>zgZD7H$ zl}MQ;#%yJGAywF7(cT+v;KsRcaNHt(pu$~WyMl)8=J9c}9nL?U|BNw)!Z}yyN?(1sVqU(r_lx_* z;`^cA+!V)SakF`7yVSK0baFON^RpA6R$5nu#x>{2(f!NIkLh$u^M&!=#30pHRh8oq zHspA%Nkd?xER_@#u}zjGx~}U4b?F9o35^S=RtnGI*k$1mn2E`IpKb3GexA6jgX#d( zM9r=tTkt=Yl`K+UPLB$(m&}q! zOTT5a-|y={41hjH>YXc{>oHF7hIw`#bMPId+q-agn?`Nl^7)gS6K0HSk-#1#(1k*o zsOR8(@a`b&LwagnQ+jS1Y7X!FCurlFrtv1{v%o|8xC^sv%e@fWVQK3c#zL2$y)^hxh42f59a)vzx6a@ZkcEDUF0PO NT(pwbM1+VY(Lc=|finOA literal 0 HcmV?d00001 diff --git a/16/modex105/DEMOS/SPACEAGE.FNT b/16/modex105/DEMOS/SPACEAGE.FNT new file mode 100644 index 0000000000000000000000000000000000000000..029bae4effb181a29f61b17c588cd848bc04e82a GIT binary patch literal 1024 zcmYLHJ!|7Y5SbOEUxqr5pFqLs>t~iV;RY!1j zs1T!jZ)J0X<+nTE^JYaBxj=YYL5MSiNTH5);!SAhnReQ4LLJYv6KTJliL?`M0<-sY zlBTX3z-|rM$^0|Re0Tq_dU}1IKT>}gC!1%R#!H_*=J(g9)x-T=89OV>Qc7Q0<$+~s zT?B^K+E5~)uWJ_Y^?HqizX~+}2c+5i7$wSfTjM6OHRDgBC36-M>lO%e$Zv$loio%!zj=P}rObnQjD6ug80Nsfe_-MHKA77r{sZ_H5+LHR z+TvT2QYL`;Fy2UiFu>AN=7IUiA5jg2X2e2eWB~Ob0QN8~c`@PQf5`LWp@9I#X99p= h7cUiYAi$&vVG}~bcO~qr4Z(-d%J<)JrH}|U`3JE0#Z>?R literal 0 HcmV?d00001 diff --git a/16/modex105/DEMOS/SYSTEM.FNT b/16/modex105/DEMOS/SYSTEM.FNT new file mode 100644 index 0000000000000000000000000000000000000000..9a1965ebfe5bd67bea71c313ef7ef2f78aa6fbb7 GIT binary patch literal 1024 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 Ix?}Ob0HE06asU7T literal 0 HcmV?d00001 diff --git a/16/modex105/FONTEDIT/CHARSETS.CS b/16/modex105/FONTEDIT/CHARSETS.CS new file mode 100644 index 0000000000000000000000000000000000000000..97fe608ff81e4b78105a52984687b21a8a166ff7 GIT binary patch literal 2144 zcmZuxJ!l+96n;6MS4UXnt-=-}41|Eng%sK1kQZ45l?FE{#|SwoHp$@#voXtha@dX{ zQYfmTCagt@!<7qF0>fazkYW)cg-{{Pq!F&fRpE+dlJCu4ehhhcyPv){@Bht-sFQSU z?`Ur=rF3mP9s`G~&wl*=$?EXx>WcWGqImeQw?g*Kn|B$j<8L9yRdu}o^5y<<<={3R zJ91BVemh_^&-b1i&-V^qIlB4L%_JF3?W2uH8ylZp>f!4Cv;EZ}DLZpBtEjiQ;#L-W z6c4L7u75%mXAG#CsbTFza*OjM2!4p3-Wj(2t#=j~I%LJ8fw*LYP9bC>57Rj1{9ZA7Mt z6KS4Onx_vgng8 z5ChN7E_A{E#u-DcG5iJBS|ct9q$P*ET4SFcHJ_hw-p*IT;K*e|=JU&VGnr1~~8H#+(P@Jm%Ot$eFuBJd>w6;$lt( zZ_xR{Vt$gPB+U&6Ju11bu*7}I%|Ck}`V-5W(=w<`MO-ZROI!i+W5yLm>$%e<4W%p) z7`$kjGQ>J~AGk9ZCWI)&)d=%cYd-+8T!t)QpYs5Kexkqot2Z4Fs z`R41b%`e0!UwyeH{!fS&ZY*{lZ@m|a$Iauzf)uuYju0V`tBS9351aLIx zKoYE`puPCvqHV#G^>wrnw9VmR)6&9HxV5`0DPT3nNkt;8{TC0{5AmfyPur=6UpQ=s zxYo!wnILk%u4}5ni%GGJ-#Ow4ghL)og!7>;E{stKtVwWvI2Xw*@hE4KQLFRa)0hVH z{}+J}BY08(?-3mP)Jab%MT$7DR|L0b_`tuYN6S;-uczYEpKvZ!rX1M!Z2JyuC%E7IvA=GDa(`>QD+soN|ACXgvqk-8t6F z`g+b`2YrteKAa~bA0JsVwj+xV5RCQLr_l%|@VE1Ph*N`Wpk_V#vYyv-u06L(E9KAY zn$Pj}eir>RM^&{1s#<$J!mwX3n@lF#&_nC>86X2k^*$bR_5;^75OWrqIpVS%j_3Kj zU$BjM*bnsZ?9kg;v}e&js#Nd~5GEQhM;P#a24hIyzo+2B|8*@NyU3c zKhoDl(t4iF`zI7CEZbYo-&2HyY)=?K#(E3@obyW5K^Oq{Pa2IdqU?;31F1O*Ao42S zpH^MH76I4}Zg!5~0c~&l{;AHgn)NV{g3yP^a9{fpdzW07LSf8BB*6Q(VGO|>EaR=u c@7}+=v9)<$+}Yd`AAF4Uy(KWY!FGSkU-|#d0ssI2 literal 0 HcmV?d00001 diff --git a/16/modex105/FONTEDIT/CSEDIT.DOC b/16/modex105/FONTEDIT/CSEDIT.DOC new file mode 100644 index 00000000..97ff07e0 --- /dev/null +++ b/16/modex105/FONTEDIT/CSEDIT.DOC @@ -0,0 +1,196 @@ + +CSEDIT - A Simple Font Editor by Matt Pritchard + + +CSEDIT is distributed with MODEXnnn.ZIP, the general purpose MODE X +Library for VGA Graphics. + +WHAT YOU NEED TO RUN CSEDIT: + + * A Vga Monitor + * A Microsoft Compatible Mouse + + A Mouse is most definitely required, as the keyboard is used for + nothing except entering file names. + +FILES NEEDED IN THE CURRENT DIRECTORY: + + CSEDIT.EXE - The Font Editor Program + CHARSETS.CS - The Font Editor's Internal Fonts + PALETTE.CS - The Font Editor's Palette + MOUSEIMG.CS - The Font Editor's Mouse Pointer + +SAMPLE FONT FILE THAT SHOULD BE INCLUDED: + + SYSTEM.FNT - The Font used by CSEDIT.EXE + INVERSE.FNT - An Inverted version of SYSTEM.FNT + SPACEAGE.FNT - A Futuristic, Tech style font + ROM_8X8.FNT - The Lower 128 characters from the VGA BIOS Rom + +WHAT IT EDITS: + + 8 by 8 character fonts, 128 characters at a time. 2 fonts at a time. + +HOW IT WORKS/FEATURES: + + CSEDIT allows the user to edit 2 different font groups at a time, + which may be loaded and saved separately. + + A enlarged character grid allows the user to edit individual pixels + on a selected character. + + The Following operations can be performed on a single character or + simultaneously on a selected block of characters. + + * Shift the selected character(s) in any direction + with or without clipping at the edges. + * Vertically Flip the selected character(s) + * Horizontally Flip the selected character(s) + * Rotate the selected character(s) 90 Degrees Clockwise + * Rotate the selected character(s) 90 Degrees Counterclockwise + * Clear the selected character(s) + * Invert the selected character(s) + * XOR the selected character(s) with other character(s) + * AND the selected character(s) with other character(s) + * OR the selected character(s) with other character(s) + * Copy the selected character(s) to another position or font. + + An UNDO feature allows the reversal of the most recent operation. + +DESCRIPTION OF OBJECTS/FEATURES FROM THE TOP DOWN: + + Character Grid: (RED) Box in Upper Left corner of screen. This is + where you edit an individual character. The Left Button sets the + pixel the mouse pointer is on, while the Right Button clears that + pixel. + + Scroll Buttons: The Four Scroll Buttons are labeled with directional + arrows, and arranged in a diamond pattern. Left Clicking on a + directional button will scroll the currently selected character + in that direction, with the pixels on the edge rolling off and + appearing on the other size. Right Clicking will prevent the + pixels from rolling to the other side. + + Vertical Flip Button: + Horizontal Flip Button: Clicking these buttons will flip the pattern + of the currently selected character(s) around the indicated axis. + i.e. the top row will be swapped with the bottom row, etc. or the + left row column will be swapped with right column, etc. + depending upon which button you push. + + Invert Button: Clicking this button causes all pixels in the selected + character(s) to flip flop between on and off. + + Clear Button: Clicking this button erases the selected characters + + Rotate Buttons: Clicking these buttons will rotate the pattern in the + selected character(s) 90 degrees in the indicated direction. + + XOR Button: Clicking this button will let you XOR the currently + selected character(s) with other character(s) in either font. + The Button will turn RED, indicating that it is waiting for + you to click on the desired character (or upper left corner + of the desired block of characters) in either the Red or Green + Character Set Displays. Clicking anywhere else will abort this + process without doing anything. If you click on (any of) the + selected character(s) the operation is aborted. If a block is + selected and the character you click on is in a position where + it can't represent the upper left corner of a block of the same + size, then the operation is not performed. + + AND Button & OR Button: These buttons work just like the XOR Button + except that the Binary operation performed is either an AND or OR + depending upon which button you have selected. + + COPY Button: This button lets you copy a character or selected block + of characters to another area in the current font or the other + font. After clicking, the button turns RED and works much like + the XOR Button. Clicking on a valid position in either font + window will copy the selected character(s) to that location. + + MODE Button: Clicking this button toggles the editor between BLOCK + mode and CHARACTER mode. The current mode is displayed on a plate + at the top of the screen, just to the right of the enlarged + character grid. In character mode the plate will read "CHAR" and + the currently selected character is displayed just to the right + of the plate. In Block mode the plate will read "BLOCK" and the + enlarged character grid is disabled. + + UNDO Button: Clicking this Button will UNDO or reverse the effects of + the most recent operation. + + QUIT Button: Clicking this button will return you to DOS. Any loaded + fonts are not saved, and no confirmation is given. + + + GREEN FONT AREA: This area displays one of the current fonts which + can be edited. The characters are display in order from #0 to #127 + from the upper left, going right, then down. The Font Box is 32 + characters wide and 4 characters Tall. When the editor is in + character mode, just point at and Left Click on the character you + wish to edit and a Cyan box will appear around that character. + + * If you Right Click on a character, the last current character, + which will still appear in the enlarged character grid, will be + copied onto the character you pointed at, replacing it. This is + a shortcut for copying characters: You can hold the right button + down an fill in a large area with a single character pattern. + When the editor is in Block Mode, you select an area by clicking + on any corner of the desired block. Then drag the mouse to the + opposite corner while holding down the left button. A Cyan Box + will stretch to surround the selected block of characters. + + GREEN FONT FILE NAME BOX: This Text Box is used to enter the name + of a font file to load or the name to save the current Green font + as. Just click on the Box, and it will change color and a + flashing cursor will appear. Now you type in a filename or edit + the existing filename. Press or click outside the text + box to end editing. + + GREEN FONT LOAD BUTTON: Clicking this button will load the font file + that is named in the Green File name box. If no name is given or + no such file exists, then nothing will be loaded. + + GREEN FONT SAVE BUTTON: Clicking this button will save the current + font in the Green Font Area under the name given in the File Name + Box. If a Valid name is not provided, nothing will be saved. + + RED FONT AREA: This is just the same as the GREEN FONT AREA; providing + you with the ability to copy and edit between multiple fonts. + + RED FONT FILE NAME BOX: This works just like the GREEN FONT FILE + NAME BOX. + + RED FONT LOAD BUTTON: This works just like the GREEN FONT LOAD BUTTON. + + RED FONT SAVE BUTTON: This works just like the GREEN FONT SAVE BUTTON. + + Message Bar: At the very bottom of the screen, this Bar will display + information and messages for various functions. + + +FONT FILE FORMAT: + + BINARY Image, in order of character. The format is identical to that + used by the VGA ROM. The Files will be exactly 1024 (128 * 8) bytes + long. + + CHARACTER: 8 Bytes + + FONT: Array (0 to 127) of CHARACTER + + +COMMENTS, QUESTIONS, BUG REPORTS, etc: + + Send the to the Author: Matt Pritchard + + Through the 80xxx Fidonet Echo or + + Matt Pritchard + P.O. Box 140264 + Irving, TX 75014 + +CREDITS: + + This Font Editor was written in QuickBASIC 4.5 + diff --git a/16/modex105/FONTEDIT/CSEDIT.EXE b/16/modex105/FONTEDIT/CSEDIT.EXE new file mode 100644 index 0000000000000000000000000000000000000000..58b073253ada69b3f089a2f3b359049195178db6 GIT binary patch literal 68368 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 literal 0 HcmV?d00001 diff --git a/16/modex105/FONTEDIT/PALETTE.CS b/16/modex105/FONTEDIT/PALETTE.CS new file mode 100644 index 0000000000000000000000000000000000000000..09c5549e4967dcb520ae894bd5116c0b530b4304 GIT binary patch literal 768 zcmZva!HUBm5J2Y=2%RO`noI*WHGwcK1qscTHe1-8|NpDio)pxF%6pnq0K&M13AbBZ z!q&xO7l(w|iNxizg=4r~RaITrh}bmEe!p+qw(tAX=`@bxJkQtb)qB6L>$Yv5`=UV{ z$O7SUU=eTvI(#S%i7f}`l?a`0a6UY=gwUL^7s{}g|hJS4Up z0C)#%fCpfX3=D>0$9YI>IT*u7!-L_;Fh?df1Dhk~A+hCPEuSq8G#Fm3nq!k?$b&4p`kvfpll!wHY YgKmDmA2t3h8~nUSZ1J&%-%)-20~L%`_y7O^ literal 0 HcmV?d00001 diff --git a/16/modex105/FONTEDIT/ROM_8X8.FNT b/16/modex105/FONTEDIT/ROM_8X8.FNT new file mode 100644 index 0000000000000000000000000000000000000000..708a4f924815cedc3c5e179b42a7cc9d9c492625 GIT binary patch literal 1024 zcmYLIv1%hR5FJwF8j-jZ*rdt_40l(kSRBY_q!RI=OQFJ*5!~J;?(YN6A8>zgZD7H$ zl}MQ;#%yJGAywF7(cT+v;KsRcaNHt(pu$~WyMl)8=J9c}9nL?U|BNw)!Z}yyN?(1sVqU(r_lx_* z;`^cA+!V)SakF`7yVSK0baFON^RpA6R$5nu#x>{2(f!NIkLh$u^M&!=#30pHRh8oq zHspA%Nkd?xER_@#u}zjGx~}U4b?F9o35^S=RtnGI*k$1mn2E`IpKb3GexA6jgX#d( zM9r=tTkt=Yl`K+UPLB$(m&}q! zOTT5a-|y={41hjH>YXc{>oHF7hIw`#bMPId+q-agn?`Nl^7)gS6K0HSk-#1#(1k*o zsOR8(@a`b&LwagnQ+jS1Y7X!FCurlFrtv1{v%o|8xC^sv%e@fWVQK3c#zL2$y)^hxh42f59a)vzx6a@ZkcEDUF0PO NT(pwbM1+VY(Lc=|finOA literal 0 HcmV?d00001 diff --git a/16/modex105/FONTEDIT/SPACEAGE.FNT b/16/modex105/FONTEDIT/SPACEAGE.FNT new file mode 100644 index 0000000000000000000000000000000000000000..029bae4effb181a29f61b17c588cd848bc04e82a GIT binary patch literal 1024 zcmYLHJ!|7Y5SbOEUxqr5pFqLs>t~iV;RY!1j zs1T!jZ)J0X<+nTE^JYaBxj=YYL5MSiNTH5);!SAhnReQ4LLJYv6KTJliL?`M0<-sY zlBTX3z-|rM$^0|Re0Tq_dU}1IKT>}gC!1%R#!H_*=J(g9)x-T=89OV>Qc7Q0<$+~s zT?B^K+E5~)uWJ_Y^?HqizX~+}2c+5i7$wSfTjM6OHRDgBC36-M>lO%e$Zv$loio%!zj=P}rObnQjD6ug80Nsfe_-MHKA77r{sZ_H5+LHR z+TvT2QYL`;Fy2UiFu>AN=7IUiA5jg2X2e2eWB~Ob0QN8~c`@PQf5`LWp@9I#X99p= h7cUiYAi$&vVG}~bcO~qr4Z(-d%J<)JrH}|U`3JE0#Z>?R literal 0 HcmV?d00001 diff --git a/16/modex105/FONTEDIT/SYSTEM.FNT b/16/modex105/FONTEDIT/SYSTEM.FNT new file mode 100644 index 0000000000000000000000000000000000000000..9a1965ebfe5bd67bea71c313ef7ef2f78aa6fbb7 GIT binary patch literal 1024 zcmYjPv1%JZ5PcEm5aBRag)K}-6L5KuW{X1(ia+GQkTh4gGKX2#%0V3BF6z_-EK>Os z1ct?etqu`V2p7gEjd3Mh1sBIAZ&oH`(CIO|J8x#*46rf1Kc0>EHS~VdG{ji+(@pq+oD&8?kJE-xo@8yMC!0paxQ=Ty*Nj4yoj$J48Ty*GP# ze)zCDIXF2u_;BZn;pBWWEHGL zCiv7oaxvt1|Gte!6`zNyLS}!M7hMM5s=V~4(3L*AX^)VmD!xk<<5UWMJj#Je2VL=s zU8v0yki6tchyn7)OzbN!-3Z3}rS}F(E1IP*7lD}UBs_21Hjo*ebB}3Tqb9b*;1e;4 zm!F_b61GF`|GrY#q`sJ*6^O$l;b#YmxLn@2TH<~19-a5{qwky}FCAKkz`V|Jo)Mkg zFC_0K%!AFw`d_kGsnfUD57(^+S!f;nI4wE_}=<@sf-WqJO)v(U&;#n}qip zUL|>GA!5b3(^-Z!`Fy1-@=~W-CK#fy)UOmXaMEzngOR#Y!+ojzzc~PZIJ_sU8jcVcNPyf^0GVeOHxtq!b&Xha#_W6, ; If DX not setup + MOV DX, Register ; then Select Register + ENDIF + IFDIFI , ; If AX not setup + MOV AX, Value ; then Get Data Value + ENDIF + OUT DX, AX ; Set I/O Register(s) +ENDM + + ; Macro to OUT a 8 bit value to an I/O Port + +OUT_8 MACRO Register, Value + IFDIFI , ; If DX not setup + MOV DX, Register ; then Select Register + ENDIF + IFDIFI , ; If AL not Setup + MOV AL, Value ; then Get Data Value + ENDIF + OUT DX, AL ; Set I/O Register +ENDM + + ; macros to PUSH and POP multiple registers + +PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + PUSH R1 ; Save R1 + PUSHx R2, R3, R4, R5, R6, R7, R8 + ENDIF +ENDM + +POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + POP R1 ; Restore R1 + POPx R2, R3, R4, R5, R6, R7, R8 + ENDIF +ENDM + + ; Macro to Clear Registers to 0 + +CLR MACRO Register, R2, R3, R4, R5, R6 + IFNB + XOR Register, Register ; Set Register = 0 + CLR R2, R3, R4, R5, R6 + ENDIF +ENDM + + ; Macros to Decrement Counter & Jump on Condition + +LOOPx MACRO Register, Destination + DEC Register ; Counter-- + JNZ Destination ; Jump if not 0 +ENDM + +LOOPjz MACRO Register, Destination + DEC Register ; Counter-- + JZ Destination ; Jump if 0 +ENDM + + + ; ===== General Constants ===== + + False EQU 0 + True EQU -1 + nil EQU 0 + + b EQU BYTE PTR + w EQU WORD PTR + d EQU DWORD PTR + o EQU OFFSET + f EQU FAR PTR + s EQU SHORT + ?x4 EQU + ?x3 EQU + + ; ===== VGA Register Values ===== + + VGA_Segment EQU 0A000h ; Vga Memory Segment + + ATTRIB_Ctrl EQU 03C0h ; VGA Attribute Controller + GC_Index EQU 03CEh ; VGA Graphics Controller + SC_Index EQU 03C4h ; VGA Sequencer Controller + SC_Data EQU 03C5h ; VGA Sequencer Data Port + CRTC_Index EQU 03D4h ; VGA CRT Controller + CRTC_Data EQU 03D5h ; VGA CRT Controller Data + MISC_OUTPUT EQU 03C2h ; VGA Misc Register + INPUT_1 EQU 03DAh ; Input Status #1 Register + + DAC_WRITE_ADDR EQU 03C8h ; VGA DAC Write Addr Register + DAC_READ_ADDR EQU 03C7h ; VGA DAC Read Addr Register + PEL_DATA_REG EQU 03C9h ; VGA DAC/PEL data Register R/W + + PIXEL_PAN_REG EQU 033h ; Attrib Index: Pixel Pan Reg + MAP_MASK EQU 002h ; Sequ Index: Write Map Mask reg + READ_MAP EQU 004h ; GC Index: Read Map Register + START_DISP_HI EQU 00Ch ; CRTC Index: Display Start Hi + START_DISP_LO EQU 00Dh ; CRTC Index: Display Start Lo + + MAP_MASK_PLANE1 EQU 00102h ; Map Register + Plane 1 + MAP_MASK_PLANE2 EQU 01102h ; Map Register + Plane 1 + ALL_PLANES_ON EQU 00F02h ; Map Register + All Bit Planes + + CHAIN4_OFF EQU 00604h ; Chain 4 mode Off + ASYNC_RESET EQU 00100h ; (A)synchronous Reset + SEQU_RESTART EQU 00300h ; Sequencer Restart + + LATCHES_ON EQU 00008h ; Bit Mask + Data from Latches + LATCHES_OFF EQU 0FF08h ; Bit Mask + Data from CPU + + VERT_RETRACE EQU 08h ; INPUT_1: Vertical Retrace Bit + PLANE_BITS EQU 03h ; Bits 0-1 of Xpos = Plane # + ALL_PLANES EQU 0Fh ; All Bit Planes Selected + CHAR_BITS EQU 0Fh ; Bits 0-3 of Character Data + + GET_CHAR_PTR EQU 01130h ; VGA BIOS Func: Get Char Set + ROM_8x8_Lo EQU 03h ; ROM 8x8 Char Set Lo Pointer + ROM_8x8_Hi EQU 04h ; ROM 8x8 Char Set Hi Pointer + + ; Constants Specific for these routines + + NUM_MODES EQU 8 ; # of Mode X Variations + + ; Specific Mode Data Table format... + +Mode_Data_Table STRUC + M_MiscR DB ? ; Value of MISC_OUTPUT register + M_Pages DB ? ; Maximum Possible # of pages + M_XSize DW ? ; X Size Displayed on screen + M_YSize DW ? ; Y Size Displayed on screen + M_XMax DW ? ; Maximum Possible X Size + M_YMax DW ? ; Maximum Possible Y Size + M_CRTC DW ? ; Table of CRTC register values +Mode_Data_Table ENDS + + ; ===== DGROUP STORAGE NEEDED (42 BYTES) ===== + + .DATA? + +SCREEN_WIDTH DW 0 ; Width of a line in Bytes +SCREEN_HEIGHT DW 0 ; Vertical Height in Pixels + +LAST_PAGE DW 0 ; # of Display Pages +PAGE_ADDR DW 4 DUP (0) ; Offsets to start of each page + +PAGE_SIZE DW 0 ; Size of Page in Addr Bytes + +DISPLAY_PAGE DW 0 ; Page # currently displayed +ACTIVE_PAGE DW 0 ; Page # currently active + +CURRENT_PAGE DW 0 ; Offset of current Page +CURRENT_SEGMENT DW 0 ; Segment of VGA memory + +CURRENT_XOFFSET DW 0 ; Current Display X Offset +CURRENT_YOFFSET DW 0 ; Current Display Y Offset + +CURRENT_MOFFSET DW 0 ; Current Start Offset + +MAX_XOFFSET DW 0 ; Current Display X Offset +MAX_YOFFSET DW 0 ; Current Display Y Offset + +CHARSET_LOW DW 0, 0 ; Far Ptr to Char Set: 0-127 +CHARSET_HI DW 0, 0 ; Far Ptr to Char Set: 128-255 + + .CODE + + ; ===== DATA TABLES ===== + + ; Data Tables, Put in Code Segment for Easy Access + ; (Like when all the other Segment Registers are in + ; use!!) and reduced DGROUP requirements... + + ; Bit Mask Tables for Left/Right/Character Masks + +Left_Clip_Mask DB 0FH, 0EH, 0CH, 08H + +Right_Clip_Mask DB 01H, 03H, 07H, 0FH + + ; Bit Patterns for converting character fonts + +Char_Plane_Data DB 00H,08H,04H,0CH,02H,0AH,06H,0EH + DB 01H,09H,05H,0DH,03H,0BH,07H,0FH + + ; CRTC Register Values for Various Configurations + +MODE_Single_Line: ; CRTC Setup Data for 400/480 Line modes + DW 04009H ; Cell Height (1 Scan Line) + DW 00014H ; Dword Mode off + DW 0E317H ; turn on Byte Mode + DW nil ; End of CRTC Data for 400/480 Line Mode + +MODE_Double_Line: ; CRTC Setup Data for 200/240 Line modes + DW 04109H ; Cell Height (2 Scan Lines) + DW 00014H ; Dword Mode off + DW 0E317H ; turn on Byte Mode + DW nil ; End of CRTC Data for 200/240 Line Mode + +MODE_320_Wide: ; CRTC Setup Data for 320 Horz Pixels + DW 05F00H ; Horz total + DW 04F01H ; Horz Displayed + DW 05002H ; Start Horz Blanking + DW 08203H ; End Horz Blanking + DW 05404H ; Start H Sync + DW 08005H ; End H Sync + DW nil ; End of CRTC Data for 320 Horz pixels + +MODE_360_Wide: ; CRTC Setup Data for 360 Horz Pixels + DW 06B00H ; Horz total + DW 05901H ; Horz Displayed + DW 05A02H ; Start Horz Blanking + DW 08E03H ; End Horz Blanking + DW 05E04H ; Start H Sync + DW 08A05H ; End H Sync + DW nil ; End of CRTC Data for 360 Horz pixels + +MODE_200_Tall: +MODE_400_Tall: ; CRTC Setup Data for 200/400 Line modes + DW 0BF06H ; Vertical Total + DW 01F07H ; Overflow + DW 09C10H ; V Sync Start + DW 08E11H ; V Sync End/Prot Cr0 Cr7 + DW 08F12H ; Vertical Displayed + DW 09615H ; V Blank Start + DW 0B916H ; V Blank End + DW nil ; End of CRTC Data for 200/400 Lines + +MODE_240_Tall: +MODE_480_Tall: ; CRTC Setup Data for 240/480 Line modes + DW 00D06H ; Vertical Total + DW 03E07H ; Overflow + DW 0EA10H ; V Sync Start + DW 08C11H ; V Sync End/Prot Cr0 Cr7 + DW 0DF12H ; Vertical Displayed + DW 0E715H ; V Blank Start + DW 00616H ; V Blank End + DW nil ; End of CRTC Data for 240/480 Lines + + ; Table of Display Mode Tables + +MODE_TABLE: + DW o MODE_320x200, o MODE_320x400 + DW o MODE_360x200, o MODE_360x400 + DW o MODE_320x240, o MODE_320x480 + DW o MODE_360x240, o MODE_360x480 + + ; Table of Display Mode Components + +MODE_320x200: ; Data for 320 by 200 Pixels + + DB 063h ; 400 scan Lines & 25 Mhz Clock + DB 4 ; Maximum of 4 Pages + DW 320, 200 ; Displayed Pixels (X,Y) + DW 1302, 816 ; Max Possible X and Y Sizes + + DW o MODE_320_Wide, o MODE_200_Tall + DW o MODE_Double_Line, nil + +MODE_320x400: ; Data for 320 by 400 Pixels + + DB 063h ; 400 scan Lines & 25 Mhz Clock + DB 2 ; Maximum of 2 Pages + DW 320, 400 ; Displayed Pixels X,Y + DW 648, 816 ; Max Possible X and Y Sizes + + DW o MODE_320_Wide, o MODE_400_Tall + DW o MODE_Single_Line, nil + +MODE_360x240: ; Data for 360 by 240 Pixels + + DB 0E7h ; 480 scan Lines & 28 Mhz Clock + DB 3 ; Maximum of 3 Pages + DW 360, 240 ; Displayed Pixels X,Y + DW 1092, 728 ; Max Possible X and Y Sizes + + DW o MODE_360_Wide, o MODE_240_Tall + DW o MODE_Double_Line , nil + +MODE_360x480: ; Data for 360 by 480 Pixels + + DB 0E7h ; 480 scan Lines & 28 Mhz Clock + DB 1 ; Only 1 Page Possible + DW 360, 480 ; Displayed Pixels X,Y + DW 544, 728 ; Max Possible X and Y Sizes + + DW o MODE_360_Wide, o MODE_480_Tall + DW o MODE_Single_Line , nil + +MODE_320x240: ; Data for 320 by 240 Pixels + + DB 0E3h ; 480 scan Lines & 25 Mhz Clock + DB 3 ; Maximum of 3 Pages + DW 320, 240 ; Displayed Pixels X,Y + DW 1088, 818 ; Max Possible X and Y Sizes + + DW o MODE_320_Wide, o MODE_240_Tall + DW o MODE_Double_Line, nil + +MODE_320x480: ; Data for 320 by 480 Pixels + + DB 0E3h ; 480 scan Lines & 25 Mhz Clock + DB 1 ; Only 1 Page Possible + DW 320, 480 ; Displayed Pixels X,Y + DW 540, 818 ; Max Possible X and Y Sizes + + DW o MODE_320_WIDE, o MODE_480_Tall + DW o MODE_Single_Line, nil + +MODE_360x200: ; Data for 360 by 200 Pixels + + DB 067h ; 400 scan Lines & 28 Mhz Clock + DB 3 ; Maximum of 3 Pages + DW 360, 200 ; Displayed Pixels (X,Y) + DW 1302, 728 ; Max Possible X and Y Sizes + + DW o MODE_360_Wide, MODE_200_Tall + DW o MODE_Double_Line, nil + +MODE_360x400: ; Data for 360 by 400 Pixels + + DB 067h ; 400 scan Lines & 28 Mhz Clock + DB 1 ; Maximum of 1 Pages + DW 360, 400 ; Displayed Pixels X,Y + DW 648, 816 ; Max Possible X and Y Sizes + + DW o MODE_360_Wide, MODE_400_Tall + DW o MODE_Single_Line, nil + + + ; ===== MODE X SETUP ROUTINES ===== + +;====================================================== +;SET_VGA_MODEX% (ModeType%, MaxXPos%, MaxYpos%, Pages%) +;====================================================== +; +; Sets Up the specified version of Mode X. Allows for +; the setup of multiple video pages, and a virtual +; screen which can be larger than the displayed screen +; (which can then be scrolled a pixel at a time) +; +; ENTRY: ModeType = Desired Screen Resolution (0-7) +; +; 0 = 320 x 200, 4 Pages max, 1.2:1 Aspect Ratio +; 1 = 320 x 400, 2 Pages max, 2.4:1 Aspect Ratio +; 2 = 360 x 200, 3 Pages max, 1.35:1 Aspect Ratio +; 3 = 360 x 400, 1 Page max, 2.7:1 Aspect Ratio +; 4 = 320 x 240, 3 Pages max, 1:1 Aspect Ratio +; 5 = 320 x 480, 1 Page max, 2:1 Aspect Ratio +; 6 = 360 x 240, 3 Pages max, 1.125:1 Aspect Ratio +; 7 = 360 x 480, 1 Page max, 2.25:1 Aspect Ratio +; +; MaxXpos = The Desired Virtual Screen Width +; MaxYpos = The Desired Virtual Screen Height +; Pages = The Desired # of Video Pages +; +; EXIT: AX = Success Flag: 0 = Failure / -1= Success +; + +SVM_STACK STRUC + SVM_Table DW ? ; Offset of Mode Info Table + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + SVM_Pages DW ? ; # of Screen Pages desired + SVM_Ysize DW ? ; Vertical Screen Size Desired + SVM_Xsize DW ? ; Horizontal Screen Size Desired + SVM_Mode DW ? ; Display Resolution Desired +SVM_STACK ENDS + + PUBLIC SET_VGA_MODEX + +SET_VGA_MODEX PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + SUB SP, 2 ; Allocate workspace + MOV BP, SP ; Set up Stack Frame + + ; Check Legality of Mode Request.... + + MOV BX, [BP].SVM_Mode ; Get Requested Mode # + CMP BX, NUM_MODES ; Is it 0..7? + JAE @SVM_BadModeSetup ; If Not, Error out + + SHL BX, 1 ; Scale BX + MOV SI, w MODE_TABLE[BX] ; CS:SI -> Mode Info + MOV [BP].SVM_Table, SI ; Save ptr for later use + + ; Check # of Requested Display Pages + + MOV CX, [BP].SVM_Pages ; Get # of Requested Pages + CLR CH ; Set Hi Word = 0! + CMP CL, CS:[SI].M_Pages ; Check # Pages for mode + JA @SVM_BadModeSetup ; Report Error if too Many Pages + JCXZ @SVM_BadModeSetup ; Report Error if 0 Pages + + ; Check Validity of X Size + + AND [BP].SVM_XSize, 0FFF8h ; X size Mod 8 Must = 0 + + MOV AX, [BP].SVM_XSize ; Get Logical Screen Width + CMP AX, CS:[SI].M_XSize ; Check against Displayed X + JB @SVM_BadModeSetup ; Report Error if too small + CMP AX, CS:[SI].M_XMax ; Check against Max X + JA @SVM_BadModeSetup ; Report Error if too big + + ; Check Validity of Y Size + + MOV BX, [BP].SVM_YSize ; Get Logical Screen Height + CMP BX, CS:[SI].M_YSize ; Check against Displayed Y + JB @SVM_BadModeSetup ; Report Error if too small + CMP BX, CS:[SI].M_YMax ; Check against Max Y + JA @SVM_BadModeSetup ; Report Error if too big + + ; Enough memory to Fit it all? + + SHR AX, 2 ; # of Bytes:Line = XSize/4 + MUL CX ; AX = Bytes/Line * Pages + MUL BX ; DX:AX = Total VGA mem needed + JNO @SVM_Continue ; Exit if Total Size > 256K + + DEC DX ; Was it Exactly 256K??? + OR DX, AX ; (DX = 1, AX = 0000) + JZ @SVM_Continue ; if so, it's valid... + +@SVM_BadModeSetup: + + CLR AX ; Return Value = False + JMP @SVM_Exit ; Normal Exit + +@SVM_Continue: + + MOV AX, 13H ; Start with Mode 13H + INT 10H ; Let BIOS Set Mode + + OUT_16 SC_INDEX, CHAIN4_OFF ; Disable Chain 4 Mode + OUT_16 SC_INDEX, ASYNC_RESET ; (A)synchronous Reset + OUT_8 MISC_OUTPUT, CS:[SI].M_MiscR ; Set New Timing/Size + OUT_16 SC_INDEX, SEQU_RESTART ; Restart Sequencer ... + + OUT_8 CRTC_INDEX, 11H ; Select Vert Retrace End Register + INC DX ; Point to Data + IN AL, DX ; Get Value, Bit 7 = Protect + AND AL, 7FH ; Mask out Write Protect + OUT DX, AL ; And send it back + + MOV DX, CRTC_INDEX ; Vga Crtc Registers + ADD SI, M_CRTC ; SI -> CRTC Parameter Data + + ; Load Tables of CRTC Parameters from List of Tables + +@SVM_Setup_Table: + + MOV DI, CS:[SI] ; Get Pointer to CRTC Data Tbl + ADD SI, 2 ; Point to next Ptr Entry + OR DI, DI ; A nil Ptr means that we have + JZ @SVM_Set_Data ; finished CRTC programming + +@SVM_Setup_CRTC: + MOV AX, CS:[DI] ; Get CRTC Data from Table + ADD DI, 2 ; Advance Pointer + OR AX, AX ; At End of Data Table? + JZ @SVM_Setup_Table ; If so, Exit & get next Table + + OUT DX, AX ; Reprogram VGA CRTC reg + JMP s @SVM_Setup_CRTC ; Process Next Table Entry + + ; Initialize Page & Scroll info, DI = 0 + +@SVM_Set_Data: + MOV DISPLAY_PAGE, DI ; Display Page = 0 + MOV ACTIVE_PAGE, DI ; Active Page = 0 + MOV CURRENT_PAGE, DI ; Current Page (Offset) = 0 + MOV CURRENT_XOFFSET, DI ; Horz Scroll Index = 0 + MOV CURRENT_YOFFSET, DI ; Vert Scroll Index = 0 + MOV CURRENT_MOFFSET, DI ; Memory Scroll Index = 0 + + MOV AX, VGA_SEGMENT ; Segment for VGA memory + MOV CURRENT_SEGMENT, AX ; Save for Future LES's + + ; Set Logical Screen Width, X Scroll and Our Data + + MOV SI, [BP].SVM_Table ; Get Saved Ptr to Mode Info + MOV AX, [BP].SVM_Xsize ; Get Display Width + + MOV CX, AX ; CX = Logical Width + SUB CX, CS:[SI].M_XSize ; CX = Max X Scroll Value + MOV MAX_XOFFSET, CX ; Set Maximum X Scroll + + SHR AX, 2 ; Bytes = Pixels / 4 + MOV SCREEN_WIDTH, AX ; Save Width in Pixels + + SHR AX, 1 ; Offset Value = Bytes / 2 + MOV AH, 13h ; CRTC Offset Register Index + XCHG AL, AH ; Switch format for OUT + OUT DX, AX ; Set VGA CRTC Offset Reg + + ; Setup Data table, Y Scroll, Misc for Other Routines + + MOV AX, [BP].SVM_Ysize ; Get Logical Screen Height + + MOV CX, AX ; CX = Logical Height + SUB BX, CS:[SI].M_YSize ; CX = Max Y Scroll Value + MOV MAX_YOFFSET, CX ; Set Maximum Y Scroll + + MOV SCREEN_HEIGHT, AX ; Save Height in Pixels + MUL SCREEN_WIDTH ; AX = Page Size in Bytes, + MOV PAGE_SIZE, AX ; Save Page Size + + MOV CX, [BP].SVM_Pages ; Get # of Pages + MOV LAST_PAGE, CX ; Save # of Pages + + CLR BX ; Page # = 0 + MOV DX, BX ; Page 0 Offset = 0 + +@SVM_Set_Pages: + + MOV PAGE_ADDR[BX], DX ; Set Page #(BX) Offset + ADD BX, 2 ; Page#++ + ADD DX, AX ; Compute Addr of Next Page + LOOPx CX, @SVM_Set_Pages ; Loop until all Pages Set + + ; Clear VGA Memory + + OUT_16 SC_INDEX, ALL_PLANES_ON ; Select All Planes + LES DI, d CURRENT_PAGE ; -> Start of VGA memory + + CLR AX ; AX = 0 + CLD ; Block Xfer Forwards + MOV CX, 8000H ; 32K * 4 * 2 = 256K + REP STOSW ; Clear dat memory! + + ; Setup Font Pointers + + MOV BH, ROM_8x8_Lo ; Ask for 8x8 Font, 0-127 + MOV AX, GET_CHAR_PTR ; Service to Get Pointer + INT 10h ; Call VGA BIOS + + MOV CHARSET_LOW, BP ; Save Char Set Offset + MOV CHARSET_LOW+2, ES ; Save Char Set Segment + + MOV BH, ROM_8x8_Hi ; Ask for 8x8 Font, 128-255 + MOV AX, GET_CHAR_PTR ; Service to Get Pointer + INT 10h ; Call VGA BIOS + + MOV CHARSET_HI, BP ; Save Char Set Offset + MOV CHARSET_HI+2, ES ; Save Char Set Segment + + MOV AX, True ; Return Success Code + +@SVM_EXIT: + ADD SP, 2 ; Deallocate workspace + POPx DI, SI, DS, BP ; Restore Saved Registers + RET 8 ; Exit & Clean Up Stack + +SET_VGA_MODEX ENDP + + +;================== +;SET_MODEX% (Mode%) +;================== +; +; Quickie Mode Set - Sets Up Mode X to Default Configuration +; +; ENTRY: ModeType = Desired Screen Resolution (0-7) +; (See SET_VGA_MODEX for list) +; +; EXIT: AX = Success Flag: 0 = Failure / -1= Success +; + +SM_STACK STRUC + DW ?,? ; BP, SI + DD ? ; Caller + SM_Mode DW ? ; Desired Screen Resolution +SM_STACK ENDS + + PUBLIC SET_MODEX + +SET_MODEX PROC FAR + + PUSHx BP, SI ; Preserve Important registers + MOV BP, SP ; Set up Stack Frame + + CLR AX ; Assume Failure + MOV BX, [BP].SM_Mode ; Get Desired Mode # + CMP BX, NUM_MODES ; Is it a Valid Mode #? + JAE @SMX_Exit ; If Not, don't Bother + + PUSH BX ; Push Mode Parameter + + SHL BX, 1 ; Scale BX to word Index + MOV SI, w MODE_TABLE[BX] ; CS:SI -> Mode Info + + PUSH CS:[SI].M_XSize ; Push Default X Size + PUSH CS:[SI].M_Ysize ; Push Default Y size + MOV AL, CS:[SI].M_Pages ; Get Default # of Pages + CLR AH ; Hi Byte = 0 + PUSH AX ; Push # Pages + + CALL f SET_VGA_MODEX ; Set up Mode X! + +@SMX_Exit: + POPx SI, BP ; Restore Registers + RET 2 ; Exit & Clean Up Stack + +SET_MODEX ENDP + + + ; ===== BASIC GRAPHICS PRIMITIVES ===== + +;============================ +;CLEAR_VGA_SCREEN (ColorNum%) +;============================ +; +; Clears the active display page +; +; ENTRY: ColorNum = Color Value to fill the page with +; +; EXIT: No meaningful values returned +; + +CVS_STACK STRUC + DW ?,? ; DI, BP + DD ? ; Caller + CVS_COLOR DB ?,? ; Color to Set Screen to +CVS_STACK ENDS + + PUBLIC CLEAR_VGA_SCREEN + +CLEAR_VGA_SCREEN PROC FAR + + PUSHx BP, DI ; Preserve Important Registers + MOV BP, SP ; Set up Stack Frame + + OUT_16 SC_INDEX, ALL_PLANES_ON ; Select All Planes + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AL, [BP].CVS_COLOR ; Get Color + MOV AH, AL ; Copy for Word Write + CLD ; Block fill Forwards + + MOV CX, PAGE_SIZE ; Get Size of Page + SHR CX, 1 ; Divide by 2 for Words + REP STOSW ; Block Fill VGA memory + + POPx DI, BP ; Restore Saved Registers + RET 2 ; Exit & Clean Up Stack + +CLEAR_VGA_SCREEN ENDP + + +;=================================== +;SET_POINT (Xpos%, Ypos%, ColorNum%) +;=================================== +; +; Plots a single Pixel on the active display page +; +; ENTRY: Xpos = X position to plot pixel at +; Ypos = Y position to plot pixel at +; ColorNum = Color to plot pixel with +; +; EXIT: No meaningful values returned +; + +SP_STACK STRUC + DW ?,? ; BP, DI + DD ? ; Caller + SETP_Color DB ?,? ; Color of Point to Plot + SETP_Ypos DW ? ; Y pos of Point to Plot + SETP_Xpos DW ? ; X pos of Point to Plot +SP_STACK ENDS + + PUBLIC SET_POINT + +SET_POINT PROC FAR + + PUSHx BP, DI ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, [BP].SETP_Ypos ; Get Line # of Pixel + MUL SCREEN_WIDTH ; Get Offset to Start of Line + + MOV BX, [BP].SETP_Xpos ; Get Xpos + MOV CX, BX ; Copy to extract Plane # from + SHR BX, 2 ; X offset (Bytes) = Xpos/4 + ADD BX, AX ; Offset = Width*Ypos + Xpos/4 + + MOV AX, MAP_MASK_PLANE1 ; Map Mask & Plane Select Register + AND CL, PLANE_BITS ; Get Plane Bits + SHL AH, CL ; Get Plane Select Value + OUT_16 SC_Index, AX ; Select Plane + + MOV AL,[BP].SETP_Color ; Get Pixel Color + MOV ES:[DI+BX], AL ; Draw Pixel + + POPx DI, BP ; Restore Saved Registers + RET 6 ; Exit and Clean up Stack + +SET_POINT ENDP + + +;========================== +;READ_POINT% (Xpos%, Ypos%) +;========================== +; +; Read the color of a pixel from the Active Display Page +; +; ENTRY: Xpos = X position of pixel to read +; Ypos = Y position of pixel to read +; +; EXIT: AX = Color of Pixel at (Xpos, Ypos) +; + +RP_STACK STRUC + DW ?,? ; BP, DI + DD ? ; Caller + RP_Ypos DW ? ; Y pos of Point to Read + RP_Xpos DW ? ; X pos of Point to Read +RP_STACK ENDS + + PUBLIC READ_POINT + +READ_POINT PROC FAR + + PUSHx BP, DI ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, [BP].RP_Ypos ; Get Line # of Pixel + MUL SCREEN_WIDTH ; Get Offset to Start of Line + + MOV BX, [BP].RP_Xpos ; Get Xpos + MOV CX, BX + SHR BX, 2 ; X offset (Bytes) = Xpos/4 + ADD BX, AX ; Offset = Width*Ypos + Xpos/4 + + MOV AL, READ_MAP ; GC Read Mask Register + MOV AH, CL ; Get Xpos + AND AH, PLANE_BITS ; & mask out Plane # + OUT_16 GC_INDEX, AX ; Select Plane to read in + + CLR AH ; Clear Return Value Hi byte + MOV AL, ES:[DI+BX] ; Get Color of Pixel + + POPx DI, BP ; Restore Saved Registers + RET 4 ; Exit and Clean up Stack + +READ_POINT ENDP + + +;====================================================== +;FILL_BLOCK (Xpos1%, Ypos1%, Xpos2%, Ypos2%, ColorNum%) +;====================================================== +; +; Fills a rectangular block on the active display Page +; +; ENTRY: Xpos1 = Left X position of area to fill +; Ypos1 = Top Y position of area to fill +; Xpos2 = Right X position of area to fill +; Ypos2 = Bottom Y position of area to fill +; ColorNum = Color to fill area with +; +; EXIT: No meaningful values returned +; + +FB_STACK STRUC + DW ?x4 ; DS, DI, SI, BP + DD ? ; Caller + FB_Color DB ?,? ; Fill Color + FB_Ypos2 DW ? ; Y pos of Lower Right Pixel + FB_Xpos2 DW ? ; X pos of Lower Right Pixel + FB_Ypos1 DW ? ; Y pos of Upper Left Pixel + FB_Xpos1 DW ? ; X pos of Upper Left Pixel +FB_STACK ENDS + + PUBLIC FILL_BLOCK + +FILL_BLOCK PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + CLD ; Direction Flag = Forward + + OUT_8 SC_INDEX, MAP_MASK ; Set up for Plane Select + + ; Validate Pixel Coordinates + ; If necessary, Swap so X1 <= X2, Y1 <= Y2 + + MOV AX, [BP].FB_Ypos1 ; AX = Y1 is Y1< Y2? + MOV BX, [BP].FB_Ypos2 ; BX = Y2 + CMP AX, BX + JLE @FB_NOSWAP1 + + MOV [BP].FB_Ypos1, BX ; Swap Y1 and Y2 and save Y1 + XCHG AX, BX ; on stack for future use + +@FB_NOSWAP1: + SUB BX, AX ; Get Y width + INC BX ; Add 1 to avoid 0 value + MOV [BP].FB_Ypos2, BX ; Save in Ypos2 + + MUL SCREEN_WIDTH ; Mul Y1 by Bytes per Line + ADD DI, AX ; DI = Start of Line Y1 + + MOV AX, [BP].FB_Xpos1 ; Check X1 <= X2 + MOV BX, [BP].FB_Xpos2 ; + CMP AX, BX + JLE @FB_NOSWAP2 ; Skip Ahead if Ok + + MOV [BP].FB_Xpos2, AX ; Swap X1 AND X2 and save X2 + XCHG AX, BX ; on stack for future use + + ; All our Input Values are in order, Now determine + ; How many full "bands" 4 pixels wide (aligned) there + ; are, and if there are partial bands (<4 pixels) on + ; the left and right edges. + +@FB_NOSWAP2: + MOV DX, AX ; DX = X1 (Pixel Position) + SHR DX, 2 ; DX/4 = Bytes into Line + ADD DI, DX ; DI = Addr of Upper-Left Corner + + MOV CX, BX ; CX = X2 (Pixel Position) + SHR CX, 2 ; CX/4 = Bytes into Line + + CMP DX, CX ; Start and end in same band? + JNE @FB_NORMAL ; if not, check for l & r edges + JMP @FB_ONE_BAND_ONLY ; if so, then special processing + +@FB_NORMAL: + SUB CX, DX ; CX = # bands -1 + MOV SI, AX ; SI = PLANE#(X1) + AND SI, PLANE_BITS ; if Left edge is aligned then + JZ @FB_L_PLANE_FLUSH ; no special processing.. + + ; Draw "Left Edge" vertical strip of 1-3 pixels... + + OUT_8 SC_Data, Left_Clip_Mask[SI] ; Set Left Edge Plane Mask + + MOV SI, DI ; SI = Copy of Start Addr (UL) + + MOV DX, [BP].FB_Ypos2 ; Get # of Lines to draw + MOV AL, [BP].FB_Color ; Get Fill Color + MOV BX, SCREEN_WIDTH ; Get Vertical increment Value + +@FB_LEFT_LOOP: + MOV ES:[SI], AL ; Fill in Left Edge Pixels + ADD SI, BX ; Point to Next Line (Below) + LOOPjz DX, @FB_LEFT_CONT ; Exit loop if all Lines Drawn + + MOV ES:[SI], AL ; Fill in Left Edge Pixels + ADD SI, BX ; Point to Next Line (Below) + LOOPx DX, @FB_LEFT_LOOP ; loop until left strip is drawn + +@FB_LEFT_CONT: + + INC DI ; Point to Middle (or Right) Block + DEC CX ; Reset CX instead of JMP @FB_RIGHT + +@FB_L_PLANE_FLUSH: + INC CX ; Add in Left band to middle block + + ; DI = Addr of 1st middle Pixel (band) to fill + ; CX = # of Bands to fill -1 + +@FB_RIGHT: + MOV SI, [BP].FB_Xpos2 ; Get Xpos2 + AND SI, PLANE_BITS ; Get Plane values + CMP SI, 0003 ; Plane = 3? + JE @FB_R_EDGE_FLUSH ; Hey, add to middle + + ; Draw "Right Edge" vertical strip of 1-3 pixels... + + OUT_8 SC_Data, Right_Clip_Mask[SI] ; Right Edge Plane Mask + + MOV SI, DI ; Get Addr of Left Edge + ADD SI, CX ; Add Width-1 (Bands) + DEC SI ; To point to top of Right Edge + + MOV DX, [BP].FB_Ypos2 ; Get # of Lines to draw + MOV AL, [BP].FB_Color ; Get Fill Color + MOV BX, SCREEN_WIDTH ; Get Vertical increment Value + +@FB_RIGHT_LOOP: + MOV ES:[SI], AL ; Fill in Right Edge Pixels + ADD SI, BX ; Point to Next Line (Below) + LOOPjz DX, @FB_RIGHT_CONT ; Exit loop if all Lines Drawn + + MOV ES:[SI], AL ; Fill in Right Edge Pixels + ADD SI, BX ; Point to Next Line (Below) + LOOPx DX, @FB_RIGHT_LOOP ; loop until left strip is drawn + +@FB_RIGHT_CONT: + + DEC CX ; Minus 1 for Middle bands + JZ @FB_EXIT ; Uh.. no Middle bands... + +@FB_R_EDGE_FLUSH: + + ; DI = Addr of Upper Left block to fill + ; CX = # of Bands to fill in (width) + + OUT_8 SC_Data, ALL_PLANES ; Write to All Planes + + MOV DX, SCREEN_WIDTH ; DX = DI Increment + SUB DX, CX ; = Screen_Width-# Planes Filled + + MOV BX, CX ; BX = Quick Refill for CX + MOV SI, [BP].FB_Ypos2 ; SI = # of Line to Fill + MOV AL, [BP].FB_Color ; Get Fill Color + +@FB_MIDDLE_LOOP: + REP STOSB ; Fill in entire line + + MOV CX, BX ; Recharge CX (Line Width) + ADD DI, DX ; Point to start of Next Line + LOOPx SI, @FB_MIDDLE_LOOP ; Loop until all lines drawn + + JMP s @FB_EXIT ; Outa here + +@FB_ONE_BAND_ONLY: + MOV SI, AX ; Get Left Clip Mask, Save X1 + AND SI, PLANE_BITS ; Mask out Row # + MOV AL, Left_Clip_Mask[SI] ; Get Left Edge Mask + MOV SI, BX ; Get Right Clip Mask, Save X2 + AND SI, PLANE_BITS ; Mask out Row # + AND AL, Right_Clip_Mask[SI] ; Get Right Edge Mask byte + + OUT_8 SC_Data, AL ; Clip For Left & Right Masks + + MOV CX, [BP].FB_Ypos2 ; Get # of Lines to draw + MOV AL, [BP].FB_Color ; Get Fill Color + MOV BX, SCREEN_WIDTH ; Get Vertical increment Value + +@FB_ONE_LOOP: + MOV ES:[DI], AL ; Fill in Pixels + ADD DI, BX ; Point to Next Line (Below) + LOOPjz CX, @FB_EXIT ; Exit loop if all Lines Drawn + + MOV ES:[DI], AL ; Fill in Pixels + ADD DI, BX ; Point to Next Line (Below) + LOOPx CX, @FB_ONE_LOOP ; loop until left strip is drawn + +@FB_EXIT: + POPx DI, SI, DS, BP ; Restore Saved Registers + RET 10 ; Exit and Clean up Stack + +FILL_BLOCK ENDP + + +;===================================================== +;DRAW_LINE (Xpos1%, Ypos1%, Xpos2%, Ypos2%, ColorNum%) +;===================================================== +; +; Draws a Line on the active display page +; +; ENTRY: Xpos1 = X position of first point on line +; Ypos1 = Y position of first point on line +; Xpos2 = X position of last point on line +; Ypos2 = Y position of last point on line +; ColorNum = Color to draw line with +; +; EXIT: No meaningful values returned +; + +DL_STACK STRUC + DW ?x3 ; DI, SI, BP + DD ? ; Caller + DL_ColorF DB ?,? ; Line Draw Color + DL_Ypos2 DW ? ; Y pos of last point + DL_Xpos2 DW ? ; X pos of last point + DL_Ypos1 DW ? ; Y pos of first point + DL_Xpos1 DW ? ; X pos of first point +DL_STACK ENDS + + PUBLIC DRAW_LINE + +DRAW_LINE PROC FAR + + PUSHx BP, SI, DI ; Preserve Important Registers + MOV BP, SP ; Set up Stack Frame + CLD ; Direction Flag = Forward + + OUT_8 SC_INDEX, MAP_MASK ; Set up for Plane Select + MOV CH, [BP].DL_ColorF ; Save Line Color in CH + + ; Check Line Type + + MOV SI, [BP].DL_Xpos1 ; AX = X1 is X1< X2? + MOV DI, [BP].DL_Xpos2 ; DX = X2 + CMP SI, DI ; Is X1 < X2 + JE @DL_VLINE ; If X1=X2, Draw Vertical Line + JL @DL_NOSWAP1 ; If X1 < X2, don't swap + + XCHG SI, DI ; X2 IS > X1, SO SWAP THEM + +@DL_NOSWAP1: + + ; SI = X1, DI = X2 + + MOV AX, [BP].DL_Ypos1 ; AX = Y1 is Y1 <> Y2? + CMP AX, [BP].DL_Ypos2 ; Y1 = Y2? + JE @DL_HORZ ; If so, Draw a Horizontal Line + + JMP @DL_BREZHAM ; Diagonal line... go do it... + + ; This Code draws a Horizontal Line in Mode X where: + ; SI = X1, DI = X2, and AX = Y1/Y2 + +@DL_HORZ: + + MUL SCREEN_WIDTH ; Offset = Ypos * Screen_Width + MOV DX, AX ; CX = Line offset into Page + + MOV AX, SI ; Get Left edge, Save X1 + AND SI, PLANE_BITS ; Mask out Row # + MOV BL, Left_Clip_Mask[SI] ; Get Left Edge Mask + MOV CX, DI ; Get Right edge, Save X2 + AND DI, PLANE_BITS ; Mask out Row # + MOV BH, Right_Clip_Mask[DI] ; Get Right Edge Mask byte + + SHR AX, 2 ; Get X1 Byte # (=X1/4) + SHR CX, 2 ; Get X2 Byte # (=X2/4) + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + ADD DI, DX ; Point to Start of Line + ADD DI, AX ; Point to Pixel X1 + + SUB CX, AX ; CX = # Of Bands (-1) to set + JNZ @DL_LONGLN ; jump if longer than one segment + + AND BL, BH ; otherwise, merge clip masks + +@DL_LONGLN: + + OUT_8 SC_Data, BL ; Set the Left Clip Mask + + MOV AL, [BP].DL_ColorF ; Get Line Color + MOV BL, AL ; BL = Copy of Line Color + STOSB ; Set Left (1-4) Pixels + + JCXZ @DL_EXIT ; Done if only one Line Segment + + DEC CX ; CX = # of Middle Segments + JZ @DL_XRSEG ; If no middle segments.... + + ; Draw Middle Segments + + OUT_8 DX, ALL_PLANES ; Write to ALL Planes + + MOV AL, BL ; Get Color from BL + REP STOSB ; Draw Middle (4 Pixel) Segments + +@DL_XRSEG: + OUT_8 DX, BH ; Select Planes for Right Clip Mask + MOV AL, BL ; Get Color Value + STOSB ; Draw Right (1-4) Pixels + + JMP s @DL_EXIT ; We Are Done... + + + ; This Code Draws A Vertical Line. On entry: + ; CH = Line Color, SI & DI = X1 + +@DL_VLINE: + + MOV AX, [BP].DL_Ypos1 ; AX = Y1 + MOV SI, [BP].DL_Ypos2 ; SI = Y2 + CMP AX, SI ; Is Y1 < Y2? + JLE @DL_NOSWAP2 ; if so, Don't Swap them + + XCHG AX, SI ; Ok, NOW Y1 < Y2 + +@DL_NOSWAP2: + + SUB SI, AX ; SI = Line Height (Y2-Y1+1) + INC SI + + ; AX = Y1, DI = X1, Get offset into Page into AX + + MUL SCREEN_WIDTH ; Offset = Y1 (AX) * Screen Width + MOV DX, DI ; Copy Xpos into DX + SHR DI, 2 ; DI = Xpos/4 + ADD AX, DI ; DI = Xpos/4 + ScreenWidth * Y1 + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + ADD DI, AX ; Point to Pixel X1, Y1 + + ;Select Plane + + MOV CL, DL ; CL = Save X1 + AND CL, PLANE_BITS ; Get X1 MOD 4 (Plane #) + MOV AX, MAP_MASK_PLANE1 ; Code to set Plane #1 + SHL AH, CL ; Change to Correct Plane # + OUT_16 SC_Index, AX ; Select Plane + + MOV AL, CH ; Get Saved Color + MOV BX, SCREEN_WIDTH ; Get Offset to Advance Line By + +@DL_VLoop: + MOV ES:[DI], AL ; Draw Single Pixel + ADD DI, BX ; Point to Next Line + LOOPjz SI, @DL_EXIT ; Lines--, Exit if done + + MOV ES:[DI], AL ; Draw Single Pixel + ADD DI, BX ; Point to Next Line + LOOPx SI, @DL_VLoop ; Lines--, Loop until Done + +@DL_EXIT: + + JMP @DL_EXIT2 ; Done! + + ; This code Draws a diagonal line in Mode X + +@DL_BREZHAM: + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, [BP].DL_Ypos1 ; get Y1 value + MOV BX, [BP].DL_Ypos2 ; get Y2 value + MOV CX, [BP].DL_Xpos1 ; Get Starting Xpos + + CMP BX, AX ; Y2-Y1 is? + JNC @DL_DeltaYOK ; if Y2>=Y1 then goto... + + XCHG BX, AX ; Swap em... + MOV CX, [BP].DL_Xpos2 ; Get New Starting Xpos + +@DL_DeltaYOK: + MUL SCREEN_WIDTH ; Offset = SCREEN_WIDTH * Y1 + + ADD DI, AX ; DI -> Start of Line Y1 on Page + MOV AX, CX ; AX = Xpos (X1) + SHR AX, 2 ; /4 = Byte Offset into Line + ADD DI, AX ; DI = Starting pos (X1,Y1) + + MOV AL, 11h ; Staring Mask + AND CL, PLANE_BITS ; Get Plane # + SHL AL, CL ; and shift into place + MOV AH, [BP].DL_ColorF ; Color in Hi Bytes + + PUSH AX ; Save Mask,Color... + + MOV AH, AL ; Plane # in AH + MOV AL, MAP_MASK ; Select Plane Register + OUT_16 SC_Index, AX ; Select initial plane + + MOV AX, [BP].DL_Xpos1 ; get X1 value + MOV BX, [BP].DL_Ypos1 ; get Y1 value + MOV CX, [BP].DL_Xpos2 ; get X2 value + MOV DX, [BP].DL_Ypos2 ; get Y2 value + + MOV BP, SCREEN_WIDTH ; Use BP for Line width to + ; to avoid extra memory access + + SUB DX, BX ; figure Delta_Y + JNC @DL_DeltaYOK2 ; jump if Y2 >= Y1 + + ADD BX, DX ; put Y2 into Y1 + NEG DX ; abs(Delta_Y) + XCHG AX, CX ; and exchange X1 and X2 + +@DL_DeltaYOK2: + MOV BX, 08000H ; seed for fraction accumulator + + SUB CX, AX ; figure Delta_X + JC @DL_DrawLeft ; if negative, go left + + JMP @DL_DrawRight ; Draw Line that slopes right + +@DL_DrawLeft: + + NEG CX ; abs(Delta_X) + + CMP CX, DX ; is Delta_X < Delta_Y? + JB @DL_SteepLeft ; yes, so go do steep line + ; (Delta_Y iterations) + + ; Draw a Shallow line to the left in Mode X + +@DL_ShallowLeft: + CLR AX ; zero low word of Delta_Y * 10000h + SUB AX, DX ; DX:AX <- DX * 0FFFFh + SBB DX, 0 ; include carry + DIV CX ; divide by Delta_X + + MOV SI, BX ; SI = Accumulator + MOV BX, AX ; BX = Add fraction + POP AX ; Get Color, Bit mask + MOV DX, SC_Data ; Sequence controller data register + INC CX ; Inc Delta_X so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Left, and Maybe Down... + +@DL_SLLLoop: + MOV ES:[DI], AH ; set first pixel, plane data set up + LOOPjz CX, @DL_SLLExit ; Delta_X--, Exit if done + + ADD SI, BX ; add numerator to accumulator + JNC @DL_SLLL2nc ; move down on carry + + ADD DI, BP ; Move Down one line... + +@DL_SLLL2nc: + DEC DI ; Left one addr + ROR AL, 1 ; Move Left one plane, back on 0 1 2 + CMP AL, 87h ; wrap?, if AL <88 then Carry set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + + MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_SLLExit ; Delta_X--, Exit if done + + ADD SI, BX ; add numerator to accumulator, + JNC @DL_SLLL3nc ; move down on carry + + ADD DI, BP ; Move Down one line... + +@DL_SLLL3nc: ; Now move left a pixel... + DEC DI ; Left one addr + ROR AL, 1 ; Move Left one plane, back on 0 1 2 + CMP AL, 87h ; Wrap?, if AL <88 then Carry set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + JMP s @DL_SLLLoop ; loop until done + +@DL_SLLExit: + JMP @DL_EXIT2 ; and exit + + ; Draw a steep line to the left in Mode X + +@DL_SteepLeft: + CLR AX ; zero low word of Delta_Y * 10000h + XCHG DX, CX ; Delta_Y switched with Delta_X + DIV CX ; divide by Delta_Y + + MOV SI, BX ; SI = Accumulator + MOV BX, AX ; BX = Add Fraction + POP AX ; Get Color, Bit mask + MOV DX, SC_Data ; Sequence controller data register + INC CX ; Inc Delta_Y so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Down, and Maybe left + +@DL_STLLoop: + + MOV ES:[DI], AH ; set first pixel + LOOPjz CX, @DL_STLExit ; Delta_Y--, Exit if done + + ADD SI, BX ; add numerator to accumulator + JNC @DL_STLnc2 ; No carry, just move down! + + DEC DI ; Move Left one addr + ROR AL, 1 ; Move Left one plane, back on 0 1 2 + CMP AL, 87h ; Wrap?, if AL <88 then Carry set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + +@DL_STLnc2: + ADD DI, BP ; advance to next line. + + MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_STLExit ; Delta_Y--, Exit if done + + ADD SI, BX ; add numerator to accumulator + JNC @DL_STLnc3 ; No carry, just move down! + + DEC DI ; Move Left one addr + ROR AL, 1 ; Move Left one plane, back on 0 1 2 + CMP AL, 87h ; Wrap?, if AL <88 then Carry set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + +@DL_STLnc3: + ADD DI, BP ; advance to next line. + JMP s @DL_STLLoop ; Loop until done + +@DL_STLExit: + JMP @DL_EXIT2 ; and exit + + ; Draw a line that goes to the Right... + +@DL_DrawRight: + CMP CX, DX ; is Delta_X < Delta_Y? + JB @DL_SteepRight ; yes, so go do steep line + ; (Delta_Y iterations) + + ; Draw a Shallow line to the Right in Mode X + +@DL_ShallowRight: + CLR AX ; zero low word of Delta_Y * 10000h + SUB AX, DX ; DX:AX <- DX * 0FFFFh + SBB DX, 0 ; include carry + DIV CX ; divide by Delta_X + + MOV SI, BX ; SI = Accumulator + MOV BX, AX ; BX = Add Fraction + POP AX ; Get Color, Bit mask + MOV DX, SC_Data ; Sequence controller data register + INC CX ; Inc Delta_X so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Right, and Maybe Down... + +@DL_SLRLoop: + MOV ES:[DI], AH ; set first pixel, mask is set up + LOOPjz CX, @DL_SLRExit ; Delta_X--, Exit if done.. + + ADD SI, BX ; add numerator to accumulator + JNC @DL_SLR2nc ; don't move down if carry not set + + ADD DI, BP ; Move Down one line... + +@DL_SLR2nc: ; Now move right a pixel... + ROL AL, 1 ; Move Right one addr if Plane = 0 + CMP AL, 12h ; Wrap? if AL >12 then Carry not set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + + MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_SLRExit ; Delta_X--, Exit if done.. + + ADD SI, BX ; add numerator to accumulator + JNC @DL_SLR3nc ; don't move down if carry not set + + ADD DI, BP ; Move Down one line... + +@DL_SLR3nc: + ROL AL, 1 ; Move Right one addr if Plane = 0 + CMP AL, 12h ; Wrap? if AL >12 then Carry not set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + JMP s @DL_SLRLoop ; loop till done + +@DL_SLRExit: + JMP @DL_EXIT2 ; and exit + + ; Draw a Steep line to the Right in Mode X + +@DL_SteepRight: + CLR AX ; zero low word of Delta_Y * 10000h + XCHG DX, CX ; Delta_Y switched with Delta_X + DIV CX ; divide by Delta_Y + + MOV SI, BX ; SI = Accumulator + MOV BX, AX ; BX = Add Fraction + POP AX ; Get Color, Bit mask + MOV DX, SC_Data ; Sequence controller data register + INC CX ; Inc Delta_Y so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Down, and Maybe Right + +@STRLoop: + MOV ES:[DI], AH ; set first pixel, mask is set up + LOOPjz CX, @DL_EXIT2 ; Delta_Y--, Exit if Done + + ADD SI, BX ; add numerator to accumulator + JNC @STRnc2 ; if no carry then just go down... + + ROL AL, 1 ; Move Right one addr if Plane = 0 + CMP AL, 12h ; Wrap? if AL >12 then Carry not set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + +@STRnc2: + ADD DI, BP ; advance to next line. + + MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_EXIT2 ; Delta_Y--, Exit if Done + + ADD SI, BX ; add numerator to accumulator + JNC @STRnc3 ; if no carry then just go down... + + ROL AL, 1 ; Move Right one addr if Plane = 0 + CMP AL, 12h ; Wrap? if AL >12 then Carry not set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + +@STRnc3: + ADD DI, BP ; advance to next line. + JMP s @STRLoop ; loop till done + +@DL_EXIT2: + POPx DI, SI, BP ; Restore Saved Registers + RET 10 ; Exit and Clean up Stack + +DRAW_LINE ENDP + + + ; ===== DAC COLOR REGISTER ROUTINES ===== + +;================================================= +;SET_DAC_REGISTER (Register%, Red%, Green%, Blue%) +;================================================= +; +; Sets a single (RGB) Vga Palette Register +; +; ENTRY: Register = The DAC # to modify (0-255) +; Red = The new Red Intensity (0-63) +; Green = The new Green Intensity (0-63) +; Blue = The new Blue Intensity (0-63) +; +; EXIT: No meaningful values returned +; + +SDR_STACK STRUC + DW ? ; BP + DD ? ; Caller + SDR_Blue DB ?,? ; Blue Data Value + SDR_Green DB ?,? ; Green Data Value + SDR_Red DB ?,? ; Red Data Value + SDR_Register DB ?,? ; Palette Register # +SDR_STACK ENDS + + PUBLIC SET_DAC_REGISTER + +SET_DAC_REGISTER PROC FAR + + PUSH BP ; Save BP + MOV BP, SP ; Set up Stack Frame + + ; Select which DAC Register to modify + + OUT_8 DAC_WRITE_ADDR, [BP].SDR_Register + + MOV DX, PEL_DATA_REG ; Dac Data Register + OUT_8 DX, [BP].SDR_Red ; Set Red Intensity + OUT_8 DX, [BP].SDR_Green ; Set Green Intensity + OUT_8 DX, [BP].SDR_Blue ; Set Blue Intensity + + POP BP ; Restore Registers + RET 8 ; Exit & Clean Up Stack + +SET_DAC_REGISTER ENDP + +;==================================================== +;GET_DAC_REGISTER (Register%, &Red%, &Green%, &Blue%) +;==================================================== +; +; Reads the RGB Values of a single Vga Palette Register +; +; ENTRY: Register = The DAC # to read (0-255) +; Red = Offset to Red Variable in DS +; Green = Offset to Green Variable in DS +; Blue = Offset to Blue Variable in DS +; +; EXIT: The values of the integer variables Red, +; Green, and Blue are set to the values +; taken from the specified DAC register. +; + +GDR_STACK STRUC + DW ? ; BP + DD ? ; Caller + GDR_Blue DW ? ; Addr of Blue Data Value in DS + GDR_Green DW ? ; Addr of Green Data Value in DS + GDR_Red DW ? ; Addr of Red Data Value in DS + GDR_Register DB ?,? ; Palette Register # +GDR_STACK ENDS + + PUBLIC GET_DAC_REGISTER + +GET_DAC_REGISTER PROC FAR + + PUSH BP ; Save BP + MOV BP, SP ; Set up Stack Frame + + ; Select which DAC Register to read in + + OUT_8 DAC_READ_ADDR, [BP].GDR_Register + + MOV DX, PEL_DATA_REG ; Dac Data Register + CLR AX ; Clear AX + + IN AL, DX ; Read Red Value + MOV BX, [BP].GDR_Red ; Get Address of Red% + MOV [BX], AX ; *Red% = AX + + IN AL, DX ; Read Green Value + MOV BX, [BP].GDR_Green ; Get Address of Green% + MOV [BX], AX ; *Green% = AX + + IN AL, DX ; Read Blue Value + MOV BX, [BP].GDR_Blue ; Get Address of Blue% + MOV [BX], AX ; *Blue% = AX + + POP BP ; Restore Registers + RET 8 ; Exit & Clean Up Stack + +GET_DAC_REGISTER ENDP + + +;=========================================================== +;LOAD_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%, Sync%) +;=========================================================== +; +; Sets a Block of Vga Palette Registers +; +; ENTRY: PalData = Far Pointer to Block of palette data +; StartReg = First Register # in range to set (0-255) +; EndReg = Last Register # in Range to set (0-255) +; Sync = Wait for Vertical Retrace Flag (Boolean) +; +; EXIT: No meaningful values returned +; +; NOTES: PalData is a linear array of 3 byte Palette values +; in the order: Red (0-63), Green (0-63), Blue (0-63) +; + +LDR_STACK STRUC + DW ?x3 ; BP, DS, SI + DD ? ; Caller + LDR_Sync DW ? ; Vertical Sync Flag + LDR_EndReg DB ?,? ; Last Register # + LDR_StartReg DB ?,? ; First Register # + LDR_PalData DD ? ; Far Ptr to Palette Data +LDR_STACK ENDS + + PUBLIC LOAD_DAC_REGISTERS + +LOAD_DAC_REGISTERS PROC FAR + + PUSHx BP, DS, SI ; Save Registers + mov BP, SP ; Set up Stack Frame + + mov AX, [BP].LDR_Sync ; Get Vertical Sync Flag + or AX, AX ; is Sync Flag = 0? + jz @LDR_Load ; if so, skip call + + call f SYNC_DISPLAY ; wait for vsync + + ; Determine register #'s, size to copy, etc + +@LDR_Load: + + lds SI, [BP].LDR_PalData ; DS:SI -> Palette Data + mov DX, DAC_WRITE_ADDR ; DAC register # selector + + CLR AX, BX ; Clear for byte loads + mov AL, [BP].LDR_StartReg ; Get Start Register + mov BL, [BP].LDR_EndReg ; Get End Register + + sub BX, AX ; BX = # of DAC registers -1 + inc BX ; BX = # of DAC registers + mov CX, BX ; CX = # of DAC registers + add CX, BX ; CX = " " * 2 + add CX, BX ; CX = " " * 3 + cld ; Block OUTs forward + out DX, AL ; set up correct register # + + ; Load a block of DAC Registers + + mov DX, PEL_DATA_REG ; Dac Data Register + + rep outsb ; block set DAC registers + + POPx SI, DS, BP ; Restore Registers + ret 10 ; Exit & Clean Up Stack + +LOAD_DAC_REGISTERS ENDP + + +;==================================================== +;READ_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%) +;==================================================== +; +; Reads a Block of Vga Palette Registers +; +; ENTRY: PalData = Far Pointer to block to store palette data +; StartReg = First Register # in range to read (0-255) +; EndReg = Last Register # in Range to read (0-255) +; +; EXIT: No meaningful values returned +; +; NOTES: PalData is a linear array of 3 byte Palette values +; in the order: Red (0-63), Green (0-63), Blue (0-63) +; + +RDR_STACK STRUC + DW ?x3 ; BP, ES, DI + DD ? ; Caller + RDR_EndReg DB ?,? ; Last Register # + RDR_StartReg DB ?,? ; First Register # + RDR_PalData DD ? ; Far Ptr to Palette Data +RDR_STACK ENDS + + PUBLIC READ_DAC_REGISTERS + +READ_DAC_REGISTERS PROC FAR + + PUSHx BP, ES, DI ; Save Registers + mov BP, SP ; Set up Stack Frame + + ; Determine register #'s, size to copy, etc + + les DI, [BP].RDR_PalData ; ES:DI -> Palette Buffer + mov DX, DAC_READ_ADDR ; DAC register # selector + + CLR AX, BX ; Clear for byte loads + mov AL, [BP].RDR_StartReg ; Get Start Register + mov BL, [BP].RDR_EndReg ; Get End Register + + sub BX, AX ; BX = # of DAC registers -1 + inc BX ; BX = # of DAC registers + mov CX, BX ; CX = # of DAC registers + add CX, BX ; CX = " " * 2 + add CX, BX ; CX = " " * 3 + cld ; Block INs forward + + ; Read a block of DAC Registers + + out DX, AL ; set up correct register # + mov DX, PEL_DATA_REG ; Dac Data Register + + rep insb ; block read DAC registers + + POPx DI, ES, BP ; Restore Registers + ret 8 ; Exit & Clean Up Stack + +READ_DAC_REGISTERS ENDP + + + ; ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== + +;========================= +;SET_ACTIVE_PAGE (PageNo%) +;========================= +; +; Sets the active display Page to be used for future drawing +; +; ENTRY: PageNo = Display Page to make active +; (values: 0 to Number of Pages - 1) +; +; EXIT: No meaningful values returned +; + +SAP_STACK STRUC + DW ? ; BP + DD ? ; Caller + SAP_Page DW ? ; Page # for Drawing +SAP_STACK ENDS + + PUBLIC SET_ACTIVE_PAGE + +SET_ACTIVE_PAGE PROC FAR + + PUSH BP ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + MOV BX, [BP].SAP_Page ; Get Desired Page # + CMP BX, LAST_PAGE ; Is Page # Valid? + JAE @SAP_Exit ; IF Not, Do Nothing + + MOV ACTIVE_PAGE, BX ; Set Active Page # + + SHL BX, 1 ; Scale Page # to Word + MOV AX, PAGE_ADDR[BX] ; Get offset to Page + + MOV CURRENT_PAGE, AX ; And set for future LES's + +@SAP_Exit: + POP BP ; Restore Registers + RET 2 ; Exit and Clean up Stack + +SET_ACTIVE_PAGE ENDP + + +;================ +;GET_ACTIVE_PAGE% +;================ +; +; Returns the Video Page # currently used for Drawing +; +; ENTRY: No Parameters are passed +; +; EXIT: AX = Current Video Page used for Drawing +; + + PUBLIC GET_ACTIVE_PAGE + +GET_ACTIVE_PAGE PROC FAR + + MOV AX, ACTIVE_PAGE ; Get Active Page # + RET ; Exit and Clean up Stack + +GET_ACTIVE_PAGE ENDP + + +;=============================== +;SET_DISPLAY_PAGE (DisplayPage%) +;=============================== +; +; Sets the currently visible display page. +; When called this routine syncronizes the display +; to the vertical blank. +; +; ENTRY: PageNo = Display Page to show on the screen +; (values: 0 to Number of Pages - 1) +; +; EXIT: No meaningful values returned +; + +SDP_STACK STRUC + DW ? ; BP + DD ? ; Caller + SDP_Page DW ? ; Page # to Display... +SDP_STACK ENDS + + PUBLIC SET_DISPLAY_PAGE + +SET_DISPLAY_PAGE PROC FAR + + PUSH BP ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + MOV BX, [BP].SDP_Page ; Get Desired Page # + CMP BX, LAST_PAGE ; Is Page # Valid? + JAE @SDP_Exit ; IF Not, Do Nothing + + MOV DISPLAY_PAGE, BX ; Set Display Page # + + SHL BX, 1 ; Scale Page # to Word + MOV CX, PAGE_ADDR[BX] ; Get offset in memory to Page + ADD CX, CURRENT_MOFFSET ; Adjust for any scrolling + + ; Wait if we are currently in a Vertical Retrace + + MOV DX, INPUT_1 ; Input Status #1 Register + +@DP_WAIT0: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; In Display mode yet? + JNZ @DP_WAIT0 ; If Not, wait for it + + ; Set the Start Display Address to the new page + + MOV DX, CRTC_Index ; We Change the VGA Sequencer + + MOV AL, START_DISP_LO ; Display Start Low Register + MOV AH, CL ; Low 8 Bits of Start Addr + OUT DX, AX ; Set Display Addr Low + + MOV AL, START_DISP_HI ; Display Start High Register + MOV AH, CH ; High 8 Bits of Start Addr + OUT DX, AX ; Set Display Addr High + + ; Wait for a Vertical Retrace to smooth out things + + MOV DX, INPUT_1 ; Input Status #1 Register + +@DP_WAIT1: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; Vertical Retrace Start? + JZ @DP_WAIT1 ; If Not, wait for it + + ; Now Set Display Starting Address + + +@SDP_Exit: + POP BP ; Restore Registers + RET 2 ; Exit and Clean up Stack + +SET_DISPLAY_PAGE ENDP + + +;================= +;GET_DISPLAY_PAGE% +;================= +; +; Returns the Video Page # currently displayed +; +; ENTRY: No Parameters are passed +; +; EXIT: AX = Current Video Page being displayed +; + + PUBLIC GET_DISPLAY_PAGE + +GET_DISPLAY_PAGE PROC FAR + + MOV AX, DISPLAY_PAGE ; Get Display Page # + RET ; Exit & Clean Up Stack + +GET_DISPLAY_PAGE ENDP + + +;======================================= +;SET_WINDOW (DisplayPage%, Xpos%, Ypos%) +;======================================= +; +; Since a Logical Screen can be larger than the Physical +; Screen, Scrolling is possible. This routine sets the +; Upper Left Corner of the Screen to the specified Pixel. +; Also Sets the Display page to simplify combined page +; flipping and scrolling. When called this routine +; syncronizes the display to the vertical blank. +; +; ENTRY: DisplayPage = Display Page to show on the screen +; Xpos = # of pixels to shift screen right +; Ypos = # of lines to shift screen down +; +; EXIT: No meaningful values returned +; + +SW_STACK STRUC + DW ? ; BP + DD ? ; Caller + SW_Ypos DW ? ; Y pos of UL Screen Corner + SW_Xpos DW ? ; X pos of UL Screen Corner + SW_Page DW ? ; (new) Display Page +SW_STACK ENDS + + PUBLIC SET_WINDOW + +SET_WINDOW PROC FAR + + PUSH BP ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + ; Check if our Scroll Offsets are Valid + + MOV BX, [BP].SW_Page ; Get Desired Page # + CMP BX, LAST_PAGE ; Is Page # Valid? + JAE @SW_Exit ; IF Not, Do Nothing + + MOV AX, [BP].SW_Ypos ; Get Desired Y Offset + CMP AX, MAX_YOFFSET ; Is it Within Limits? + JA @SW_Exit ; if not, exit + + MOV CX, [BP].SW_Xpos ; Get Desired X Offset + CMP CX, MAX_XOFFSET ; Is it Within Limits? + JA @SW_Exit ; if not, exit + + ; Compute proper Display start address to use + + MUL SCREEN_WIDTH ; AX = YOffset * Line Width + SHR CX, 2 ; CX / 4 = Bytes into Line + ADD AX, CX ; AX = Offset of Upper Left Pixel + + MOV CURRENT_MOFFSET, AX ; Save Offset Info + + MOV DISPLAY_PAGE, BX ; Set Current Page # + SHL BX, 1 ; Scale Page # to Word + ADD AX, PAGE_ADDR[BX] ; Get offset in VGA to Page + MOV BX, AX ; BX = Desired Display Start + + MOV DX, INPUT_1 ; Input Status #1 Register + + ; Wait if we are currently in a Vertical Retrace + +@SW_WAIT0: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; In Display mode yet? + JNZ @SW_WAIT0 ; If Not, wait for it + + ; Set the Start Display Address to the new window + + MOV DX, CRTC_Index ; We Change the VGA Sequencer + MOV AL, START_DISP_LO ; Display Start Low Register + MOV AH, BL ; Low 8 Bits of Start Addr + OUT DX, AX ; Set Display Addr Low + + MOV AL, START_DISP_HI ; Display Start High Register + MOV AH, BH ; High 8 Bits of Start Addr + OUT DX, AX ; Set Display Addr High + + ; Wait for a Vertical Retrace to smooth out things + + MOV DX, INPUT_1 ; Input Status #1 Register + +@SW_WAIT1: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; Vertical Retrace Start? + JZ @SW_WAIT1 ; If Not, wait for it + + ; Now Set the Horizontal Pixel Pan values + + OUT_8 ATTRIB_Ctrl, PIXEL_PAN_REG ; Select Pixel Pan Register + + MOV AX, [BP].SW_Xpos ; Get Desired X Offset + AND AL, 03 ; Get # of Pixels to Pan (0-3) + SHL AL, 1 ; Shift for 256 Color Mode + OUT DX, AL ; Fine tune the display! + +@SW_Exit: + POP BP ; Restore Saved Registers + RET 6 ; Exit and Clean up Stack + +SET_WINDOW ENDP + + +;============= +;GET_X_OFFSET% +;============= +; +; Returns the X coordinate of the Pixel currently display +; in the upper left corner of the display +; +; ENTRY: No Parameters are passed +; +; EXIT: AX = Current Horizontal Scroll Offset +; + + PUBLIC GET_X_OFFSET + +GET_X_OFFSET PROC FAR + + MOV AX, CURRENT_XOFFSET ; Get current horz offset + RET ; Exit & Clean Up Stack + +GET_X_OFFSET ENDP + + +;============= +;GET_Y_OFFSET% +;============= +; +; Returns the Y coordinate of the Pixel currently display +; in the upper left corner of the display +; +; ENTRY: No Parameters are passed +; +; EXIT: AX = Current Vertical Scroll Offset +; + + PUBLIC GET_Y_OFFSET + +GET_Y_OFFSET PROC FAR + + MOV AX, CURRENT_YOFFSET ; Get current vertical offset + RET ; Exit & Clean Up Stack + +GET_Y_OFFSET ENDP + + +;============ +;SYNC_DISPLAY +;============ +; +; Pauses the computer until the next Vertical Retrace starts +; +; ENTRY: No Parameters are passed +; +; EXIT: No meaningful values returned +; + + PUBLIC SYNC_DISPLAY + +SYNC_DISPLAY PROC FAR + + MOV DX, INPUT_1 ; Input Status #1 Register + + ; Wait for any current retrace to end + +@SD_WAIT0: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; In Display mode yet? + JNZ @SD_WAIT0 ; If Not, wait for it + + ; Wait for the start of the next vertical retrace + +@SD_WAIT1: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; Vertical Retrace Start? + JZ @SD_WAIT1 ; If Not, wait for it + + RET ; Exit & Clean Up Stack + +SYNC_DISPLAY ENDP + + + ; ===== TEXT DISPLAY ROUTINES ===== + +;================================================== +;GPRINTC (CharNum%, Xpos%, Ypos%, ColorF%, ColorB%) +;================================================== +; +; Draws an ASCII Text Character using the currently selected +; 8x8 font on the active display page. It would be a simple +; exercise to make this routine process variable height fonts. +; +; ENTRY: CharNum = ASCII character # to draw +; Xpos = X position to draw Character at +; Ypos = Y position of to draw Character at +; ColorF = Color to draw text character in +; ColorB = Color to set background to +; +; EXIT: No meaningful values returned +; + +GPC_STACK STRUC + GPC_Width DW ? ; Screen Width-1 + GPC_Lines DB ?,? ; Scan lines to Decode + GPC_T_SETS DW ? ; Saved Charset Segment + GPC_T_SETO DW ? ; Saved Charset Offset + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + GPC_ColorB DB ?,? ; Background Color + GPC_ColorF DB ?,? ; Text Color + GPC_Ypos DW ? ; Y Position to Print at + GPC_Xpos DW ? ; X position to Print at + GPC_Char DB ?,? ; Character to Print +GPC_STACK ENDS + + PUBLIC GPRINTC + +GPRINTC PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + SUB SP, 8 ; Allocate WorkSpace on Stack + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, SCREEN_WIDTH ; Get Logical Line Width + MOV BX, AX ; BX = Screen Width + DEC BX ; = Screen Width-1 + MOV [BP].GPC_Width, BX ; Save for later use + + MUL [BP].GPC_Ypos ; Start of Line = Ypos * Width + ADD DI, AX ; DI -> Start of Line Ypos + + MOV AX, [BP].GPC_Xpos ; Get Xpos of Character + MOV CX, AX ; Save Copy of Xpos + SHR AX, 2 ; Bytes into Line = Xpos/4 + ADD DI, AX ; DI -> (Xpos, Ypos) + + ;Get Source ADDR of Character Bit Map & Save + + MOV AL, [BP].GPC_Char ; Get Character # + TEST AL, 080h ; Is Hi Bit Set? + JZ @GPC_LowChar ; Nope, use low char set ptr + + AND AL, 07Fh ; Mask Out Hi Bit + MOV BX, CHARSET_HI ; BX = Char Set Ptr:Offset + MOV DX, CHARSET_HI+2 ; DX = Char Set Ptr:Segment + JMP s @GPC_Set_Char ; Go Setup Character Ptr + +@GPC_LowChar: + + MOV BX, CHARSET_LOW ; BX = Char Set Ptr:Offset + MOV DX, CHARSET_LOW+2 ; DX = Char Set Ptr:Segment + +@GPC_Set_Char: + MOV [BP].GPC_T_SETS, DX ; Save Segment on Stack + + MOV AH, 0 ; Valid #'s are 0..127 + SHL AX, 3 ; * 8 Bytes Per Bitmap + ADD BX, AX ; BX = Offset of Selected char + MOV [BP].GPC_T_SETO, BX ; Save Offset on Stack + + AND CX, PLANE_BITS ; Get Plane # + MOV CH, ALL_PLANES ; Get Initial Plane mask + SHL CH, CL ; And shift into position + AND CH, ALL_PLANES ; And mask to lower nibble + + MOV AL, 04 ; 4-Plane # = # of initial + SUB AL, CL ; shifts to align bit mask + MOV CL, AL ; Shift Count for SHL + + ;Get segment of character map + + OUT_8 SC_Index, MAP_MASK ; Setup Plane selections + INC DX ; DX -> SC_Data + + MOV AL, 08 ; 8 Lines to Process + MOV [BP].GPC_Lines, AL ; Save on Stack + + MOV DS, [BP].GPC_T_SETS ; Point to character set + +@GPC_DECODE_CHAR_BYTE: + + MOV SI, [BP].GPC_T_SETO ; Get DS:SI = String + + MOV BH, [SI] ; Get Bit Map + INC SI ; Point to Next Line + MOV [BP].GPC_T_SETO, SI ; And save new Pointer... + + CLR AX ; Clear AX + + CLR BL ; Clear BL + ROL BX, CL ; BL holds left edge bits + MOV SI, BX ; Use as Table Index + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @GPC_NO_LEFT1BITS ; Skip if No Pixels to set + + MOV AH, [BP].GPC_ColorF ; Get Foreground Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_LEFT1BITS: + XOR AL, CH ; Invert mask for Background + JZ @GPC_NO_LEFT0BITS ; Hey, no need for this + + MOV AH, [BP].GPC_ColorB ; Get background Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + + ;Now Do Middle/Last Band + +@GPC_NO_LEFT0BITS: + INC DI ; Point to next Byte + ROL BX, 4 ; Shift 4 bits + + MOV SI, BX ; Make Lookup Pointer + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @GPC_NO_MIDDLE1BITS ; Skip if no pixels to set + + MOV AH, [BP].GPC_ColorF ; Get Foreground Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_MIDDLE1BITS: + XOR AL, ALL_PLANES ; Invert mask for Background + JZ @GPC_NO_MIDDLE0BITS ; Hey, no need for this + + MOV AH, [BP].GPC_ColorB ; Get background Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_MIDDLE0BITS: + XOR CH, ALL_PLANES ; Invert Clip Mask + CMP CL, 4 ; Aligned by 4? + JZ @GPC_NEXT_LINE ; If so, Exit now.. + + INC DI ; Point to next Byte + ROL BX, 4 ; Shift 4 bits + + MOV SI, BX ; Make Lookup Pointer + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @GPC_NO_RIGHT1BITS ; Skip if No Pixels to set + + MOV AH, [BP].GPC_ColorF ; Get Foreground Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_RIGHT1BITS: + + XOR AL, CH ; Invert mask for Background + JZ @GPC_NO_RIGHT0BITS ; Hey, no need for this + + MOV AH, [BP].GPC_ColorB ; Get background Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_RIGHT0BITS: + DEC DI ; Adjust for Next Line Advance + +@GPC_NEXT_LINE: + ADD DI, [BP].GPC_Width ; Point to Next Line + XOR CH, CHAR_BITS ; Flip the Clip mask back + + DEC [BP].GPC_Lines ; Count Down Lines + JZ @GPC_EXIT ; Ok... Done! + + JMP @GPC_DECODE_CHAR_BYTE ; Again! Hey! + +@GPC_EXIT: + ADD SP, 08 ; Deallocate stack workspace + POPx DI, SI, DS, BP ; Restore Saved Registers + RET 10 ; Exit and Clean up Stack + +GPRINTC ENDP + + +;========================================== +;TGPRINTC (CharNum%, Xpos%, Ypos%, ColorF%) +;========================================== +; +; Transparently draws an ASCII Text Character using the +; currently selected 8x8 font on the active display page. +; +; ENTRY: CharNum = ASCII character # to draw +; Xpos = X position to draw Character at +; Ypos = Y position of to draw Character at +; ColorF = Color to draw text character in +; +; EXIT: No meaningful values returned +; + +TGP_STACK STRUC + TGP_Width DW ? ; Screen Width-1 + TGP_Lines DB ?,? ; Scan lines to Decode + TGP_T_SETS DW ? ; Saved Charset Segment + TGP_T_SETO DW ? ; Saved Charset Offset + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + TGP_ColorF DB ?,? ; Text Color + TGP_Ypos DW ? ; Y Position to Print at + TGP_Xpos DW ? ; X position to Print at + TGP_Char DB ?,? ; Character to Print +TGP_STACK ENDS + + PUBLIC TGPRINTC + +TGPRINTC PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + SUB SP, 8 ; Allocate WorkSpace on Stack + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, SCREEN_WIDTH ; Get Logical Line Width + MOV BX, AX ; BX = Screen Width + DEC BX ; = Screen Width-1 + MOV [BP].TGP_Width, BX ; Save for later use + + MUL [BP].TGP_Ypos ; Start of Line = Ypos * Width + ADD DI, AX ; DI -> Start of Line Ypos + + MOV AX, [BP].TGP_Xpos ; Get Xpos of Character + MOV CX, AX ; Save Copy of Xpos + SHR AX, 2 ; Bytes into Line = Xpos/4 + ADD DI, AX ; DI -> (Xpos, Ypos) + + ;Get Source ADDR of Character Bit Map & Save + + MOV AL, [BP].TGP_Char ; Get Character # + TEST AL, 080h ; Is Hi Bit Set? + JZ @TGP_LowChar ; Nope, use low char set ptr + + AND AL, 07Fh ; Mask Out Hi Bit + MOV BX, CHARSET_HI ; BX = Char Set Ptr:Offset + MOV DX, CHARSET_HI+2 ; DX = Char Set Ptr:Segment + JMP s @TGP_Set_Char ; Go Setup Character Ptr + +@TGP_LowChar: + + MOV BX, CHARSET_LOW ; BX = Char Set Ptr:Offset + MOV DX, CHARSET_LOW+2 ; DX = Char Set Ptr:Segment + +@TGP_Set_Char: + MOV [BP].TGP_T_SETS, DX ; Save Segment on Stack + + MOV AH, 0 ; Valid #'s are 0..127 + SHL AX, 3 ; * 8 Bytes Per Bitmap + ADD BX, AX ; BX = Offset of Selected char + MOV [BP].TGP_T_SETO, BX ; Save Offset on Stack + + AND CX, PLANE_BITS ; Get Plane # + MOV CH, ALL_PLANES ; Get Initial Plane mask + SHL CH, CL ; And shift into position + AND CH, ALL_PLANES ; And mask to lower nibble + + MOV AL, 04 ; 4-Plane # = # of initial + SUB AL, CL ; shifts to align bit mask + MOV CL, AL ; Shift Count for SHL + + ;Get segment of character map + + OUT_8 SC_Index, MAP_MASK ; Setup Plane selections + INC DX ; DX -> SC_Data + + MOV AL, 08 ; 8 Lines to Process + MOV [BP].TGP_Lines, AL ; Save on Stack + + MOV DS, [BP].TGP_T_SETS ; Point to character set + +@TGP_DECODE_CHAR_BYTE: + + MOV SI, [BP].TGP_T_SETO ; Get DS:SI = String + + MOV BH, [SI] ; Get Bit Map + INC SI ; Point to Next Line + MOV [BP].TGP_T_SETO, SI ; And save new Pointer... + + MOV AH, [BP].TGP_ColorF ; Get Foreground Color + + CLR BL ; Clear BL + ROL BX, CL ; BL holds left edge bits + MOV SI, BX ; Use as Table Index + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @TGP_NO_LEFT1BITS ; Skip if No Pixels to set + + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + + ;Now Do Middle/Last Band + +@TGP_NO_LEFT1BITS: + + INC DI ; Point to next Byte + ROL BX, 4 ; Shift 4 bits + + MOV SI, BX ; Make Lookup Pointer + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @TGP_NO_MIDDLE1BITS ; Skip if no pixels to set + + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@TGP_NO_MIDDLE1BITS: + XOR CH, ALL_PLANES ; Invert Clip Mask + CMP CL, 4 ; Aligned by 4? + JZ @TGP_NEXT_LINE ; If so, Exit now.. + + INC DI ; Point to next Byte + ROL BX, 4 ; Shift 4 bits + + MOV SI, BX ; Make Lookup Pointer + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @TGP_NO_RIGHT1BITS ; Skip if No Pixels to set + + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@TGP_NO_RIGHT1BITS: + + DEC DI ; Adjust for Next Line Advance + +@TGP_NEXT_LINE: + ADD DI, [BP].TGP_Width ; Point to Next Line + XOR CH, CHAR_BITS ; Flip the Clip mask back + + DEC [BP].TGP_Lines ; Count Down Lines + JZ @TGP_EXIT ; Ok... Done! + + JMP @TGP_DECODE_CHAR_BYTE ; Again! Hey! + +@TGP_EXIT: + ADD SP, 08 ; Deallocate stack workspace + POPx DI, SI, DS, BP ; Restore Saved Registers + RET 8 ; Exit and Clean up Stack + +TGPRINTC ENDP + + +;=============================================================== +;PRINT_STR (SEG String, MaxLen%, Xpos%, Ypos%, ColorF%, ColorB%) +;=============================================================== +; +; Routine to quickly Print a null terminated ASCII string on the +; active display page up to a maximum length. +; +; ENTRY: String = Far Pointer to ASCII string to print +; MaxLen = # of characters to print if no null found +; Xpos = X position to draw Text at +; Ypos = Y position of to draw Text at +; ColorF = Color to draw text in +; ColorB = Color to set background to +; +; EXIT: No meaningful values returned +; + +PS_STACK STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + PS_ColorB DW ? ; Background Color + PS_ColorF DW ? ; Text Color + PS_Ypos DW ? ; Y Position to Print at + PS_Xpos DW ? ; X position to Print at + PS_Len DW ? ; Maximum Length of string to print + PS_Text DW ?,? ; Far Ptr to Text String +PS_STACK ENDS + + PUBLIC PRINT_STR + +PRINT_STR PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + MOV BP, SP ; Set up Stack Frame + +@PS_Print_It: + + MOV CX, [BP].PS_Len ; Get Remaining text Length + JCXZ @PS_Exit ; Exit when out of text + + LES DI, d [BP].PS_Text ; ES:DI -> Current Char in Text + MOV AL, ES:[DI] ; AL = Text Character + AND AX, 00FFh ; Clear High Word + JZ @PS_Exit ; Exit if null character + + DEC [BP].PS_Len ; Remaining Text length-- + INC [BP].PS_Text ; Point to Next text char + + ; Set up Call to GPRINTC + + PUSH AX ; Set Character Parameter + MOV BX, [BP].PS_Xpos ; Get Xpos + PUSH BX ; Set Xpos Parameter + ADD BX, 8 ; Advance 1 Char to Right + MOV [BP].PS_Xpos, BX ; Save for next time through + + MOV BX, [BP].PS_Ypos ; Get Ypos + PUSH BX ; Set Ypos Parameter + + MOV BX, [BP].PS_ColorF ; Get Text Color + PUSH BX ; Set ColorF Parameter + + MOV BX, [BP].PS_ColorB ; Get Background Color + PUSH BX ; Set ColorB Parameter + + CALL f GPRINTC ; Print Character! + JMP s @PS_Print_It ; Process next character + +@PS_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + RET 14 ; Exit and Clean up Stack + +PRINT_STR ENDP + + +;================================================================ +;TPRINT_STR (SEG String, MaxLen%, Xpos%, Ypos%, ColorF%, ColorB%) +;================================================================ +; +; Routine to quickly transparently Print a null terminated ASCII +; string on the active display page up to a maximum length. +; +; ENTRY: String = Far Pointer to ASCII string to print +; MaxLen = # of characters to print if no null found +; Xpos = X position to draw Text at +; Ypos = Y position of to draw Text at +; ColorF = Color to draw text in +; +; EXIT: No meaningful values returned +; + +TPS_STACK STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + TPS_ColorF DW ? ; Text Color + TPS_Ypos DW ? ; Y Position to Print at + TPS_Xpos DW ? ; X position to Print at + TPS_Len DW ? ; Maximum Length of string to print + TPS_Text DW ?,? ; Far Ptr to Text String +TPS_STACK ENDS + + PUBLIC TPRINT_STR + +TPRINT_STR PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + MOV BP, SP ; Set up Stack Frame + +@TPS_Print_It: + + MOV CX, [BP].TPS_Len ; Get Remaining text Length + JCXZ @TPS_Exit ; Exit when out of text + + LES DI, d [BP].TPS_Text ; ES:DI -> Current Char in Text + MOV AL, ES:[DI] ; AL = Text Character + AND AX, 00FFh ; Clear High Word + JZ @TPS_Exit ; Exit if null character + + DEC [BP].TPS_Len ; Remaining Text length-- + INC [BP].TPS_Text ; Point to Next text char + + ; Set up Call to TGPRINTC + + PUSH AX ; Set Character Parameter + MOV BX, [BP].TPS_Xpos ; Get Xpos + PUSH BX ; Set Xpos Parameter + ADD BX, 8 ; Advance 1 Char to Right + MOV [BP].TPS_Xpos, BX ; Save for next time through + + MOV BX, [BP].TPS_Ypos ; Get Ypos + PUSH BX ; Set Ypos Parameter + + MOV BX, [BP].TPS_ColorF ; Get Text Color + PUSH BX ; Set ColorF Parameter + + CALL f TGPRINTC ; Print Character! + JMP s @TPS_Print_It ; Process next character + +@TPS_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + RET 12 ; Exit and Clean up Stack + +TPRINT_STR ENDP + + +;=========================================== +;SET_DISPLAY_FONT(SEG FontData, FontNumber%) +;=========================================== +; +; Allows the user to specify their own font data for +; wither the lower or upper 128 characters. +; +; ENTRY: FontData = Far Pointer to Font Bitmaps +; FontNumber = Which half of set this is +; = 0, Lower 128 characters +; = 1, Upper 128 characters +; +; EXIT: No meaningful values returned +; + +SDF_STACK STRUC + DW ? ; BP + DD ? ; Caller + SDF_Which DW ? ; Hi Table/Low Table Flag + SDF_Font DD ? ; Far Ptr to Font Table +SDF_STACK ENDS + + PUBLIC SET_DISPLAY_FONT + +SET_DISPLAY_FONT PROC FAR + + PUSH BP ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + LES DI, [BP].SDF_Font ; Get Far Ptr to Font + + MOV SI, o CHARSET_LOW ; Assume Lower 128 chars + TEST [BP].SDF_Which, 1 ; Font #1 selected? + JZ @SDF_Set_Font ; If not, skip ahead + + MOV SI, o CHARSET_HI ; Ah, really it's 128-255 + +@SDF_Set_Font: + MOV [SI], DI ; Set Font Pointer Offset + MOV [SI+2], ES ; Set Font Pointer Segment + + POP BP ; Restore Registers + RET 6 ; We are Done.. Outa here + +SET_DISPLAY_FONT ENDP + + + ; ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== + +;====================================================== +;DRAW_BITMAP (SEG Image, Xpos%, Ypos%, Width%, Height%) +;====================================================== +; +; Draws a variable sized Graphics Bitmap such as a +; picture or an Icon on the current Display Page in +; Mode X. The Bitmap is stored in a linear byte array +; corresponding to (0,0) (1,0), (2,0) .. (Width, Height) +; This is the same linear manner as mode 13h graphics. +; +; ENTRY: Image = Far Pointer to Bitmap Data +; Xpos = X position to Place Upper Left pixel at +; Ypos = Y position to Place Upper Left pixel at +; Width = Width of the Bitmap in Pixels +; Height = Height of the Bitmap in Pixels +; +; EXIT: No meaningful values returned +; + +DB_STACK STRUC + DB_LineO DW ? ; Offset to Next Line + DB_PixCount DW ? ; (Minimum) # of Pixels/Line + DB_Start DW ? ; Addr of Upper Left Pixel + DB_PixSkew DW ? ; # of bytes to Adjust EOL + DB_SkewFlag DW ? ; Extra Pix on Plane Flag + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + DB_Height DW ? ; Height of Bitmap in Pixels + DB_Width DW ? ; Width of Bitmap in Pixels + DB_Ypos DW ? ; Y position to Draw Bitmap at + DB_Xpos DW ? ; X position to Draw Bitmap at + DB_Image DD ? ; Far Pointer to Graphics Bitmap +DB_STACK ENDS + + PUBLIC DRAW_BITMAP + +DRAW_BITMAP PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + SUB SP, 10 ; Allocate workspace + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + CLD ; Direction Flag = Forward + + MOV AX, [BP].DB_Ypos ; Get UL Corner Ypos + MUL SCREEN_WIDTH ; AX = Offset to Line Ypos + + MOV BX, [BP].DB_Xpos ; Get UL Corner Xpos + MOV CL, BL ; Save Plane # in CL + SHR BX, 2 ; Xpos/4 = Offset Into Line + + ADD DI, AX ; ES:DI -> Start of Line + ADD DI, BX ; ES:DI -> Upper Left Pixel + MOV [BP].DB_Start, DI ; Save Starting Addr + + ; Compute line to line offset + + MOV BX, [BP].DB_Width ; Get Width of Image + MOV DX, BX ; Save Copy in DX + SHR BX, 2 ; /4 = width in bands + MOV AX, SCREEN_WIDTH ; Get Screen Width + SUB AX, BX ; - (Bitmap Width/4) + + MOV [BP].DB_LineO, AX ; Save Line Width offset + MOV [BP].DB_PixCount, BX ; Minimum # pix to copy + + AND DX, PLANE_BITS ; Get "partial band" size (0-3) + MOV [BP].DB_PixSkew, DX ; Also End of Line Skew + MOV [BP].DB_SkewFlag, DX ; Save as Flag/Count + + AND CX, PLANE_BITS ; CL = Starting Plane # + MOV AX, MAP_MASK_PLANE2 ; Plane Mask & Plane Select + SHL AH, CL ; Select correct Plane + OUT_16 SC_Index, AX ; Select Plane... + MOV BH, AH ; BH = Saved Plane Mask + MOV BL, 4 ; BL = Planes to Copy + +@DB_COPY_PLANE: + + LDS SI, [BP].DB_Image ; DS:SI-> Source Image + MOV DX, [BP].DB_Height ; # of Lines to Copy + MOV DI, [BP].DB_Start ; ES:DI-> Dest pos + +@DB_COPY_LINE: + MOV CX, [BP].DB_PixCount ; Min # to copy + + TEST CL, 0FCh ; 16+PixWide? + JZ @DB_COPY_REMAINDER ; Nope... + + ; Pixel Copy loop has been unrolled to x4 + +@DB_COPY_LOOP: + MOVSB ; Copy Bitmap Pixel + ADD SI, 3 ; Skip to Next Byte in same plane + MOVSB ; Copy Bitmap Pixel + ADD SI, 3 ; Skip to Next Byte in same plane + MOVSB ; Copy Bitmap Pixel + ADD SI, 3 ; Skip to Next Byte in same plane + MOVSB ; Copy Bitmap Pixel + ADD SI, 3 ; Skip to Next Byte in same plane + + SUB CL, 4 ; Pixels to Copy=-4 + TEST CL, 0FCh ; 4+ Pixels Left? + JNZ @DB_COPY_LOOP ; if so, do another block + +@DB_COPY_REMAINDER: + JCXZ @DB_NEXT_LINE ; Any Pixels left on line + +@DB_COPY2: + MOVSB ; Copy Bitmap Pixel + ADD SI,3 ; Skip to Next Byte in same plane + LOOPx CX, @DB_COPY2 ; Pixels to Copy--, Loop until done + +@DB_NEXT_LINE: + + ; any Partial Pixels? (some planes only) + + OR CX, [BP].DB_SkewFlag ; Get Skew Count + JZ @DB_NEXT2 ; if no partial pixels + + MOVSB ; Copy Bitmap Pixel + DEC DI ; Back up to align + DEC SI ; Back up to align + +@DB_NEXT2: + ADD SI, [BP].DB_PixSkew ; Adjust Skew + ADD DI, [BP].DB_LineO ; Set to Next Display Line + LOOPx DX, @DB_COPY_LINE ; Lines to Copy--, Loop if more + + ; Copy Next Plane.... + + DEC BL ; Planes to Go-- + JZ @DB_Exit ; Hey! We are done + + ROL BH, 1 ; Next Plane in line... + OUT_8 SC_Data, BH ; Select Plane + + CMP AL, 12h ; Carry Set if AL=11h + ADC [BP].DB_Start, 0 ; Screen Addr =+Carry + INC w [BP].DB_Image ; Start @ Next Byte + + SUB [BP].DB_SkewFlag, 1 ; Reduce Planes to Skew + ADC [BP].DB_SkewFlag, 0 ; Back to 0 if it was -1 + + JMP s @DB_COPY_PLANE ; Go Copy the Next Plane + +@DB_Exit: + ADD SP, 10 ; Deallocate workspace + POPx DI, SI, DS, BP ; Restore Saved Registers + RET 12 ; Exit and Clean up Stack + +DRAW_BITMAP ENDP + + +;======================================================= +;TDRAW_BITMAP (SEG Image, Xpos%, Ypos%, Width%, Height%) +;======================================================= +; +; Transparently Draws a variable sized Graphics Bitmap +; such as a picture or an Icon on the current Display Page +; in Mode X. Pixels with a value of 0 are not drawn, +; leaving the previous "background" contents intact. +; +; The Bitmap format is the same as for the DRAW_BITMAP function. +; +; ENTRY: Image = Far Pointer to Bitmap Data +; Xpos = X position to Place Upper Left pixel at +; Ypos = Y position to Place Upper Left pixel at +; Width = Width of the Bitmap in Pixels +; Height = Height of the Bitmap in Pixels +; +; EXIT: No meaningful values returned +; + +TB_STACK STRUC + TB_LineO DW ? ; Offset to Next Line + TB_PixCount DW ? ; (Minimum) # of Pixels/Line + TB_Start DW ? ; Addr of Upper Left Pixel + TB_PixSkew DW ? ; # of bytes to Adjust EOL + TB_SkewFlag DW ? ; Extra Pix on Plane Flag + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + TB_Height DW ? ; Height of Bitmap in Pixels + TB_Width DW ? ; Width of Bitmap in Pixels + TB_Ypos DW ? ; Y position to Draw Bitmap at + TB_Xpos DW ? ; X position to Draw Bitmap at + TB_Image DD ? ; Far Pointer to Graphics Bitmap +TB_STACK ENDS + + PUBLIC TDRAW_BITMAP + +TDRAW_BITMAP PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + SUB SP, 10 ; Allocate workspace + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + CLD ; Direction Flag = Forward + + MOV AX, [BP].TB_Ypos ; Get UL Corner Ypos + MUL SCREEN_WIDTH ; AX = Offset to Line Ypos + + MOV BX, [BP].TB_Xpos ; Get UL Corner Xpos + MOV CL, BL ; Save Plane # in CL + SHR BX, 2 ; Xpos/4 = Offset Into Line + + ADD DI, AX ; ES:DI -> Start of Line + ADD DI, BX ; ES:DI -> Upper Left Pixel + MOV [BP].TB_Start, DI ; Save Starting Addr + + ; Compute line to line offset + + MOV BX, [BP].TB_Width ; Get Width of Image + MOV DX, BX ; Save Copy in DX + SHR BX, 2 ; /4 = width in bands + MOV AX, SCREEN_WIDTH ; Get Screen Width + SUB AX, BX ; - (Bitmap Width/4) + + MOV [BP].TB_LineO, AX ; Save Line Width offset + MOV [BP].TB_PixCount, BX ; Minimum # pix to copy + + AND DX, PLANE_BITS ; Get "partial band" size (0-3) + MOV [BP].TB_PixSkew, DX ; Also End of Line Skew + MOV [BP].TB_SkewFlag, DX ; Save as Flag/Count + + AND CX, PLANE_BITS ; CL = Starting Plane # + MOV AX, MAP_MASK_PLANE2 ; Plane Mask & Plane Select + SHL AH, CL ; Select correct Plane + OUT_16 SC_Index, AX ; Select Plane... + MOV BH, AH ; BH = Saved Plane Mask + MOV BL, 4 ; BL = Planes to Copy + +@TB_COPY_PLANE: + + LDS SI, [BP].TB_Image ; DS:SI-> Source Image + MOV DX, [BP].TB_Height ; # of Lines to Copy + MOV DI, [BP].TB_Start ; ES:DI-> Dest pos + + ; Here AH is set with the value to be considered + ; "Transparent". It can be changed! + + MOV AH, 0 ; Value to Detect 0 + +@TB_COPY_LINE: + MOV CX, [BP].TB_PixCount ; Min # to copy + + TEST CL, 0FCh ; 16+PixWide? + JZ @TB_COPY_REMAINDER ; Nope... + + ; Pixel Copy loop has been unrolled to x4 + +@TB_COPY_LOOP: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_01 ; Skip ahead if so + MOV ES:[DI], AL ; Copy Pixel to VGA screen + +@TB_SKIP_01: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_02 ; Skip ahead if so + MOV ES:[DI+1], AL ; Copy Pixel to VGA screen + +@TB_SKIP_02: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_03 ; Skip ahead if so + MOV ES:[DI+2], AL ; Copy Pixel to VGA screen + +@TB_SKIP_03: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_04 ; Skip ahead if so + MOV ES:[DI+3], AL ; Copy Pixel to VGA screen + +@TB_SKIP_04: + ADD DI, 4 ; Adjust Pixel Write Location + SUB CL, 4 ; Pixels to Copy=-4 + TEST CL, 0FCh ; 4+ Pixels Left? + JNZ @TB_COPY_LOOP ; if so, do another block + +@TB_COPY_REMAINDER: + JCXZ @TB_NEXT_LINE ; Any Pixels left on line + +@TB_COPY2: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_05 ; Skip ahead if so + MOV ES:[DI], AL ; Copy Pixel to VGA screen + +@TB_SKIP_05: + INC DI ; Advance Dest Addr + LOOPx CX, @TB_COPY2 ; Pixels to Copy--, Loop until done + +@TB_NEXT_LINE: + + ; any Partial Pixels? (some planes only) + + OR CX, [BP].TB_SkewFlag ; Get Skew Count + JZ @TB_NEXT2 ; if no partial pixels + + LODSB ; Get Pixel Value in AL + DEC SI ; Backup to Align + CMP AL, AH ; It is "Transparent"? + JE @TB_NEXT2 ; Skip ahead if so + MOV ES:[DI], AL ; Copy Pixel to VGA screen + +@TB_NEXT2: + ADD SI, [BP].TB_PixSkew ; Adjust Skew + ADD DI, [BP].TB_LineO ; Set to Next Display Line + LOOPx DX, @TB_COPY_LINE ; Lines to Copy--, Loop if More + + ;Copy Next Plane.... + + DEC BL ; Planes to Go-- + JZ @TB_Exit ; Hey! We are done + + ROL BH, 1 ; Next Plane in line... + OUT_8 SC_Data, BH ; Select Plane + + CMP AL, 12h ; Carry Set if AL=11h + ADC [BP].TB_Start, 0 ; Screen Addr =+Carry + INC w [BP].TB_Image ; Start @ Next Byte + + SUB [BP].TB_SkewFlag, 1 ; Reduce Planes to Skew + ADC [BP].TB_SkewFlag, 0 ; Back to 0 if it was -1 + + JMP @TB_COPY_PLANE ; Go Copy the next Plane + +@TB_Exit: + ADD SP, 10 ; Deallocate workspace + POPx DI, SI, DS, BP ; Restore Saved Registers + RET 12 ; Exit and Clean up Stack + +TDRAW_BITMAP ENDP + + + ; ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== + +;================================== +;COPY_PAGE (SourcePage%, DestPage%) +;================================== +; +; Duplicate on display page onto another +; +; ENTRY: SourcePage = Display Page # to Duplicate +; DestPage = Display Page # to hold copy +; +; EXIT: No meaningful values returned +; + +CP_STACK STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + CP_DestP DW ? ; Page to hold copied image + CP_SourceP DW ? ; Page to Make copy from +CP_STACK ENDS + + PUBLIC COPY_PAGE + +COPY_PAGE PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + MOV BP, SP ; Set up Stack Frame + CLD ; Block Xfer Forwards + + ; Make sure Page #'s are valid + + MOV AX, [BP].CP_SourceP ; Get Source Page # + CMP AX, LAST_PAGE ; is it > Max Page #? + JAE @CP_Exit ; if so, abort + + MOV BX, [BP].CP_DestP ; Get Destination Page # + CMP BX, LAST_PAGE ; is it > Max Page #? + JAE @CP_Exit ; if so, abort + + CMP AX, BX ; Pages #'s the same? + JE @CP_Exit ; if so, abort + + ; Setup DS:SI and ES:DI to Video Pages + + SHL BX, 1 ; Scale index to Word + MOV DI, PAGE_ADDR[BX] ; Offset to Dest Page + + MOV BX, AX ; Index to Source page + SHL BX, 1 ; Scale index to Word + MOV SI, PAGE_ADDR[BX] ; Offset to Source Page + + MOV CX, PAGE_SIZE ; Get size of Page + MOV AX, CURRENT_SEGMENT ; Get Video Mem Segment + MOV ES, AX ; ES:DI -> Dest Page + MOV DS, AX ; DS:SI -> Source Page + + ; Setup VGA registers for Mem to Mem copy + + OUT_16 GC_Index, LATCHES_ON ; Data from Latches = on + OUT_16 SC_Index, ALL_PLANES_ON ; Copy all Planes + + ; Note.. Do *NOT* use MOVSW or MOVSD - they will + ; Screw with the latches which are 8 bits x 4 + + REP MOVSB ; Copy entire Page! + + ; Reset VGA for normal memory access + + OUT_16 GC_Index, LATCHES_OFF ; Data from Latches = off + +@CP_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + RET 4 ; Exit and Clean up Stack + +COPY_PAGE ENDP + + +;========================================================================== +;COPY_BITMAP (SourcePage%, X1%, Y1%, X2%, Y2%, DestPage%, DestX1%, DestY1%) +;========================================================================== +; +; Copies a Bitmap Image from one Display Page to Another +; This Routine is Limited to copying Images with the same +; Plane Alignment. To Work: (X1 MOD 4) must = (DestX1 MOD 4) +; Copying an Image to the Same Page is supported, but results +; may be defined when the when the rectangular areas +; (X1, Y1) - (X2, Y2) and (DestX1, DestY1) - +; (DestX1+(X2-X1), DestY1+(Y2-Y1)) overlap... +; No Paramter checking to done to insure that +; X2 >= X1 and Y2 >= Y1. Be Careful... +; +; ENTRY: SourcePage = Display Page # with Source Image +; X1 = Upper Left Xpos of Source Image +; Y1 = Upper Left Ypos of Source Image +; X2 = Lower Right Xpos of Source Image +; Y2 = Lower Right Ypos of Source Image +; DestPage = Display Page # to copy Image to +; DestX1 = Xpos to Copy UL Corner of Image to +; DestY1 = Ypos to Copy UL Corner of Image to +; +; EXIT: AX = Success Flag: 0 = Failure / -1= Success +; + +CB_STACK STRUC + CB_Height DW ? ; Height of Image in Lines + CB_Width DW ? ; Width of Image in "bands" + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + CB_DestY1 DW ? ; Destination Ypos + CB_DestX1 DW ? ; Destination Xpos + CB_DestP DW ? ; Page to Copy Bitmap To + CB_Y2 DW ? ; LR Ypos of Image + CB_X2 DW ? ; LR Xpos of Image + CB_Y1 DW ? ; UL Ypos of Image + CB_X1 DW ? ; UL Xpos of Image + CB_SourceP DW ? ; Page containing Source Bitmap +CB_STACK ENDS + + PUBLIC COPY_BITMAP + +COPY_BITMAP PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + SUB SP, 4 ; Allocate WorkSpace on Stack + MOV BP, SP ; Set up Stack Frame + + ; Prep Registers (and keep jumps short!) + + MOV ES, CURRENT_SEGMENT ; ES -> VGA Ram + CLD ; Block Xfer Forwards + + ; Make sure Parameters are valid + + MOV BX, [BP].CB_SourceP ; Get Source Page # + CMP BX, LAST_PAGE ; is it > Max Page #? + JAE @CB_Abort ; if so, abort + + MOV CX, [BP].CB_DestP ; Get Destination Page # + CMP CX, LAST_PAGE ; is it > Max Page #? + JAE @CB_Abort ; if so, abort + + MOV AX, [BP].CB_X1 ; Get Source X1 + XOR AX, [BP].CB_DestX1 ; Compare Bits 0-1 + AND AX, PLANE_BITS ; Check Plane Bits + JNZ @CB_Abort ; They should cancel out + + ; Setup for Copy processing + + OUT_8 SC_INDEX, MAP_MASK ; Set up for Plane Select + OUT_16 GC_Index, LATCHES_ON ; Data from Latches = on + + ; Compute Info About Images, Setup ES:SI & ES:DI + + MOV AX, [BP].CB_Y2 ; Height of Bitmap in lines + SUB AX, [BP].CB_Y1 ; is Y2 - Y1 + 1 + INC AX ; (add 1 since were not 0 based) + MOV [BP].CB_Height, AX ; Save on Stack for later use + + MOV AX, [BP].CB_X2 ; Get # of "Bands" of 4 Pixels + MOV DX, [BP].CB_X1 ; the Bitmap Occupies as X2-X1 + SHR AX, 2 ; Get X2 Band (X2 / 4) + SHR DX, 2 ; Get X1 Band (X1 / 4) + SUB AX, DX ; AX = # of Bands - 1 + INC AX ; AX = # of Bands + MOV [BP].CB_Width, AX ; Save on Stack for later use + + SHL BX, 1 ; Scale Source Page to Word + MOV SI, PAGE_ADDR[BX] ; SI = Offset of Source Page + MOV AX, [BP].CB_Y1 ; Get Source Y1 Line + MUL SCREEN_WIDTH ; AX = Offset to Line Y1 + ADD SI, AX ; SI = Offset to Line Y1 + MOV AX, [BP].CB_X1 ; Get Source X1 + SHR AX, 2 ; X1 / 4 = Byte offset + ADD SI, AX ; SI = Byte Offset to (X1,Y1) + + MOV BX, CX ; Dest Page Index to BX + SHL BX, 1 ; Scale Source Page to Word + MOV DI, PAGE_ADDR[BX] ; DI = Offset of Dest Page + MOV AX, [BP].CB_DestY1 ; Get Dest Y1 Line + MUL SCREEN_WIDTH ; AX = Offset to Line Y1 + ADD DI, AX ; DI = Offset to Line Y1 + MOV AX, [BP].CB_DestX1 ; Get Dest X1 + SHR AX, 2 ; X1 / 4 = Byte offset + ADD DI, AX ; DI = Byte Offset to (D-X1,D-Y1) + + MOV CX, [BP].CB_Width ; CX = Width of Image (Bands) + DEC CX ; CX = 1? + JE @CB_Only_One_Band ; 0 Means Image Width of 1 Band + + MOV BX, [BP].CB_X1 ; Get Source X1 + AND BX, PLANE_BITS ; Aligned? (bits 0-1 = 00?) + JZ @CB_Check_Right ; if so, check right alignment + JNZ @CB_Left_Band ; not aligned? well.. + +@CB_Abort: + CLR AX ; Return False (Failure) + JMP @CB_Exit ; and Finish Up + + ; Copy when Left & Right Clip Masks overlap... + +@CB_Only_One_Band: + MOV BX, [BP].CB_X1 ; Get Left Clip Mask + AND BX, PLANE_BITS ; Mask out Row # + MOV AL, Left_Clip_Mask[BX] ; Get Left Edge Mask + MOV BX, [BP].CB_X2 ; Get Right Clip Mask + AND BX, PLANE_BITS ; Mask out Row # + AND AL, Right_Clip_Mask[BX] ; Get Right Edge Mask byte + + OUT_8 SC_Data, AL ; Clip For Left & Right Masks + + MOV CX, [BP].CB_Height ; CX = # of Lines to Copy + MOV DX, SCREEN_WIDTH ; DX = Width of Screen + CLR BX ; BX = Offset into Image + +@CB_One_Loop: + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPjz CX, @CB_One_Done ; Exit Loop if Finished + + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPx CX, @CB_One_Loop ; Loop until Finished + +@CB_One_Done: + JMP @CB_Finish ; Outa Here! + + ; Copy Left Edge of Bitmap + +@CB_Left_Band: + + OUT_8 SC_Data, Left_Clip_Mask[BX] ; Set Left Edge Plane Mask + + MOV CX, [BP].CB_Height ; CX = # of Lines to Copy + MOV DX, SCREEN_WIDTH ; DX = Width of Screen + CLR BX ; BX = Offset into Image + +@CB_Left_Loop: + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPjz CX, @CB_Left_Done ; Exit Loop if Finished + + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPx CX, @CB_Left_Loop ; Loop until Finished + +@CB_Left_Done: + INC DI ; Move Dest Over 1 band + INC SI ; Move Source Over 1 band + DEC [BP].CB_Width ; Band Width-- + + ; Determine if Right Edge of Bitmap needs special copy + +@CB_Check_Right: + MOV BX, [BP].CB_X2 ; Get Source X2 + AND BX, PLANE_BITS ; Aligned? (bits 0-1 = 11?) + CMP BL, 03h ; Plane = 3? + JE @CB_Copy_Middle ; Copy the Middle then! + + ; Copy Right Edge of Bitmap + +@CB_Right_Band: + + OUT_8 SC_Data, Right_Clip_Mask[BX] ; Set Right Edge Plane Mask + + DEC [BP].CB_Width ; Band Width-- + MOV CX, [BP].CB_Height ; CX = # of Lines to Copy + MOV DX, SCREEN_WIDTH ; DX = Width of Screen + MOV BX, [BP].CB_Width ; BX = Offset to Right Edge + +@CB_Right_Loop: + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPjz CX, @CB_Right_Done ; Exit Loop if Finished + + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPx CX, @CB_Right_Loop ; Loop until Finished + +@CB_Right_Done: + + ; Copy the Main Block of the Bitmap + +@CB_Copy_Middle: + + MOV CX, [BP].CB_Width ; Get Width Remaining + JCXZ @CB_Finish ; Exit if Done + + OUT_8 SC_Data, ALL_PLANES ; Copy all Planes + + MOV DX, SCREEN_WIDTH ; Get Width of Screen minus + SUB DX, CX ; Image width (for Adjustment) + MOV AX, [BP].CB_Height ; AX = # of Lines to Copy + MOV BX, CX ; BX = Quick REP reload count + MOV CX, ES ; Move VGA Segment + MOV DS, CX ; Into DS + + ; Actual Copy Loop. REP MOVSB does the work + +@CB_Middle_Copy: + MOV CX, BX ; Recharge Rep Count + REP MOVSB ; Move Bands + LOOPjz AX, @CB_Finish ; Exit Loop if Finished + + ADD SI, DX ; Adjust DS:SI to Next Line + ADD DI, DX ; Adjust ES:DI to Next Line + + MOV CX, BX ; Recharge Rep Count + REP MOVSB ; Move Bands + + ADD SI, DX ; Adjust DS:SI to Next Line + ADD DI, DX ; Adjust ES:DI to Next Line + LOOPx AX, @CB_Middle_Copy ; Copy Lines until Done + +@CB_Finish: + OUT_16 GC_Index, LATCHES_OFF ; Data from Latches = on + +@CB_Exit: + ADD SP, 04 ; Deallocate stack workspace + POPx DI, SI, DS, BP ; Restore Saved Registers + RET 16 ; Exit and Clean up Stack + +COPY_BITMAP ENDP + + END ; End of Code Segment diff --git a/16/modex105/MODEX.BI b/16/modex105/MODEX.BI new file mode 100644 index 00000000..6b1d7afe --- /dev/null +++ b/16/modex105/MODEX.BI @@ -0,0 +1,63 @@ + + ' ===== SCREEN RESOLUTIONS ===== + +CONST Mode320x200 = 0, Mode320x400 = 1 +CONST Mode360x200 = 2, Mode360x400 = 3 +CONST Mode320x240 = 4, Mode320x480 = 5 +CONST Mode360x240 = 6, Mode360x480 = 7 + + ' ===== MODE X SETUP ROUTINES ===== + +DECLARE FUNCTION SET.VGA.MODEX% ALIAS "SET_VGA_MODEX" (BYVAL ModeType%, BYVAL MaxXpos%, BYVAL MaxYpos%, BYVAL Pages%) +DECLARE FUNCTION SET.MODEX% ALIAS "SET_MODEX" (BYVAL Mode%) + + ' ===== BASIC GRAPHICS PRIMITIVES ===== + +DECLARE SUB CLEAR.VGA.SCREEN ALIAS "CLEAR_VGA_SCREEN" (BYVAL ColorNum%) +DECLARE SUB SET.POINT ALIAS "SET_POINT" (BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorNum%) +DECLARE FUNCTION READ.POINT% ALIAS "READ_POINT" (BYVAL Xpos%, BYVAL Ypos%) +DECLARE SUB FILL.BLOCK ALIAS "FILL_BLOCK" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) +DECLARE SUB DRAW.LINE ALIAS "DRAW_LINE" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) + + ' ===== DAC COLOR REGISTER ROUTINES ===== + +DECLARE SUB SET.DAC.REGISTER ALIAS "SET_DAC_REGISTER" (BYVAL RegNo%, BYVAL Red%, BYVAL Green%, BYVAL Blue%) +DECLARE SUB GET.DAC.REGISTER ALIAS "GET_DAC_REGISTER" (BYVAL RegNo%, Red%, Green%, Blue%) +DECLARE SUB LOAD.DAC.REGISTERS ALIAS "LOAD_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%, BYVAL VSync%) +DECLARE SUB READ.DAC.REGISTERS ALIAS "READ_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%) + + + ' ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== + +DECLARE SUB SET.ACTIVE.PAGE ALIAS "SET_ACTIVE_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.ACTIVE.PAGE% ALIAS "GET_ACTIVE_PAGE" +DECLARE SUB SET.DISPLAY.PAGE ALIAS "SET_DISPLAY_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.DISPLAY.PAGE% ALIAS "GET_DISPLAY_PAGE" +DECLARE SUB SET.WINDOW ALIAS "SET_WINDOW" (BYVAL DisplayPage%, BYVAL XOffset%, BYVAL YOffset%) +DECLARE FUNCTION GET.X.OFFSET% ALIAS "GET_X_OFFSET" () +DECLARE FUNCTION GET.Y.OFFSET% ALIAS "GET_Y_OFFSET" () +DECLARE SUB SYNC.DISPLAY ALIAS "SYNC_DISPLAY" + + ' ===== TEXT DISPLAY ROUTINES ===== + +DECLARE SUB GPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TGPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB PRINT.STR ALIAS "PRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TPRINT.STR ALIAS "TPRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB SET.DISPLAY.FONT ALIAS "SET_DISPLAY_FONT" (SEG FontData AS ANY, BYVAL FontNumber%) + + ' ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== + +DECLARE SUB DRAW.BITMAP ALIAS "DRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) +DECLARE SUB TDRAW.BITMAP ALIAS "TDRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) + + ' ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== + +DECLARE SUB COPY.PAGE ALIAS "COPY_PAGE" (BYVAL SourcePage%, BYVAL DestPage%) +DECLARE SUB COPY.BITMAP ALIAS "COPY_BITMAP" (BYVAL SourcePage%, BYVAL X1%, BYVAL Y1%, BYVAL X2%, BYVAL Y2%, BYVAL DestPage%, BYVAL DestX1%, BYVAL DestY1%) + + + + + + diff --git a/16/modex105/MODEX.H b/16/modex105/MODEX.H new file mode 100644 index 00000000..7de25a63 --- /dev/null +++ b/16/modex105/MODEX.H @@ -0,0 +1,76 @@ + +#ifndef __MODEX_H +#define __MODEX_H + + /* ===== SCREEN RESOLUTIONS ===== */ + +#define Mode_320x200 0 +#define Mode_320x400 1 +#define Mode_360x200 2 +#define Mode_360x400 3 +#define Mode_320x240 4 +#define Mode_320x480 5 +#define Mode_360x240 6 +#define Mode_360x480 7 + + /* ===== MODE X SETUP ROUTINES ===== */ + +int far pascal set_vga_modex (int Mode, int MaxXpos, int MaxYpos, int Pages); +int far pascal set_modex (int Mode); + + /* ===== BASIC GRAPHICS PRIMITIVES ===== */ + +void far pascal clear_vga_screen (int Color); +void far pascal set_point (int Xpos, int Ypos, int Color); +int far pascal read_point (int Xpos, int Ypos); +void far pascal fill_block (int Xpos1, int Ypos1, int Xpos2, int Ypos2, + int Color); +void far pascal draw_line (int Xpos1, int Ypos1, int Xpos2, int Ypos2, + int Color); + + /* ===== DAC COLOR REGISTER ROUTINES ===== */ + +void far pascal set_dac_register (int RegNo, int Red, int Green, int Blue); +void far pascal get_dac_register (int RegNo, int* Red, int* Green, int* Blue); +void far pascal load_dac_registers (char far *PalData, int StartReg, + int EndReg, int VSync); +void far pascal readd_dac_registers (char far *PalData, int StartReg, + int EndReg); + + /* ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== */ + +void far pascal set_active_page (int PageNo); +int far pascal get_active_page (void); +void far pascal set_display_page (int PageNo); +int far pascal get_display_page (void); +void far pascal set_window (int DisplayPage, int XOffset, int YOffset); +int far pascal get_x_offset (void); +int far pascal get_y_offset (void); +void far pascal sync_display (void); + + /* ===== TEXT DISPLAY ROUTINES ===== */ + +void far pascal gprintc (int CharNum, int Xpos, int Ypos, int ColorF, + int ColorB); +void far pascal tgprintc (int CharNum, int Xpos, int Ypos, int ColorF); +void far pascal print_str (char far *Text, int MaxLen, int Xpos, int Ypos, + int ColorF, int ColorB); +void far pascal tprint_str (char far *Text, int MaxLen, int Xpos, int Ypos, + int ColorF); +void far pascal set_display_font (char far *FontData, int FontNumber); + + /* ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== */ + +void far pascal draw_bitmap (char far *Image, int Xpos, int Ypos, + int Width, int Height); +void far pascal tdraw_bitmap (char far *Image, int Xpos, int Ypos, + int Width, int Height); + + /* ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== */ + +void far pascal copy_page (int SourcePage, int DestPage); +void far pascal copy_bitmap (int SourcePage, int X1, int Y1, int X2, int Y2, + int DestPage, int DestX1, int DestY1); + + +#endif diff --git a/16/modex105/PACKING.LST b/16/modex105/PACKING.LST new file mode 100644 index 00000000..88f817ca --- /dev/null +++ b/16/modex105/PACKING.LST @@ -0,0 +1,87 @@ + +PACKING LIST FOR MODEX104 + +DIRECTORY: \ - The Mode X Library versoon 1.04 + +ASM BAT 26 05-14-93 6:00p - Batch File to Assemble MODEX.ASM +MODE-X TXT 2135 05-14-93 6:00p - File Describing MODE X Routines +MODEX ASM 117039 05-14-93 6:00p - Assembly source to Mode X Library +MODEX BI 3238 05-14-93 6:00p - Include File for BASIC/PDS +MODEX H 2943 05-14-93 6:00p - Include File for C/C++ +MODEX OBJ 5208 05-14-93 6:00p - The Mode X Library +README DOC 3259 05-14-93 6:00p - Information on this Product +PACKING LST 4767 05-14-93 6:00p - This File + +DIRECTORY: \DEMOS - Mode X Demos + +CHARDEMO EXE 13066 05-14-93 6:00p - Demo of Multiple Fonts & Color Cycling +TEST6 EXE 19990 05-14-93 6:00p - Main Mode X Demo +ROM_8X8 FNT 1024 05-14-93 6:00p - Font for CHARDEMO.EXE +SPACEAGE FNT 1024 05-14-93 6:00p - Font for CHARDEMO.EXE +SYSTEM FNT 1024 05-14-93 6:00p - Font for CHARDEMO.EXE + +DIRECTORY: \DEMOS\BASIC7 - Demo Sources for Microsoft BASIC 7.1 (PDS) + +MAKE-LIB BAT 166 05-14-93 6:00p - Batch File to make MODEX.LIB/.QLB +MODEX BI 3238 05-14-93 6:00p - Include File for MODE X Library +MODEX LIB 7189 05-14-93 6:00p - Mode X & Utility Libraries for QBX +MODEX OBJ 5208 05-14-93 6:00p - Mode X Library - Object File +MODEX QLB 11141 05-14-93 6:00p - Mode X & Utility Quick Library +TEST6 BAS 12733 05-14-93 6:00p - Main Demo Source Code (TEST6.EXE) +UASM-BC7 BAT 43 05-14-93 6:00p - Batch file to Make UTILS.OBJ for QBX +UTILS ASM 8506 05-14-93 6:00p - Basic Utilities - Assembler source +UTILS BI 2028 05-14-93 6:00p - Basic Utilities - Basic Includes +UTILS OBJ 681 05-14-93 6:00p - Basic Utilities - Object File +CHARDEMO BAS 3431 05-14-93 6:00p - Source to CHARDEMO.EXE + +DIRECTORY: \DEMOS\C - Demo Sources for Borland C/C++ + +C_UTILS ASM 8782 05-14-93 6:00p - C Utilities - Assembler source +C_UTILS H 2623 05-14-93 6:00p - C Utilities - C Includes +C_UTILS OBJ 648 05-14-93 6:00p - C Utilities - Object File +MODEX H 2943 05-14-93 6:00p - Mode X Library C Incldues +MODEX OBJ 5208 05-14-93 6:00p - Mode X Library +UTLS-ASM BAT 36 05-14-93 6:00p - Batch File to Make C_UTILS.OBJ +X-DEMO C 15085 05-14-93 6:00p - Source to Main Demo (TEST6) in C +X-DEMO EXE 41090 05-14-93 6:00p - C Version of Main Demo +X-DEMO PRJ 5188 05-14-93 6:00p - Borland C Project file + +DIRECTORY: \DEMOS\PASCAL - Demo Sources for Turbo Pascal + +TEST5 PAS 15873 05-14-93 6:00p - Source for a TP Version of TEST6.EXE + +DIRECTORY: \DEMOS\QB45 - Demo Sources for Microsoft QuickBASIC 4.5 + +MAKE-LIB BAT 164 05-14-93 6:00p - Batch File to make MODEX.LIB/.QLB +MODEX BI 3238 05-14-93 6:00p - Include File for MODE X Library +MODEX LIB 7189 05-14-93 6:00p - Mode X & Utility Libraries for QB45 +MODEX OBJ 5208 05-14-93 6:00p - Mode X Library - Object File +MODEX QLB 9739 05-14-93 6:00p - Mode X & Utility Quick Library/QB45 +TEST6A BAS 12743 05-14-93 6:00p - Main Demo Source Code (TEST6.EXE) +TEST6A EXE 40544 05-14-93 6:00p - QB45 Version of Main Demo +UASM-QB4 BAT 30 05-14-93 6:00p - Batch file to Make UTILS.OBJ for QB45 +UTILS ASM 8506 05-14-93 6:00p - Basic Utilities - Assembler source +UTILS BI 2028 05-14-93 6:00p - Basic Utilities - Basic Includes +UTILS OBJ 628 05-14-93 6:00p - Basic Utilities - Object File + +DIRECTORY: \FONTEDIT - Font Editor + +CSEDIT EXE 39242 05-14-93 6:00p - Font Editor Program +CSEDIT DOC 8629 05-14-93 6:00p - Font Editor Documentation +CHARSETS CS 2144 05-14-93 6:00p - Internal Fonts for Editor +MOUSEIMG CS 128 05-14-93 6:00p - Mouse Pointers for Editor +PALETTE CS 768 05-14-93 6:00p - Palette for Editor +INVERSE FNT 1024 05-14-93 6:00p - Sample Font +ROM_8X8 FNT 1024 05-14-93 6:00p - Sample Font +SPACEAGE FNT 1024 05-14-93 6:00p - Sample Font +SYSTEM FNT 1024 05-14-93 6:00p - Sample Font + +DIRECTORY: \PALEDIT - Palette Editor + +PALEDIT EXE 31954 05-14-93 6:00p - Palette Editor Program +PALEDIT DOC 6688 05-14-93 6:00p - Palette Editor Documentation +CHARSETS CS 2144 05-14-93 6:00p - Internal Fonts for Editor +MOUSEIMG CS 128 05-14-93 6:00p - Mouse Pointers for Editor +GAMECOLR PAL 768 05-14-93 6:00p - Sample Palette +PRIME PAL 768 05-14-93 6:00p - Sample Palette +RGB PAL 768 05-14-93 6:00p - Sample Palette diff --git a/16/modex105/PALEDIT/CHARSETS.CS b/16/modex105/PALEDIT/CHARSETS.CS new file mode 100644 index 0000000000000000000000000000000000000000..97fe608ff81e4b78105a52984687b21a8a166ff7 GIT binary patch literal 2144 zcmZuxJ!l+96n;6MS4UXnt-=-}41|Eng%sK1kQZ45l?FE{#|SwoHp$@#voXtha@dX{ zQYfmTCagt@!<7qF0>fazkYW)cg-{{Pq!F&fRpE+dlJCu4ehhhcyPv){@Bht-sFQSU z?`Ur=rF3mP9s`G~&wl*=$?EXx>WcWGqImeQw?g*Kn|B$j<8L9yRdu}o^5y<<<={3R zJ91BVemh_^&-b1i&-V^qIlB4L%_JF3?W2uH8ylZp>f!4Cv;EZ}DLZpBtEjiQ;#L-W z6c4L7u75%mXAG#CsbTFza*OjM2!4p3-Wj(2t#=j~I%LJ8fw*LYP9bC>57Rj1{9ZA7Mt z6KS4Onx_vgng8 z5ChN7E_A{E#u-DcG5iJBS|ct9q$P*ET4SFcHJ_hw-p*IT;K*e|=JU&VGnr1~~8H#+(P@Jm%Ot$eFuBJd>w6;$lt( zZ_xR{Vt$gPB+U&6Ju11bu*7}I%|Ck}`V-5W(=w<`MO-ZROI!i+W5yLm>$%e<4W%p) z7`$kjGQ>J~AGk9ZCWI)&)d=%cYd-+8T!t)QpYs5Kexkqot2Z4Fs z`R41b%`e0!UwyeH{!fS&ZY*{lZ@m|a$Iauzf)uuYju0V`tBS9351aLIx zKoYE`puPCvqHV#G^>wrnw9VmR)6&9HxV5`0DPT3nNkt;8{TC0{5AmfyPur=6UpQ=s zxYo!wnILk%u4}5ni%GGJ-#Ow4ghL)og!7>;E{stKtVwWvI2Xw*@hE4KQLFRa)0hVH z{}+J}BY08(?-3mP)Jab%MT$7DR|L0b_`tuYN6S;-uczYEpKvZ!rX1M!Z2JyuC%E7IvA=GDa(`>QD+soN|ACXgvqk-8t6F z`g+b`2YrteKAa~bA0JsVwj+xV5RCQLr_l%|@VE1Ph*N`Wpk_V#vYyv-u06L(E9KAY zn$Pj}eir>RM^&{1s#<$J!mwX3n@lF#&_nC>86X2k^*$bR_5;^75OWrqIpVS%j_3Kj zU$BjM*bnsZ?9kg;v}e&js#Nd~5GEQhM;P#a24hIyzo+2B|8*@NyU3c zKhoDl(t4iF`zI7CEZbYo-&2HyY)=?K#(E3@obyW5K^Oq{Pa2IdqU?;31F1O*Ao42S zpH^MH76I4}Zg!5~0c~&l{;AHgn)NV{g3yP^a9{fpdzW07LSf8BB*6Q(VGO|>EaR=u c@7}+=v9)<$+}Yd`AAF4Uy(KWY!FGSkU-|#d0ssI2 literal 0 HcmV?d00001 diff --git a/16/modex105/PALEDIT/GAMECOLR.PAL b/16/modex105/PALEDIT/GAMECOLR.PAL new file mode 100644 index 0000000000000000000000000000000000000000..621b1e5e0e8a6bdd054160a76df79c41ed16cb60 GIT binary patch literal 768 zcmbV};i}>=5QV=V{ZZuhLc}5w0$MS6i*`%&nsp;R@Bdai@dcK(N!vFYzrI<7GXD-dFIX2(s-WZI;c#O)}jL4N_^8 zTcu8u)7UF|4Pgnx;^Wefi<_1%Ep1+!vLNT!Y}jtu?JDGc&+$l%HZrbP=9$}#$AjmS z*Na+Q6g63GQa8zs>ZAOi5HxtjUZd00DYeRtim4rL!)D8N$Ihm-XMf}viC>HtuD_TQ zw{IT5c@|#g$5NW2HtQqFP3lMas4(adbn^P@b#;~O(dtj5s{bLtd&Hga3vnS?g@jJX YqmSBdQG+6i^ro%x_>On~3fi#v3oGhTWdHyG literal 0 HcmV?d00001 diff --git a/16/modex105/PALEDIT/MOUSEIMG.CS b/16/modex105/PALEDIT/MOUSEIMG.CS new file mode 100644 index 0000000000000000000000000000000000000000..101e2084b44a2da8647ea004e20ffc599897dc29 GIT binary patch literal 128 zcmXwwyA6Xt5JVqBG8vc(jsUrhb3`33!65-+x3nvTG6*aUE5LfeXnx8{>eQ%KC5%j> xL+EL0E7_Ch82ppy6n|(>dLPTn2m0He)d4^WFp&TN literal 0 HcmV?d00001 diff --git a/16/modex105/PALEDIT/PALEDIT.DOC b/16/modex105/PALEDIT/PALEDIT.DOC new file mode 100644 index 00000000..61d0b2ee --- /dev/null +++ b/16/modex105/PALEDIT/PALEDIT.DOC @@ -0,0 +1,166 @@ + +PALEDIT - A Simple VGA 256 Color Palette Editor + + +PALEDIT is distributed with MODEXnnn.ZIP, the general purpose MODE X +Library for VGA Graphics. + +WHAT YOU NEED TO RUN PALEDIT: + + * A Vga Monitor + * A Microsoft Compatible Mouse + + A Mouse is most definitely required, as the keyboard is used for + nothing except entering file names. + +FILES NEEDED IN THE CURRENT DIRECTORY: + + PALEDIT.EXE - The Palette Editor Program + CHARSETS.CS - The Palette Editor's Internal Fonts + MOUSEIMG.CS - The Palette Editor's Mouse Pointer + +SAMPLE PALETTE FILE THAT SHOULD BE INCLUDED: + + RGB.PAL - A Simple Palette with Reds, Greens, and Blues + PRIME.PAL - A Simple Palette + GAMECOLR.PAL - A Bright Palette from a Game of mine. + +WHAT IT EDITS: + + The VGA DAC Registers, all 256 of them. + +HOW IT WORKS/FEATURES: + + PALEDIT allows the user to see the entire VGA Palette of 256 colors + and select and modify the RED, GREEN, and BLUE values of any individual + color (DAC) register. The entire group of 256 colors can be saved to + a disk file for later retrieval. + + Individual "SLIDERS" show the current RED, GREEN, and BLUE color + components of the current color and allow them to be changed. + + The Following operations can be performed. + + * Raise, Lower, and set the RED, GREEN, or BLUE components. + * Copy the current RGB values to another Color (DAC) Register + * Brighten the selected color + * Darken and selected color + * Reset the selected color to its original state + * Blend an entire range of colors, creating a smooth + Transition from one color to another + * Optionally Lock out the first 16 colors to prevent + Accidental Modification + +DESCRIPTION OF OBJECTS/FEATURES FROM THE TOP DOWN: + + COLOR SLIDERS: In the upper left of the screen there are + Three Rectangular Boxes: One for each primary color: + RED, GREEN, and BLUE. Each Box has an arrow at each + end, and a scale bar in the middle, connecting the two + arrows. The scale bar is much like a thermometer, + indicating how much of that color is in the selected + color. To the right of each Box, the name of the color + is indicated, along with the content color in the form + of a number from 0 to 63; where 0 means none of that + color goes into making the selected color, and 63 means + that the selected color is saturated with that color. + + Clicking the mouse on the slider's left arrow box will + decrease the amount of that primary color in the selected + color. Holding the mouse button down will reduce the + color value all the way to 0. + + Clicking the mouse on the slider's right arrow box will + increase the amount of that primary color in the selected + color. Holding the mouse button down will increase the + color value all the way to 63. + + Clicking the mouse on the scale bar will set the amount + of that primary color to the value the represents that + position on the slider. + + LOCK Button: Clicking the button toggles the lockout of the + first 16 colors. When they are locked out, they can not + be modified, and when selected the word "LOCKED" will + appear below the color # on the Color Information Display. + + LOAD Button: Clicking this button will load the Palette file + that is named in the Palette File name box. If no name is + given or no such file exists, then nothing will be loaded. + + SAVE Button: Clicking this button will save the current Palette + in a file using the name given in the Palette File Name Box. + If a Valid name is not provided, nothing will be saved. + + QUIT Button: Clicking this button will return you to DOS. + Nothing is saved, and no confirmation is given. + + + Color Information Display: This Box is on the left side of the + Screen, below the Color Sliders. It shows the number of the + currently selected color (from 0 to 255) and indicates if + that color is locked. To the right of this box is a big + square showing the current color. + + LIGHTER Button: Clicking this button will make the selected + color brighter. + + DARKER Button: Clicking this button will make the selected + color darker. + + RESET Button: Clicking this button will restore the selected + color to the value it had when it was first selected. + + BLEND Button: Clicking this button will let you Blend a range + of colors together. One end of the range of colors is the + currently selected color. After Clicking the BLEND button. + You must click on the color at the other end of the range + in the Palette Display Box. All of the colors in between + those two colors will be changed to represent a gradual + transition from the color at one end to the color at the + other end. + + PALETTE FILE NAME BOX: This Text Box is used to enter the name + of a Palette file to load or the name to save the current + Palette as. Just click on the Box, and it will change color + and a flashing cursor will appear. Now you type in a filename + or edit the existing filename. Press or click + outside the text box to end editing. + + PALETTE DISPLAY BOX: This Box shows all 256 colors in an array + of 32 by 8 color blocks. The Currently Selected Color will + have a Box around it. Clicking on a color with the Left + Mouse button will make that color the new currently selected + color. Clicking on a color with the Right Mouse Button will + copy the color value from the old selected color to it, before + it is made the new selected color. + + Message Bar: At the very bottom of the screen, this Bar will display + information and messages for various functions. + +PALETTE FILE FORMAT: + + BINARY image, in order of VGA DAC (Color) Number. 3 Bytes Per + Color, 256 Colors. 768 Bytes total. The Files will be exactly + 768 bytes in size. + + COLOR: + RED: 1 BYTE + GREEN: 1 BYTE + BLUE: 1 BYTE + + PALETTE: Array (0 to 255) of COLOR + +COMMENTS, QUESTIONS, BUG REPORTS, etc: + + Send the to the Author: Matt Pritchard + + Through the 80xxx Fidonet Echo or + + Matt Pritchard + P.O. Box 140264 + Irving, TX 75014 + +CREDITS: + + This Palette Editor was written in QuickBASIC 4.5 diff --git a/16/modex105/PALEDIT/PALEDIT.EXE b/16/modex105/PALEDIT/PALEDIT.EXE new file mode 100644 index 0000000000000000000000000000000000000000..f69e172d05b32a8aa903c3857db0b199c84a91de GIT binary patch literal 70230 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℞6Tu?4W+slD)hB_fLLp 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 LZQpnAec3!FlnS+^wcg+JrM`4b~t%&As zqr2%O?4C|r`EFtq+q>OPRaITrP1Ce2%W)jv_roxZ<2X&zqA2RR?z(Q8rl0*Ykl-9- zaSIAufC`tOfer>-feF{J2McVt0S8?0;2-#K3jy3g2=@@d1H^EEM@S%r44xo|0?I88 z6+A-?FVMg%w9r8h|6zbP7-51L-eG|cSm6`4v_gLYe)R*AB+0U@D2kv?(=@{{1bF-X z-nMPQp67W2zaR(%fl(A44u>R3vMkH