128 lines
3.2 KiB
NASM
128 lines
3.2 KiB
NASM
; Program to put up a mode 10h EGA graphics screen, then save it
|
|
; to the file SNAPSHOT.SCR.
|
|
;
|
|
VGA_SEGMENT equ 0a000h
|
|
GC_INDEX equ 3ceh ;Graphics Controller Index register
|
|
READ_MAP equ 4 ;Read Map register index in GC
|
|
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'
|
|
SampleText db 'This is bit-mapped text, drawn in hi-res '
|
|
db 'EGA graphics mode 10h.', 0dh, 0ah, 0ah
|
|
db 'Saving the screen (including this text)...'
|
|
db 0dh, 0ah, '$'
|
|
Filename db 'SNAPSHOT.SCR',0;name of file we're saving to
|
|
ErrMsg1 db "*** Couldn't open SNAPSHOT.SCR ***",0dh,0ah,'$'
|
|
ErrMsg2 db '*** Error writing to SNAPSHOT.SCR ***',0dh,0ah,'$'
|
|
WaitKeyMsg db 0dh, 0ah, 'Done. Press any key to end...',0dh,0ah,'$'
|
|
Handle dw ? ;handle of file we're saving to
|
|
Plane db ? ;plane being read
|
|
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
|
|
;
|
|
; Put up some text, so the screen isn't empty.
|
|
;
|
|
mov ah,9 ;DOS print string function
|
|
mov dx,offset SampleText
|
|
int 21h
|
|
;
|
|
; Delete SNAPSHOT.SCR if it exists.
|
|
;
|
|
mov ah,41h ;DOS unlink file function
|
|
mov dx,offset Filename
|
|
int 21h
|
|
;
|
|
; Create the file SNAPSHOT.SCR.
|
|
;
|
|
mov ah,3ch ;DOS create file function
|
|
mov dx,offset Filename
|
|
sub cx,cx ;make it a normal file
|
|
int 21h
|
|
mov [Handle],ax ;save the handle
|
|
jnc SaveTheScreen ;we're ready to save 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 readable in turn and
|
|
; writing it to disk. Note that all 4 planes are readable at
|
|
; A000:0000; the Read Map register selects which plane is readable
|
|
; at any one time.
|
|
;
|
|
SaveTheScreen:
|
|
mov [Plane],0 ;start with plane 0
|
|
SaveLoop:
|
|
mov dx,GC_INDEX
|
|
mov al,READ_MAP ;set GC Index to Read Map register
|
|
out dx,al
|
|
inc dx
|
|
mov al,[Plane] ;get the # of the plane we want
|
|
; to save
|
|
out dx,al ;set to read from the desired plane
|
|
mov ah,40h ;DOS write to file function
|
|
mov bx,[Handle]
|
|
mov cx,DISPLAYED_SCREEN_SIZE;# of bytes to save
|
|
sub dx,dx ;write all displayed bytes at A000:0000
|
|
push ds
|
|
mov si,VGA_SEGMENT
|
|
mov ds,si
|
|
int 21h ;write the displayed portion of this plane
|
|
pop ds
|
|
cmp ax,DISPLAYED_SCREEN_SIZE;did all bytes get written?
|
|
jz SaveLoopBottom
|
|
mov ah,9 ;DOS print string function
|
|
mov dx,offset ErrMsg2
|
|
int 21h ;notify about the error
|
|
jmp short DoClose ;and done
|
|
SaveLoopBottom:
|
|
mov al,[Plane]
|
|
inc ax ;point to the next plane
|
|
mov [Plane],al
|
|
cmp al,3 ;have we done all planes?
|
|
jbe SaveLoop ;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,9 ;DOS print string function
|
|
mov dx,offset WaitKeyMsg
|
|
int 21h ;prompt
|
|
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
|