home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / screen / crt_disk / crt_disk.c next >
Encoding:
C/C++ Source or Header  |  1985-02-03  |  9.8 KB  |  419 lines

  1. /*-----------------------------------------------------------------------------
  2.  *
  3.  * FILE IDENTIFICATION
  4.  *
  5.  *    Name:          crt_disk.c       Routines to save & restore screen images
  6.  *
  7.  *    Programmer:   Kevin Rosenberg
  8.  *    Address:      2515 E. 16th St.
  9.  *              Newport Beach, CA 92663
  10.  *              (714) 642-0119
  11.  *
  12.  *
  13.  * PUBLIC DOMAIN NOTICE
  14.  *   2/2/85
  15.  *        This program may be used freely for any non-commercial purpose.
  16.  *    If you have a need for custom graphic routines or stand-alone
  17.  *    programs, I might be able to help.  I large selection (800K total
  18.  *    source code) of graphic    and scientific software.
  19.  *
  20.  *
  21.  * LANGAUGE
  22.  *    Lattice V2.12
  23.  *
  24.  *
  25.  * GLOBAL FUNCTIONS
  26.  *    crt_save (fname)        Store screen image as a disk file
  27.  *    crt_restore (fname)        Restore screen image for disk file
  28.  *
  29.  *
  30.  * BUGS, LIMITATIONS
  31.  *   1)    Only tested with mode GM_MONOGRF (monochrome graphics)
  32.  *   2)    No support for text modes (trivial to add, though)
  33.  *
  34.  *
  35.  * PERFORMANCE NOTES
  36.  *    It take approx. 0.5 sec to save or restore the screen using
  37.  *    monochrome graphics.  It would take twice as only for enhanced
  38.  *    16 color graphics.
  39.  *
  40.  *
  41.  * OTHER FILES NEEDED
  42.  *   For Compiling:
  43.  *    dos.h            Lattice file for 8086 register structure defs
  44.  *    crt_disk.h        Special file create for Pub. Dom. dissemination
  45.  *
  46.  *   For linking:
  47.  *    crt_disk.lib        For large memory model ONLY.
  48.  *                Contains object code for:
  49.  *                    sys_error, crt_set_mode, crt_get_mode
  50.  *                    C_ptr_to_8086_addr, peekb, pokeb
  51.  *
  52.  * LINKING INSTRUCTIONS  (PUB DOM)
  53.  *    Simply add the file crt_disk.lib to the library portion of the link
  54.  *    command, for example,
  55.  *        LINK cl+main,main,nul,crt_disk+lcl
  56.  *
  57.  *    Note that the LARGE memory model must be used on all your routines
  58.  *    if you want to use this program.  If you need the small model, let
  59.  *    me know and I'll get around to testing it.
  60.  *
  61.  *
  62.  * COMPILATION INSTRUCTIONS  (PUB DOM)
  63.  *    You DON'T need to compile this file unless you wish to modify it.
  64.  *    If so, make your modification & then follow this procedure:
  65.  *
  66.  *        LC1 crt_disk -n -ml -s
  67.  *        LC2 crt_disk
  68.  *
  69.  *    NOTE: You must compile all your routines in the LARGE memory model
  70.  *          so you may link them with the routines in crt_disk.lib
  71.  *
  72.  *    You must substitute the new object code of crt_disk.c in the library
  73.  *    crt_disk.lib.  Do this with PLIB86 or other librarian.  Your new
  74.  *    library is now ready to be linked with your other programs.
  75.  *
  76.  *
  77.  * MODIFICATION LOG
  78.  *    1-4-85    Started coding
  79.  *    1-15-85    Finished debugging & testing with mode GM_MONOGRF
  80.  *    2-1-85    Made new header file, crt_disk.h, to supply with this
  81.  *        program for PD use & remove #include's for standard headers
  82.  *    2-2-85    Finished creating PD library, crt_disk.lib.  Tested with file
  83.  *        c:\ega\pd\testmono.c
  84.  *
  85.  *---------------------------------------------------------------------------*/
  86.  
  87. #include <dos.h>
  88. #include <crt_disk.h>
  89.  
  90.  
  91.  
  92. /* FUNCTION IDENIFICATION
  93.  *    crt_save            Save screen image on disk
  94.  *
  95.  * SYNOPSIS
  96.  *    retval = crt_save (fname)
  97.  *    int retval            TRUE if no error, otherwise FALSE
  98.  *    char *fname            Name of file for screen image
  99.  *
  100.  * NOTES
  101.  *    Works with graphic modes of standard & enhanced adapters.
  102.  *    Does NOT work with text modes.
  103.  */
  104.  
  105. crt_save (fname)
  106. char *fname;
  107. {
  108.     unsigned int seg, len, i;
  109.     int fd, mode, retval;
  110.  
  111.     if ((fd = _file_create (fname, OPEN_WRONLY)) == -1)
  112.         return (FALSE);
  113.  
  114.     mode = crt_get_mode();
  115.     _file_putc (mode, fd);
  116.  
  117.     switch (mode) {
  118.         case GM_640x200:                /* Standard modes */
  119.         case GM_320x200:
  120.         seg = 0xB000;
  121.         len = (200 * 80);
  122.         retval = _crt_write (fd, seg, len);
  123.         break;
  124.         case GM_E320x200:                /* Enhanced modes */
  125.         case GM_E640x200:                /* on std. monitor */
  126.         seg = 0xA000;
  127.         len = (200 * 80);
  128.         goto label1;
  129.         case GM_MONOGRF:                /* 350 line graphics */
  130.         case GM_ENHANCED:
  131.         seg = 0xA000;
  132.         len = (350 * 80);
  133. label1:
  134.         if ((peekb (0, 0x487) & 0x60) == 0) {    /* 4 color mode */
  135.             outp (0x3CE, 4);                /* select bit 0 */
  136.             outp (0x3CF, 0);    
  137.             if ((retval = _crt_write (fd, seg, len)) == FALSE)
  138.             break;
  139.             outp (0x3CE, 4);                  /* select bit 2 */
  140.             outp (0x3CF, 2);
  141.             if ((retval = _crt_write (fd, seg, len)) == FALSE)
  142.             break;
  143.         } else {                /* 16 color mode */
  144.             for (i = 0; i < 4; i++) {
  145.             outp (0x3CE, 4);
  146.             outp (0x3CF, i);
  147.             if ((retval = _crt_write (fd, seg, len)) == FALSE)
  148.                 break;
  149.             }
  150.         }
  151.         break;
  152.         default:
  153.         retval = FALSE;
  154.         break;
  155.     }
  156.  
  157.     _file_close (fd);
  158.  
  159.     return (retval);
  160. }
  161.  
  162.  
  163. /* FUNCTION NAME
  164.  *    crt_restore            Restore screen image from disk file
  165.  *
  166.  * SYNOPSIS
  167.  *    retval = crt_restore (fname)
  168.  *    int retval            TRUE if no errors, otherwise FALSE
  169.  *    char *fname            Name of screen image file
  170.  */
  171.  
  172. crt_restore (fname)
  173. char *fname;
  174. {
  175.     int fd, retval;
  176.     unsigned int seg, len, i;
  177.     int mode;
  178.  
  179.     if ((fd = _file_open (fname, OPEN_RDONLY)) == -1)
  180.         return (FALSE);
  181.  
  182.     mode = _file_getc (fd);        /* read display mode (1st byte) */
  183.  
  184.     crt_set_mode (mode, TRUE);
  185.  
  186.     switch (mode) {
  187.         case GM_640x200:            /* standard modes */
  188.         case GM_320x200:
  189.         seg = 0xB000;
  190.         len = (200 * 80);
  191.         retval = _crt_read (fd, seg, len);
  192.         break;
  193.         case GM_E320x200:            /* enhanced modes on */
  194.         case GM_E640x200:            /* standard monitor */
  195.         seg = 0xA000;
  196.         len = (200 * 80);
  197.         goto label2;
  198.         case GM_MONOGRF:            /* 350 line modes */
  199.         case GM_ENHANCED:
  200.         seg = 0xA000;
  201.         len = (350 * 80);
  202. label2:
  203.         outp (0x3CE, 8);        /* set bit mask to all bits */
  204.         outp (0x3CF, 0xFF);
  205.         outp (0x3CE, 3);        /* set to OR raster write mode */
  206.         outp (0x3CF, 0x10);
  207.  
  208.         peekb (seg, 0);
  209.         if ((peekb (0, 0x487) & 0x60) == 0) {    /* 4 color enh */
  210.             outp (0x3C4, 2);            /* set color */
  211.             outp (0x3C5, 3);
  212.             if ((retval = _crt_read (fd, seg, len)) == FALSE)
  213.             break;
  214.             outp (0x3C4, 2);
  215.             outp (0x3C5, 12);
  216.             if ((retval = _crt_read (fd, seg, len)) == FALSE)
  217.             break;
  218.         } else {                /* 16 color mode */
  219.             for (i = 0; i < 4; i++) {
  220.             outp (0x3C4, 2);        /* set each bit plane */
  221.             outp (0x3C5, i);
  222.             if ((retval = _crt_read (fd, seg, len)) == FALSE)
  223.                 break;
  224.             }
  225.         }
  226.         break;
  227.         default:
  228.         sys_error (ERR_WARNING,
  229.                 "File %s is not a crt image [crt_restore]", fname);
  230.         retval = FALSE;
  231.         break;
  232.     }
  233.  
  234.     _file_close (fd);
  235.  
  236.     return (retval);
  237. }
  238.  
  239.  
  240. /*----------------------------------------------------------------------*/
  241. /*            Screen/Disk IO interface            */
  242. /*----------------------------------------------------------------------*/
  243.  
  244. INTERNAL_FUNC
  245. _crt_write (fd, seg, len)
  246. unsigned int seg, len;
  247. int fd;
  248. {
  249.     if (_file_write (seg, 0, len, fd) != len) {
  250.         sys_error (ERR_SEVERE, "Error writing screen image file [_crt_write]");
  251.         return (FALSE);
  252.     } else
  253.         return (TRUE);
  254. }
  255.  
  256.  
  257. INTERNAL_FUNC
  258. _crt_read (fd, seg, len)
  259. int fd;
  260. unsigned int seg, len;
  261. {
  262.     if (_file_read (seg, 0, len, fd) != len) {
  263.         sys_error (ERR_SEVERE, "Error reading file [_crt_read]");
  264.         return (FALSE);
  265.     } else
  266.         return (TRUE);
  267. }
  268.  
  269.  
  270. /*----------------------------------------------------------------------*/
  271. /*            DOS File I/O Routines                */
  272. /*                                    */
  273. /*    These routines are used so DOS can read and write directly    */
  274. /*    to the display buffer.                        */
  275. /*                                    */
  276. /*----------------------------------------------------------------------*/
  277.  
  278. /* NAME
  279.  *    _file_open        Open a file directly from DOS
  280.  *
  281.  * SYNOPSIS
  282.  *    fd = _file_open (fname, mode)
  283.  *    int fd            File handle
  284.  *    char *fname        Name of file to open
  285.  *    int mode        Mode of opening (same as C library open()
  286.  */
  287.  
  288. INTERNAL_FUNC
  289. _file_open (fname, mode)
  290. char *fname;
  291. int mode;
  292. {
  293.     union REGS srv, rrv;
  294.     struct SREGS seg;
  295.     unsigned int flags;
  296.  
  297.     srv.h.ah = 0x3D;    /* Open file function */
  298.     srv.h.al = mode;
  299.     C_ptr_to_8086_addr (fname, &seg.ds, &srv.x.dx);
  300.  
  301.     flags = int86x (INTR_DOS, &srv, &rrv, &seg);
  302.  
  303.     if (flags & CFLAG_8086)
  304.         sys_error (ERR_SEVERE,
  305.            "Error opening file (code = %d) [_file_open]", rrv.x.ax);
  306.     else
  307.         return (rrv.x.ax);
  308. }
  309.  
  310.  
  311. INTERNAL_FUNC
  312. _file_create (fname, mode)
  313. char *fname;
  314. int mode;
  315. {
  316.     union REGS srv, rrv;
  317.     struct SREGS seg;
  318.     unsigned int flags;
  319.  
  320.     srv.h.ah = 0x3C;    /* Create file function */
  321.     srv.x.cx = 0;        /* Attribute */
  322.     C_ptr_to_8086_addr (fname, &seg.ds, &srv.x.dx);
  323.  
  324.     flags = int86x (INTR_DOS, &srv, &rrv, &seg);
  325.  
  326.     if (flags & CFLAG_8086)
  327.         sys_error (ERR_SEVERE,
  328.            "Error creating file (code = %d) [_file_create]", rrv.x.ax);
  329.     else
  330.         return (rrv.x.ax);
  331. }
  332.  
  333.  
  334. INTERNAL_FUNC
  335. _file_read (seg, ofs, n, fd)
  336. unsigned seg, ofs, n, fd;
  337. {
  338.     union REGS srv, rrv;
  339.     struct SREGS sreg;
  340.     unsigned flags;
  341.  
  342.     srv.h.ah = 0x3F;
  343.     srv.x.bx = fd;
  344.     srv.x.cx = n;
  345.     sreg.ds = seg;
  346.     srv.x.dx = ofs;
  347.  
  348.     flags = int86x (INTR_DOS, &srv, &rrv, &sreg);
  349.  
  350.     return (rrv.x.ax);
  351. }
  352.  
  353.  
  354. INTERNAL_FUNC
  355. _file_write (seg, ofs, n, fd)
  356. unsigned seg, ofs, n, fd;
  357. {
  358.     union REGS srv, rrv;
  359.     struct SREGS sreg;
  360.     unsigned flags;
  361.  
  362.     srv.h.ah = 0x40;
  363.     srv.x.bx = fd;
  364.     srv.x.cx = n;
  365.     sreg.ds = seg;
  366.     srv.x.dx = ofs;
  367.  
  368.     flags = int86x (INTR_DOS, &srv, &rrv, &sreg);
  369.  
  370.     return (rrv.x.ax);
  371. }
  372.  
  373.  
  374. INTERNAL_FUNC
  375. _file_close (fd)
  376. int fd;
  377. {
  378.     union REGS srv, rrv;
  379.  
  380.     srv.h.ah = 0x3E;
  381.     srv.x.bx = fd;
  382.     int86 (INTR_DOS, &srv, &rrv);
  383. }
  384.  
  385.  
  386. INTERNAL_FUNC
  387. _file_getc (fd)
  388. int fd;
  389. {
  390.     char c;
  391.     unsigned seg, ofs;
  392.  
  393.     C_ptr_to_8086_addr (&c, &seg, &ofs);
  394.     _file_read (seg, ofs, 1, fd);
  395.  
  396.     return ((int) c);
  397. }
  398.  
  399.  
  400. INTERNAL_FUNC
  401. _file_putc (c, fd)
  402. char c;
  403. int fd;
  404. {
  405.     char cval;
  406.     unsigned seg, ofs;
  407.  
  408.     cval = c;
  409.     C_ptr_to_8086_addr (&cval, &seg, &ofs);
  410.     _file_write (seg, ofs, 1, fd);
  411.  
  412.     return ((int) c);
  413. }
  414.  
  415.  
  416. /*----------------------------------------------------------------------*/
  417. /*             END OF FILE CRT_DISK.C                */
  418. /*----------------------------------------------------------------------*/
  419.