Previous | Table of Contents | Next

LISTING 29.2 L29-2.ASM

    ; Program to restore a mode 10h EGA graphics screen from
    ; the file SNAPSHOT.SCR.
    ;
    VGA_SEGMENT                 equ   0a000h
    SC_INDEX                    equ   3c4h            ;Sequence Controller Index register
    MAP_MASK                    equ   2               ;Map Mask register index in SC
    DISPLAYED_SCREEN_SIZE       equ  (640/8)*350      ;# of displayed bytes per plane in a
                                                      ; hi-res graphics screen
    ;
    stack      segment para stack ‘STACK’
                     db              512 dup (?)
    stack      ends
    ;
    Data       segment     word ‘DATA’
    Filename         db          ‘SNAPSHOT.SCR’,0   ;name of file we’re restoring from
    ErrMsg1          db          ‘*** Couldn’‘t open SNAPSHOT.SCR ***’,0dh,0ah,‘$’
    ErrMsg2          db          ‘*** Error reading from SNAPSHOT.SCR ***’,0dh,0ah,‘$’
    WaitKeyMsg       db          0dh, 0ah, ‘Done. Press any key to end...’,0dh,0ah,‘$’
    Handle           dw          ?                  ;handle of file we’re restoring from
    Plane            db          ?                  ;plane being written
    Data       ends
    ;
    Code          segment
                  assume   cs:Code, ds:Data
    Start         proc     near
                  mov      ax,Data
                  mov      ds,ax
    ;
    ; Go to hi-res graphics mode.
    ;
                  mov      ax,10h          ;AH = 0 means mode set, AL = 10h selects
                                           ; hi-res graphics mode
                  int      10h             ;BIOS video interrupt
    ;
    ; Open SNAPSHOT.SCR.
    ;
                  mov      ah,3dh           ;DOS open file function
                  mov      dx,offset Filename
                  sub      al,al            ;open for reading
                  int      21h
                  mov      [Handle],ax      ;save the handle
                  jnc      RestoreTheScreen ;we’re ready to restore if no error
                  mov      ah,9             ;DOS print string function
                  mov      dx,offset ErrMsg1
                  int      21h              ;notify of the error
                  jmp      short Done;and done
    ;
    ; Loop through the 4 planes, making each writable in turn and
    ; reading it from disk. Note that all 4 planes are writable at
    ; A000:0000; the Map Mask register selects which planes are readable
    ; at any one time. We only make one plane readable at a time.
    ;
    RestoreTheScreen:
                  mov      [Plane],0                ;start with plane 0
    RestoreLoop:
                  mov      dx,SC_INDEX
                  mov      al,MAP_MASK              ;set SC Index to Map Mask register
    outdx,al
                  inc      dx
                  mov      cl,[Plane]               ;get the # of the plane we want
    ; to restore
                  mov      al,1
                  shl      al,cl                    ;set the bit enabling writes to
                                                    ; only the one desired plane
                  out      dx,al                    ;set to read from desired plane
                  mov      ah,3fh                   ;DOS read from file function
                  mov      bx,[Handle]
                  mov      cx,DISPLAYED_SCREEN_SIZE ;# of bytes to read
                  sub      dx,dx                    ;start loading bytes at A000:0000
                  push     ds
                  mov      si,VGA_SEGMENT
                  mov      ds,si
                  int      21h                      ;read the displayed portion of this plane
                  pop      ds
                  jc       ReadError
                  cmp      ax,DISPLAYED_SCREEN_SIZE ;did all bytes get read?
                  jz       RestoreLoopBottom
    ReadError:
                  mov      ah,9                     ;DOS print string function
                  mov      dx,offset ErrMsg2
                  int      21h                      ;notify about the error
                  jmp      short DoClose            ;and done
    RestoreLoopBottom:
                  mov      al,[Plane]
                  inc      ax                       ;point to the next plane
                  mov      [Plane],al
                  cmp      al,3                     ;have we done all planes?
                  jbe      RestoreLoop              ;no, so do the next plane
    ;
    ; Close SNAPSHOT.SCR.
    ;
    DoClose:
                  mov      ah,3eh                   ;DOS close file function
                  mov      bx,[Handle]
                  int      21h
    ;
    ; Wait for a keypress.
    ;
                  mov      ah,8                     ;DOS input without echo function
                  int      21h
    ;
    ; Restore text mode.
    ;
                  mov      ax,3
                  int      10h
    ;
    ; Done.
    ;
    Done:
                  mov      ah,4ch                   ;DOS terminate function
                  int      21h
    Start         endp
    Code          ends
                  end      Start

If you compare Listings 29.1 and 29.2, you will see that the Map Mask register setting used to load a given plane does not match the Read Map register setting used to read that plane. This is so because while only one plane can ever be read at a time, anywhere from zero to four planes can be written to at once; consequently, Read Map register settings are plane selections from 0 to 3, while Map Mask register settings are plane masks from 0 to 15, where a bit 0 setting of 1 enables writes to plane 0, a bit 1 setting of 1 enables writes to plane 1, and so on. Again, Chapter 28 provides a detailed explanation of the differences between the Read Map and Map Mask registers.

Screen saving and restoring is pretty simple, eh? There are a few caveats, of course, but nothing serious. First, the adapter’s registers must be programmed properly in order for screen saving and restoring to work. For screen saving, you must be in read mode 0; if you’re in color compare mode, there’s no telling what bit pattern you’ll save, but it certainly won’t be the desired screen image. For screen restoring, you must be in write mode 0, with the Bit Mask register set to 0FFH and Data Rotate register set to 0 (no data rotation and the logical function set to pass the data through unchanged).

Previous | Table of Contents | Next

Graphics Programming Black Book © 2001 Michael Abrash