Category : Assembly Language Source Code
Archive   : GX1FILE.ZIP
Filename : GX1FILE.ASM

 
Output of file : GX1FILE.ASM contained in archive : GX1FILE.ZIP

CodSeg Segment para 'code'

Assume cs:CodSeg,ds:CodSeg

BufSize equ 64 ;*BUF SIZE*

map_paras equ BufSize * 40h

scanln db 160 dup('X') ;Buffer to hold current scan
nwbytes db 160 dup('Y') ;Buffer to hold changed bytes
chgmap db 20 dup('Z') ;Buffer for a map of changes
abtstk dw 0 ;Stack ptr for Error Abort
pfname dd 0 ;Ptr to passed file name
smode db 4 ;Mode of the screen
tbgc db 0 ;Background color
tpalit db 4 ;CGA Palette ID
handle dw 0 ;File Handle
dtaidx dw 0 ;File I/O buffer index
fntact db 0 ;Switch for variable len file
minx dw 0 ;Minimum and Maximum screen
miny dw 0 ; coordinates
maxx dw 319
maxy dw 199
maxc db 4 ;Max colors on screen
xsiz dw 0 ;Loop counters
ysiz dw 0
hdwseg dw 0b800h ;Segment of Hardware bitmap
bufseg dw 0f000h ;Segment of 64k buffer
dftpal db 0,1,2,3,4,5,14h,7
db 38h,39h,3ah,3bh,3dh,3eh,3fh,0,0
egapal db 17 dup(0) ;EGA palette
dta db 128 dup('D') ;Disk Transfer Area
oldfatl dd 0 ;Fatal Error Vector Save
ebpl dw 80 ;Bytes per scan line
rlcount db 0 ;Run length counter
rlsame db 0 ;REPEATING byte flag
;
; Data for Hercules graphics open
;
herc_set db 35h,2dh,2eh,07h,5bh,02h,57h,57h,02h,03h,0,0

; --------------------------------------------------------------------------
;
; SvGX1 - Save the current screen to a GX1 file. Return value is an error
; number: 0=ok; 100=64k memory not available, NZ=Dos Errors.
;
; Pascal Declaration :
; function SvGX1( var fname : lstring; smode : integer ): integer; extern;
;
; C Declaration :
; extern int far pascal SvGX1( char *, int );
;
; --------------------------------------------------------------------------

PUBLIC SvGX1,LdGX1

SvGX1 Proc Far

push bp
mov bp,sp
push ds
push es
push si
push di
cld
mov dx,8[bp] ;Get ptr to filename
;
;*FAR POINT* Change above line to LDS DX,8[BP]
;
mov al,6[bp] ;Get screen mode number
mov bx,ds
push cs
pop ds
mov smode,al
mov word ptr pfname,dx
mov word ptr pfname+2,bx
mov abtstk,sp ;Save stack pointer for aborts
;
mov bx,map_paras
mov ah,48h
int 21h ;Ask for 64k buffer
jnc bufok
mov ax,100
jmp capend ;Error 100 - No buffer space
;
bufok: mov bufseg,ax
push es
xor ax,ax
mov es,ax
;Redirect MSDOS fatal errors.
cli
mov ax,offset fatlerr
xchg word ptr es:[24h*4],ax
mov word ptr oldfatl,ax
mov ax,cs
xchg word ptr es:[24h*4+2],ax
mov word ptr oldfatl+2,ax
sti
;
cmp smode,12 ;Capture EGA palette
jb nopal
les bx,es:[4a8h] ;Get vector to EGA vectors
les bx,es:[4+bx] ;Get Color table vector
mov ax,es
or ax,bx
jz nopad ;No scratch pad available
push ds
push es
pop ds
pop es
mov si,bx
lea di,egapal ;Get EGA palette from BIOS
mov cx,17 ; scratchpad.
rep movsb
push es
pop ds
jmp short nopal
nopad: xor ax,ax ;No scratch pad so check for
mov es,ax ; Microsoft mouse.
mov ax,es:[33h*4]
or ax,es:[33h*4+2]
jz nomous ;Mouse not present.
push ds
pop es
lea di,egapal
mov cx,17
xor al,al
rep movsb ;Init palette to 0s
mov dx,3dah ;Reset attribute ctrlr.
in al,dx
lea bx,egapal
mov cx,16 ;Use Mouse EGA shadow regs.
mov dx,18h
mov ah,0f2h
int 10h
mov si,15
xor al,al
mschk1: or al,egapal[si] ;Check for correct mouse
dec si ; response! Some compatable
jns mschk1 ; mice do not implement this.
or al,al ;If still zeros - fall through
jnz nopal ; to default palette
nomous: push ds
pop es
lea si,dftpal
lea di,egapal
mov cx,17
rep movsb
;
nopal: pop es
;
call fmake ;Make a new picture file.
call compress ;Compress to Disk
xor ax,ax

capend: mov sp,abtstk
push ax
xor ax,ax
mov es,ax
;Reset MSDOS error to old value
cli
mov ax,word ptr oldfatl
mov word ptr es:[24h*4],ax
mov ax,word ptr oldfatl+2
mov word ptr es:[24h*4+2],ax
sti

mov es,bufseg
mov ah,49h
int 21h ;Release buffer memory

pop ax
pop di
pop si
pop es
pop ds
pop bp
ret 4 ;*FAR POINT* Use 6 for far ptr

SvGX1 EndP

; --------------------------------------------------------------------------

;
; LdGX1 - Load a GX1 file to the screen. Return value is an error
; number: 0=ok; NZ=Dos Errors.
;
; Pascal Declaration :
; function LdGX1( var fname : lstring ): integer; extern;
;
; C Declaration :
; extern int far pascal LdGX1( char * );
;
; --------------------------------------------------------------------------

LdGX1 Proc far

push bp
mov bp,sp
push es
push ds
push si
push di
mov cs:abtstk,sp ;Stack save for aborts.
mov dx,6[bp] ;*FAR POINT* use LDS DX,6[BP]
xor cx,cx
mov ax,3d00h
int 21h ;Try to open the file.
jnc fok
jc lderr
ldabend: mov sp,abtstk ;FILE NOT FOUND ABORT
push ax
mov ah,49h
mov es,bufseg
int 21h
pop ax
lderr: pop di
pop si
pop ds
pop es
pop bp
ret 2 ;*FAR POINT* use 4 here
;
fok: push cs
pop ds
push ax
mov bx,map_paras
mov ah,48h
int 21h ;Allocate buffer memory
pop bx
jnc bufok2
mov ax,100
jmp short ldabend
bufok2: mov bufseg,ax
xor cx,cx
dec cx ;Read 64k from file
xor dx,dx
mov ah,3fh
mov ds,bufseg
int 21h
push cs
pop ds
jc ldabend
mov ah,3eh
int 21h
jc ldabend
;
mov es,bufseg ;Get screen mode # and color
mov al,es:[1] ; info from file.
mov smode,al
mov al,es:[2]
mov tbgc,al
and tbgc,0fh
mov cl,4
shr al,cl
mov tpalit,al
mov dtaidx,3
mov hdwseg,0b000h ;*HERC PAGE*
cmp smode,4 ;Graphics?
jae ucgr
;
; Text mode uncompress.
;
mov ax,es ;Point to area 4k into buffer
add ax,100h
mov es,ax
mov cx,2000 ;Calc chars per screen
cmp smode,2
jae col80
shr cx,1
col80: xor di,di
push cx
call dtaget ;Unpack the chars
pop cx
push cx
call dtaget ;Unpack the attributes
pop cx
mov bx,cx
xor si,si
xor di,di
push es
mov ax,0b800h
mov es,ax
pop ds
cpytxt: mov al,ds:[si] ;Format text screen to hardware
mov ah,ds:[si+bx]
inc si
stosw
loop cpytxt
push cs
pop ds
jmp ucmpn8
;
ucgr: call setmax ;Setup mode params
cmp smode,12
jb ucntega
push es
push ds
pop es
lea di,egapal ;get EGA palette data
mov cx,16
call dtaget
lea dx,egapal
mov ax,1002h ;setup EGA with palette
int 10h
pop es
ucntega: call setmax
mov ax,word ptr ebpl
mov xsiz,ax
mov ax,maxy
inc ax
mov ysiz,ax
ucmp3a: mov es,hdwseg
cmp smode,9 ;Is card an EGA?
jb untega ;nope
;
mov dx,3c4h ;Enable 1st plane for write
mov al,2
out dx,al
inc dx
mov al,3
cmp smode,9
je ucmp3b
cmp smode,12
je ucmp3b
mov al,1
ucmp3b: out dx,al
xor di,di
call ucmplane ;Uncompress plane
mov dx,3c5h ;Enable plane 2 for write
mov al,0ch
cmp smode,9
je ucmp3c
cmp smode,12
je ucmp3c
mov al,2
ucmp3c: out dx,al
xor di,di
call ucmplane ;Uncompress plane
cmp smode,9
je ucmpn8
cmp smode,12
je ucmpn8
egau1: mov dx,3c5h ;Enable plane 3
mov al,4
out dx,al
xor di,di
call ucmplane
mov dx,3c5h ;Plane 4
mov al,8
out dx,al
xor di,di
call ucmplane
jmp short ucmpn8
;
untega: xor di,di
call ucmplane
ucmpn8: mov es,bufseg
mov ah,49h
int 21h
xor ax,ax
pop di
pop si
pop ds
pop es
pop bp
ret 2 ;*FAR POINT* use 4 here

LdGX1 EndP


; ---------------------------------------------------------------------------
;
; S U B R O U T I N E S
;
; ---------------------------------------------------------------------------

Support Proc Near

;..............................................................................
;
; FMAKE.
;
; Open a file for Output.
;
Public fmake
;
fmake: push ds
lds dx,pfname
xor cx,cx
mov ah,3ch ;Command - Make File!
int 21h ;Call DOS.
pop ds
jc fmerr ;Yep - We have an error.
mov handle,ax ;Save file handle.
mov dtaidx,0 ;Init DTA index.
ret ;Make is Done.
foerr: push ax
mov bx,handle
mov ah,3eh
int 21h
pop ax
fmerr: jmp capend
;
; ---------------------------------------------------------------------------
;
; FatlErr This is an MSDOS Fatal Error routine (int 24h) which
; eliminates the default error messages.
;
fatlerr: xor al,al ;Ignore error
iret

; ---------------------------------------------------------------------------
; SETMAX
;
; This routine sets up the descriptive parameters for each screen mode
;
; ---------------------------------------------------------------------------
setmax: mov minx,0 ;Init boundaries.
mov miny,0
mov maxx,319
mov maxy,199
mov ebpl,80 ;Bytes per scan line
mov hdwseg,0b800h ;Segment of bitmap memory.
cmp smode,10
jne stmx
mov ebpl,40
stmx: cmp smode,8
jne stmx1
mov ebpl,90
mov maxx,359 ;This value div 2
mov maxy,347
mov hdwseg,0b800h ;*HERC PAGE*
jmp short smxmous
stmx1: cmp smode,4
je smxmous
mov maxx,639
cmp smode,9
jb smxmous
cmp smode,10
je smxmous
cmp smode,11
je smxmous
mov maxy,349
smxmous: mov maxc,4 ;Set max colors
cmp smode,4
je mxcx
cmp smode,8
je mxcx
cmp smode,9
je mxcx
cmp smode,12
je mxcx
shl maxc,1
shl maxc,1
mxcx: cmp smode,9
jb smend
mov hdwseg,0a000h
smend: ret

; ---------------------------------------------------------------------------
;
; COMPRESS. Save a Compressed Picture!
;
; This routine works by marking differences of each scan line from its
; immediate predecessor and then run-length encoding the result.
; ---------------------------------------------------------------------------

compress: cmp smode,4
jae cpgr
;
mov hdwseg,0b800h ;*HERC PAGE*
mov es,bufseg
mov byte ptr es:[0],0fbh
mov al,smode ;get the mode the picture is in
mov es:[1],al

mov cl,smode ;what text mode is it?
shr cl,1
xor cl,1
mov bp,4000 ;get number of bytes on screen
shr bp,cl
mov cx,bp
add bp,3 ;setup BP for run length coding

push ds
xor si,si ;start with characters
mov di,3 ;pack it to buffer, start=3
mov ds,hdwseg ;address of screen
shr cx,1 ;half the total bytes to move
push cx
cpgrl1: mov al,ds:[si] ;get character from screen
mov es:[di],al ;put it into buffer
inc si ;next character from screen
inc si
inc di ;next buffer position
loop cpgrl1
pop cx
mov si,1 ;start with attributes
cpgrl2: mov al,ds:[si] ;get attribute
mov es:[di],al ;put the attribute into buffer
inc si ;next attribute
inc si
inc di ;next buffer position
loop cpgrl2
pop ds
jmp cmpn9
;
cpgr: call setmax
mov ax,word ptr ebpl
mov xsiz,ax
mov ax,maxy
inc ax
mov ysiz,ax
mov es,bufseg
mov byte ptr es:[0],0fah ;ID Byte.
mov al,smode
mov es:[1],al
mov al,tbgc
mov ah,tpalit
mov cl,4
shl ah,cl
or al,ah
mov es:[2],al ;Palette Setting.
mov bp,3
mov es,hdwseg
cmp smode,9 ;Ega Modes?
jb cntega ;Nope!
cmp smode,12
jb nxep
push es
mov es,bufseg
mov di,bp
lea si,egapal
mov cx,16
rep movsb
mov bp,di
pop es
nxep: mov dx,3ceh ;Enable plane 0 for read
mov al,4
out dx,al
inc dx
xor al,al
out dx,al
push dx
call cmplane
pop dx
mov al,2 ;Plane 1
cmp smode,9
je cega2
cmp smode,12
je cega2
mov al,1
cega2: out dx,al
push dx
call cmplane
pop dx
cmp smode,9
je cegax
cmp smode,12
je cegax
mov al,2 ;Plane 2
out dx,al
push dx
call cmplane
pop dx
mov al,3 ;Plane 3
out dx,al
call cmplane
cegax: jmp short cmpn8

cntega: call cmplane
cmpn8: mov es,bufseg
cmp byte ptr es:[0],0fah ;Check if header still valid!
je cmpn9
mov ax,101 ;Pic too big for buffer error.
jmp capend
;
; Run Length Encoding - BP has offset 1 past eof, 1st 3 bytes are header.
;
cmpn9: mov si,bp
mov byte ptr es:[si],0 ;Mark End of File!
dec si
mov di,si
xor cx,cx
xor bx,bx

en2: dec si
cmp si,3 ;Do not compress header.
jae en2a
jmp enx
en2a: mov al,es:[si]
cmp al,es:[di]
je ensame
or bl,bl ;Previously same?
jnz en3 ;Yes!
en2b: dec di
mov es:[di],al
call clinc
jmp short en2
en3: cmp bl,4
jae en3b
; -------------------------------------------------------------------
; Here we have a Run Length which is too short ( less than 4 ).
; -------------------------------------------------------------------
call bnosame
jmp short en2b
;
en3b: dec di
or bl,80h
mov es:[di],bl ;Move the "same" length.
dec di
mov es:[di],al ;Move new char in.
mov cl,1
xor bl,bl
jmp short en2
ensame: or cl,cl ;Previously verbatim?
jnz en4 ;Yes!
or bl,bl
jnz en3c
mov bl,2
jmp short en2
en3c: call blinc
jmp short en2
en4: cmp cl,1
jbe en5
dec cl
mov es:[di],cl
dec di
mov es:[di],al
en5: mov bl,2
xor cl,cl
jmp short en2
;
enx: dec di
or bl,bl ;Same Count?
jz enx1 ;Nope!
or bl,80h
mov es:[di],bl
jmp short enx2
enx1: mov es:[di],cl
enx2: dec di
mov al,es:[si] ;Get BG and Palette color.
mov es:[di],al
dec di
dec si
mov al,es:[si] ;Get the MODE!
mov es:[di],al
dec di
mov al,es:[0]
mov byte ptr es:[di],al ;RUN LENGTH ENCODED PICTURE!
mov dx,di
mov cx,bp
sub cx,si
mov bx,handle
push ds
push es
pop ds
mov ah,40h
int 21h ;Write file data.
mov ah,3eh
int 21h ;Close file.
pop ds
ret
;
clinc: inc cl
cmp cl,128
jb xit
mov dh,es:[di]
mov byte ptr es:[di],127
cmp si,di ;Allow for last 127 verbatim.
je mvfil
dec di
jmp short clx
mvfil: push ds
push si
push di
push es
pop ds
mov di,bp
mov cx,di
sub cx,si
mov si,di
dec si
std
rep movsb
cld
inc bp
pop di
pop si
pop ds
clx: mov es:[di],dh
mov cl,1
xit: ret
;
blinc: inc bl
cmp bl,128
jb xit
dec di
mov byte ptr es:[di],0feh
dec di
mov byte ptr es:[di],al
mov bl,2
ret
;
bnosame: mov dl,es:[di] ;Get SAME byte in DL.
mov cl,es:1[di] ;Get Previous length!
test cl,80h ;Was it a verbatim length?
jnz bcsam ;NO!
inc di
mov es:[di],dl ;Replace prev len with char.
call clinc
dec di
mov es:[di],dl
call clinc
dec bl
jmp short bcver
bcsam: mov cl,1
bcver: dec bl
jz bcx
dec di
mov es:[di],dl
call clinc
jmp short bcver
bcx: ret
;
cmplane: push ds ;This routine vertically
push xsiz ; compresses a plane of
push es ; bitmap data.
mov cx,xsiz
mov es,bufseg
pop ds
xor si,si
mov di,bp
rep movsb ;Transfer 1st Scan verbatim!
mov bp,di
pop cx
pop es
xor si,si
lea di,scanln
rep movsb ;Transfer also into Scan buffer
push ds
push es
pop ds
pop es
mov bx,2000h
cmp smode,9
jb cps0
mov bx,xsiz
cps0: mov cx,ysiz
dec cx
cps1: xor si,si ;This label is jumped to at the
xor di,di ; start of a new scan line.
xor dx,dx
cps2: mov al,es:[bx+si] ;This label is taken for every
cmp al,scanln[si] ; byte in a scan line.
je cps3
xchg di,dx ;When byte differs from prev.
mov nwbytes[di],al ; line add it to change buffer
inc di ; and update the scan line
xchg di,dx ; buffer.
mov scanln[si],al
stc
cps3: rcl chgmap[di],1 ;Update chg map for this byte
inc si
cmp si,xsiz
je cps4
test si,7
jnz cps2
inc di
jmp short cps2
cps4: push cx
test xsiz,7
jz cps4a
mov cx,xsiz
and cx,7
mov ch,cl
mov cl,8
sub cl,ch
shl chgmap[di],cl
cps4a: push es
mov es,bufseg
lea si,chgmap
xchg di,bp
mov cx,xsiz
shr cx,1
shr cx,1
shr cx,1
test xsiz,7
jz cps4b
inc cx
cps4b: rep movsb
lea si,nwbytes
mov cx,dx
rep movsb
xchg bp,di
pop es
pop cx
dec cx
jz cps5
cmp smode,9
jb cps44
add bx,xsiz
jmp cps1
cps44: cmp smode,8
jne cps4c
add bh,20h
cmp bh,80h
jb vcps1
sub bh,80h
add bx,90
vcps1: jmp cps1
cps4c: xor bh,20h
test bh,20h
jnz vcps1
add bx,xsiz
jmp cps1
cps5: ret

ucmplane: push es
push ds
pop es
push di
lea di,scanln ;Get first scan line into buf
mov cx,xsiz
call dtaget
pop di
mov cx,ysiz
pop es
ucps1: push cx ;This label xfers a scan line
lea si,scanln ; to the target segment.
mov cx,xsiz
rep movsb
pop cx
dec cx
jnz ucp10
jmp ucpsx ;Jump if its all over!
ucp10: cmp smode,9
jae ucps2a
cmp smode,8
jne ucps1a ;Calc base of next scan line
sub di,xsiz
add di,2000h
cmp di,8000h
jb ucps2a
sub di,8000h
add di,xsiz
jmp short ucps2a
ucps1a: test di,2000h ;Calc base of next scan line.
jnz ucps2
sub di,xsiz
ucps2: xor di,2000h
ucps2a: push es
push di
push cx
push ds
pop es
mov cx,xsiz ;Calc size of change map
shr cx,1
shr cx,1
shr cx,1
test xsiz,7
jz ucps2b
inc cx
ucps2b: lea di,chgmap
call dtaget ;Read change map
xor di,di
xor bx,bx
ucps3: shl chgmap[bx],1
jnc ucps4
push di
push bx
mov cx,1 ;Get a changed byte
lea ax,scanln
add di,ax
call dtaget
pop bx
pop di
ucps4: inc di
cmp di,xsiz ;End of line?
je ucps5
test di,7 ;Time for new byte of chg map?
jnz ucps3
inc bx ;bump change map index
jmp short ucps3
ucps5: pop cx
pop di
pop es
jmp ucps1
ucpsx: ret

;
; The following subroutine opens the screen for Graphics.
;
egmset db 15,13,14,16,16
;
set_mode: cmp smode,8
je hrcopn
mov al,bl
cmp al,9 ;Is it an extended mode?
jb egopn1
xor bh,bh
sub bl,9
mov al,egmset[bx]
egopn1: xor ah,ah
int 10h
cmp smode,12
jae opepal
cmp smode,9
jne opex
mov ax,1003h
xor bl,bl ;Disable Blinking!
int 10h
opex: ret
opepal: push es
push ds
pop es
lea dx,egapal ;Setup the Colors.
mov ax,1002h
int 10h
pop es
ret
;
hrcopn: mov al,2
lea si,herc_set
mov dx,3b8h
out dx,al ;Mode change - screen blank.
mov dx,3b4h
mov cx,12
xor ah,ah
hset1: mov al,ah
out dx,al
inc dx
mov al,[si]
inc si
out dx,al
dec dx
inc ah
loop hset1
hset2: mov al,8ah
cmp hdwseg,0b800h
je hset3
mov al,0ah
hset3: mov dx,3b8h
out dx,al ;Turn screen on!
ret
;
opngraf: mov bl,smode
call set_mode
cmp smode,4 ;IBM Standard Mode?
je opn4clr
ret
;
opn4clr: cmp tpalit,6 ;CGA B&W graphics?
je palhi
mov dx,3d8h ;Assume documented palettes.
mov al,2ah
cmp tpalit,4 ;Is it undocumented?
jb opn3
mov al,2eh ;Set the B&W bit for CRW
opn3: out dx,al
mov bl,tbgc
test tpalit,1 ;Bright or Dark?
jz opn4 ;Its dark!
or bl,10h
opn4: xor bh,bh
mov ah,11
int 10h
mov bl,tpalit
cmp tpalit,4
jb opn5
mov bl,3
opn5: shr bl,1
and bl,1
mov bh,1
mov ah,11
int 10h
ret
;
palhi: mov bl,tbgc ;Get BG Color.
or bl,bl
jnz opnh2
mov bl,0fh ;If black force to white.
opnh2: xor bh,bh
mov ah,11
int 10h
opnhx: ret
;
;..............................................................................
;
; DTAGET.
;
; This routine returns any number of characters from a file to anywhere
; in memory.
;
; ES:[DI] = Address to transfer data to.
;
; CX = Number of characters to transfer.
;
PUBLIC dtaget
;
dtaget: mov si,dtaidx ;Get current DTA index.
dtg0: cmp rlcount,0 ;Is the count 0?
jne dtg0a
mov rlsame,0 ;Get new count from file data.
push ds
mov ds,bufseg
mov al,ds:[si]
pop ds
shl al,1 ;Repeating byte flag to carry
pushf
shr al,1
mov rlcount,al ;Run length
popf
rcl rlsame,1 ;REPEAT flag
inc si
dtg0a: push ds
mov ds,bufseg
mov al,ds:[si]
pop ds
mov es:[di],al
dec rlcount
jnz dtg0b
mov rlsame,0
dtg0b: test rlsame,1
jnz dtg1b
dtg1a: inc si ;Bump the pointers.
dtg1b: inc di
dtg2: dec cx ;Count 1 char transferred.
jnz dtg0 ;Jump if more to send.
mov dtaidx,si ;Save new DTA pointer.
ret ;We're done!
;

Support EndP

CodSeg EndS

END


  3 Responses to “Category : Assembly Language Source Code
Archive   : GX1FILE.ZIP
Filename : GX1FILE.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/