home *** CD-ROM | disk | FTP | other *** search
- /*-----------------------------------------------------------------------------
- *
- * FILE IDENTIFICATION
- *
- * Name: crt_disk.c Routines to save & restore screen images
- *
- * Programmer: Kevin Rosenberg
- * Address: 2515 E. 16th St.
- * Newport Beach, CA 92663
- * (714) 642-0119
- *
- *
- * PUBLIC DOMAIN NOTICE
- * 2/2/85
- * This program may be used freely for any non-commercial purpose.
- * If you have a need for custom graphic routines or stand-alone
- * programs, I might be able to help. I large selection (800K total
- * source code) of graphic and scientific software.
- *
- *
- * LANGAUGE
- * Lattice V2.12
- *
- *
- * GLOBAL FUNCTIONS
- * crt_save (fname) Store screen image as a disk file
- * crt_restore (fname) Restore screen image for disk file
- *
- *
- * BUGS, LIMITATIONS
- * 1) Only tested with mode GM_MONOGRF (monochrome graphics)
- * 2) No support for text modes (trivial to add, though)
- *
- *
- * PERFORMANCE NOTES
- * It take approx. 0.5 sec to save or restore the screen using
- * monochrome graphics. It would take twice as only for enhanced
- * 16 color graphics.
- *
- *
- * OTHER FILES NEEDED
- * For Compiling:
- * dos.h Lattice file for 8086 register structure defs
- * crt_disk.h Special file create for Pub. Dom. dissemination
- *
- * For linking:
- * crt_disk.lib For large memory model ONLY.
- * Contains object code for:
- * sys_error, crt_set_mode, crt_get_mode
- * C_ptr_to_8086_addr, peekb, pokeb
- *
- * LINKING INSTRUCTIONS (PUB DOM)
- * Simply add the file crt_disk.lib to the library portion of the link
- * command, for example,
- * LINK cl+main,main,nul,crt_disk+lcl
- *
- * Note that the LARGE memory model must be used on all your routines
- * if you want to use this program. If you need the small model, let
- * me know and I'll get around to testing it.
- *
- *
- * COMPILATION INSTRUCTIONS (PUB DOM)
- * You DON'T need to compile this file unless you wish to modify it.
- * If so, make your modification & then follow this procedure:
- *
- * LC1 crt_disk -n -ml -s
- * LC2 crt_disk
- *
- * NOTE: You must compile all your routines in the LARGE memory model
- * so you may link them with the routines in crt_disk.lib
- *
- * You must substitute the new object code of crt_disk.c in the library
- * crt_disk.lib. Do this with PLIB86 or other librarian. Your new
- * library is now ready to be linked with your other programs.
- *
- *
- * MODIFICATION LOG
- * 1-4-85 Started coding
- * 1-15-85 Finished debugging & testing with mode GM_MONOGRF
- * 2-1-85 Made new header file, crt_disk.h, to supply with this
- * program for PD use & remove #include's for standard headers
- * 2-2-85 Finished creating PD library, crt_disk.lib. Tested with file
- * c:\ega\pd\testmono.c
- *
- *---------------------------------------------------------------------------*/
-
- #include <dos.h>
- #include <crt_disk.h>
-
-
-
- /* FUNCTION IDENIFICATION
- * crt_save Save screen image on disk
- *
- * SYNOPSIS
- * retval = crt_save (fname)
- * int retval TRUE if no error, otherwise FALSE
- * char *fname Name of file for screen image
- *
- * NOTES
- * Works with graphic modes of standard & enhanced adapters.
- * Does NOT work with text modes.
- */
-
- crt_save (fname)
- char *fname;
- {
- unsigned int seg, len, i;
- int fd, mode, retval;
-
- if ((fd = _file_create (fname, OPEN_WRONLY)) == -1)
- return (FALSE);
-
- mode = crt_get_mode();
- _file_putc (mode, fd);
-
- switch (mode) {
- case GM_640x200: /* Standard modes */
- case GM_320x200:
- seg = 0xB000;
- len = (200 * 80);
- retval = _crt_write (fd, seg, len);
- break;
- case GM_E320x200: /* Enhanced modes */
- case GM_E640x200: /* on std. monitor */
- seg = 0xA000;
- len = (200 * 80);
- goto label1;
- case GM_MONOGRF: /* 350 line graphics */
- case GM_ENHANCED:
- seg = 0xA000;
- len = (350 * 80);
- label1:
- if ((peekb (0, 0x487) & 0x60) == 0) { /* 4 color mode */
- outp (0x3CE, 4); /* select bit 0 */
- outp (0x3CF, 0);
- if ((retval = _crt_write (fd, seg, len)) == FALSE)
- break;
- outp (0x3CE, 4); /* select bit 2 */
- outp (0x3CF, 2);
- if ((retval = _crt_write (fd, seg, len)) == FALSE)
- break;
- } else { /* 16 color mode */
- for (i = 0; i < 4; i++) {
- outp (0x3CE, 4);
- outp (0x3CF, i);
- if ((retval = _crt_write (fd, seg, len)) == FALSE)
- break;
- }
- }
- break;
- default:
- retval = FALSE;
- break;
- }
-
- _file_close (fd);
-
- return (retval);
- }
-
-
- /* FUNCTION NAME
- * crt_restore Restore screen image from disk file
- *
- * SYNOPSIS
- * retval = crt_restore (fname)
- * int retval TRUE if no errors, otherwise FALSE
- * char *fname Name of screen image file
- */
-
- crt_restore (fname)
- char *fname;
- {
- int fd, retval;
- unsigned int seg, len, i;
- int mode;
-
- if ((fd = _file_open (fname, OPEN_RDONLY)) == -1)
- return (FALSE);
-
- mode = _file_getc (fd); /* read display mode (1st byte) */
-
- crt_set_mode (mode, TRUE);
-
- switch (mode) {
- case GM_640x200: /* standard modes */
- case GM_320x200:
- seg = 0xB000;
- len = (200 * 80);
- retval = _crt_read (fd, seg, len);
- break;
- case GM_E320x200: /* enhanced modes on */
- case GM_E640x200: /* standard monitor */
- seg = 0xA000;
- len = (200 * 80);
- goto label2;
- case GM_MONOGRF: /* 350 line modes */
- case GM_ENHANCED:
- seg = 0xA000;
- len = (350 * 80);
- label2:
- outp (0x3CE, 8); /* set bit mask to all bits */
- outp (0x3CF, 0xFF);
- outp (0x3CE, 3); /* set to OR raster write mode */
- outp (0x3CF, 0x10);
-
- peekb (seg, 0);
- if ((peekb (0, 0x487) & 0x60) == 0) { /* 4 color enh */
- outp (0x3C4, 2); /* set color */
- outp (0x3C5, 3);
- if ((retval = _crt_read (fd, seg, len)) == FALSE)
- break;
- outp (0x3C4, 2);
- outp (0x3C5, 12);
- if ((retval = _crt_read (fd, seg, len)) == FALSE)
- break;
- } else { /* 16 color mode */
- for (i = 0; i < 4; i++) {
- outp (0x3C4, 2); /* set each bit plane */
- outp (0x3C5, i);
- if ((retval = _crt_read (fd, seg, len)) == FALSE)
- break;
- }
- }
- break;
- default:
- sys_error (ERR_WARNING,
- "File %s is not a crt image [crt_restore]", fname);
- retval = FALSE;
- break;
- }
-
- _file_close (fd);
-
- return (retval);
- }
-
-
- /*----------------------------------------------------------------------*/
- /* Screen/Disk IO interface */
- /*----------------------------------------------------------------------*/
-
- INTERNAL_FUNC
- _crt_write (fd, seg, len)
- unsigned int seg, len;
- int fd;
- {
- if (_file_write (seg, 0, len, fd) != len) {
- sys_error (ERR_SEVERE, "Error writing screen image file [_crt_write]");
- return (FALSE);
- } else
- return (TRUE);
- }
-
-
- INTERNAL_FUNC
- _crt_read (fd, seg, len)
- int fd;
- unsigned int seg, len;
- {
- if (_file_read (seg, 0, len, fd) != len) {
- sys_error (ERR_SEVERE, "Error reading file [_crt_read]");
- return (FALSE);
- } else
- return (TRUE);
- }
-
-
- /*----------------------------------------------------------------------*/
- /* DOS File I/O Routines */
- /* */
- /* These routines are used so DOS can read and write directly */
- /* to the display buffer. */
- /* */
- /*----------------------------------------------------------------------*/
-
- /* NAME
- * _file_open Open a file directly from DOS
- *
- * SYNOPSIS
- * fd = _file_open (fname, mode)
- * int fd File handle
- * char *fname Name of file to open
- * int mode Mode of opening (same as C library open()
- */
-
- INTERNAL_FUNC
- _file_open (fname, mode)
- char *fname;
- int mode;
- {
- union REGS srv, rrv;
- struct SREGS seg;
- unsigned int flags;
-
- srv.h.ah = 0x3D; /* Open file function */
- srv.h.al = mode;
- C_ptr_to_8086_addr (fname, &seg.ds, &srv.x.dx);
-
- flags = int86x (INTR_DOS, &srv, &rrv, &seg);
-
- if (flags & CFLAG_8086)
- sys_error (ERR_SEVERE,
- "Error opening file (code = %d) [_file_open]", rrv.x.ax);
- else
- return (rrv.x.ax);
- }
-
-
- INTERNAL_FUNC
- _file_create (fname, mode)
- char *fname;
- int mode;
- {
- union REGS srv, rrv;
- struct SREGS seg;
- unsigned int flags;
-
- srv.h.ah = 0x3C; /* Create file function */
- srv.x.cx = 0; /* Attribute */
- C_ptr_to_8086_addr (fname, &seg.ds, &srv.x.dx);
-
- flags = int86x (INTR_DOS, &srv, &rrv, &seg);
-
- if (flags & CFLAG_8086)
- sys_error (ERR_SEVERE,
- "Error creating file (code = %d) [_file_create]", rrv.x.ax);
- else
- return (rrv.x.ax);
- }
-
-
- INTERNAL_FUNC
- _file_read (seg, ofs, n, fd)
- unsigned seg, ofs, n, fd;
- {
- union REGS srv, rrv;
- struct SREGS sreg;
- unsigned flags;
-
- srv.h.ah = 0x3F;
- srv.x.bx = fd;
- srv.x.cx = n;
- sreg.ds = seg;
- srv.x.dx = ofs;
-
- flags = int86x (INTR_DOS, &srv, &rrv, &sreg);
-
- return (rrv.x.ax);
- }
-
-
- INTERNAL_FUNC
- _file_write (seg, ofs, n, fd)
- unsigned seg, ofs, n, fd;
- {
- union REGS srv, rrv;
- struct SREGS sreg;
- unsigned flags;
-
- srv.h.ah = 0x40;
- srv.x.bx = fd;
- srv.x.cx = n;
- sreg.ds = seg;
- srv.x.dx = ofs;
-
- flags = int86x (INTR_DOS, &srv, &rrv, &sreg);
-
- return (rrv.x.ax);
- }
-
-
- INTERNAL_FUNC
- _file_close (fd)
- int fd;
- {
- union REGS srv, rrv;
-
- srv.h.ah = 0x3E;
- srv.x.bx = fd;
- int86 (INTR_DOS, &srv, &rrv);
- }
-
-
- INTERNAL_FUNC
- _file_getc (fd)
- int fd;
- {
- char c;
- unsigned seg, ofs;
-
- C_ptr_to_8086_addr (&c, &seg, &ofs);
- _file_read (seg, ofs, 1, fd);
-
- return ((int) c);
- }
-
-
- INTERNAL_FUNC
- _file_putc (c, fd)
- char c;
- int fd;
- {
- char cval;
- unsigned seg, ofs;
-
- cval = c;
- C_ptr_to_8086_addr (&cval, &seg, &ofs);
- _file_write (seg, ofs, 1, fd);
-
- return ((int) c);
- }
-
-
- /*----------------------------------------------------------------------*/
- /* END OF FILE CRT_DISK.C */
- /*----------------------------------------------------------------------*/