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

 
Output of file : GRPIC.ASM contained in archive : GRPIC.ZIP
NAME GRPIC
;********************************************************************
;* *
;* *
;* Module Name: GRPIC.ASM *
;* Function: Load a compressed (.pcx) pc-paint file on cga. *
;* Author: Wade Dawson *
;* Date: 05/30/88 *
;*------------------------------------------------------------------*
;* NOTE: *
;* This is an example of an assembly language function which *
;* may be used from clipper. The syntax is as follows: *
;* *
;* err = GRPIC(fname,length) *
;* where; *
;* err = The return status : 0-ok, 1-error. *
;* fname = A character var or string containing a filespec. *
;* length = The amount of time in milliseconds to display *
;* picture. *
;* THIS MODULE REQUIRES A MINIMUM OF RELEASE 5.00 OF THE ASSEMBLER *
;* *
;*------------------------------------------------------------------*
;
; CLIPPER assembly interface exapmle.
;
INCLUDE EXTENDA.INC
;
DATASEG DTA
CLstatic
CLstatic ;File work areas
CLstatic ;Video ram work
CLstatic ;Define vidram
CLstatic ;Buffer address
;Storage for work areas
;
pcc_rec label byte
db 0
vers db 0
db 0
bpel db 0
db 12 dup(?) ;skip over less important data
pal db 48 dup(?) ;pallette triplets (16)
db 0 ;skip this to
dplane db 0 ;planes in pic
bytprln dw 0 ;bytes per line
db 61 dup(?) ;get the rest of the header
;
;Storage for .pcx header record (128 bytes)
;
CLpublic ;Make GRPIC known to all
CLfunc int GRPIC ;DEFINE FUNCTION MACRO
CLcode ;Begin code segment, proc GRPIC, save stack.
assume ds:dta ;Point assembler to our DaTA segment
push bx
push cx
push dx
push di
push si
push ds
push es
;
mov ax,dta ;Load DS with our segment address
mov ds,ax ;Put the value in ds
push ds ;Save ds for later
lds dx,path ;Point to file passed by clipper
mov ax,3d00h ;Open file read/write
int 21h ;Dos function call
pop ds ;Get ds back
jnc fname_ok
jmp fname_bad ;CARRY SET MEANS ERROR - EXIT W/ERROR
;open file
fname_ok:
mov bx,ax ;File handle returned in ax
mov f_hdl,ax ;Put in bx and save in memory
lea dx,pcc_rec ;POINT DS:DX TO HEADER RECORD BUFFER
mov cx,128 ;GET HEADER LENGTH (128) IN CX
mov ah,03fh ;Dos read file request
int 21h ;DOS function call
jc fname_bad ;Carry set means error -- exit!
;file header (128 bytes) read
mov ax,4 ;Set CGA mode 4 - 320 x 200, 4-color
int 10h ;BIOS function
;turn on graphics mode (320 x 200) 4 color
mov bl,pal ;Get pallette info
mov cl,4 ;Shift right 4 times
shr bl,cl ;Divide by 16
mov bh,pal + 3 ;Get more pallette info
mov cl,5 ;Divide by 32
shr bh,cl ;Shift right 5 times
mov ah,11h ;BIOS set pallette call
int 10h ;BIOS function call
mov si,0 ;Use si as byte count
les di,vpntr ;Point to vidram
mov last_scan,0 ;Reset scan base
mov buff_off,0 ;Initialize buffer address
mov f_res,0 ;Set "File Resident" flag to FALSE
;Initialize for load
;
;The folllowing loop displays the picture by allocating a buffer, reading the
;file into the buffer, then decrypting and writing the data to a 320X200 CGA
grpic_002:
call read_next_byte ;get a byte from file
jz grpic_done ;exit if error or done
mov cl,al ;save raw data in cl for possible count
and al,192 ;see if bit6 and bit7 set
cmp al,192 ;were they?
jnz grpic_004 ;bit 6 & 7 must BOTH be on - Not Run len enc
;This data is run-length-encoded
and cx,63 ;strip bits 6 & 7, leaving run length in 0-5
call read_next_byte ;get repeat data <-file
jz grpic_done ;z in return means EOF or error - exit
call vstor ;store the data to vidram (es:di)
jmp grpic_002 ;continue until eof
grpic_004:
;This data IS NOT run-length-encoded
mov al,cl ;this data is only 1 byte length
mov cx,1 ;get data byte
call vstor ;write to proper bank
jmp grpic_002 ;continue for whole pic
grpic_done:
les si,buff ;Get buffer address to give back to dos
DOSREQ 49h ;Give buffer back to DOS
;Give memory buffer back to dos
grpic_loop:
mov cx,wate ;Now, delay specified length in [WATE]
grpic_loop2:
mov bx,8000h ;Count to 8000h (about 1 ms)
grpic_003:
sub bx,1 ;Decrement count and affect flags
jnz grpic_003 ;Continue till bx = 0
loop grpic_loop2 ;Continue until cx (user delay time) = 0
mov ax,3 ;Bring back normal text (80 X 25)
int 10h ;BIOS function call
mov ax,0 ;Set zero (good) return code for clipper
jmp back_to_clip ;Return to clipper
;
fname_bad:
mov ax,1 ;This will return a one to clipper (ERROR)
back_to_clip:
pop es
pop ds
pop si
pop di
pop dx
pop cx
pop bx ;Restore any registers used
Clret ax
;
;
;
;
WORKFUNCS
;define support routines
;***************************************
;* S U P P O R T R O U T I N E S *
;***************************************
;
;
read_next_byte proc near
assume ds:dta ;make sure masm knows what segment is ds
push es ;preserve all regs used
push di
push si
push dx
push cx
and f_res,1 ;non-zero means file already read
jnz rnb_002 ;this is a request to return the next byte
;Come here to open the file and read into memory on the first call.
mov bx,f_hdl ;get handle in bx
mov al,2 ;Function 2 - Move to EOF + offset (CX:DX)
DOSREQ 42h ;Dos function, Move read/write file pointer
sub ax,128 ;don't counter 128 byte header
mov f_siz,ax ;save in memory as well
mov al,0 ;Function #0 - Top Of File + offset (CX:DX)
xor cx,cx ;zero cx again
mov dx,128 ;point just pas header record
DOSREQ 42h ;Dos function (LSEEK) move read/write pointer
mov cl,4 ;ready to divide by 16
mov bx,f_siz ;Get size back in bx
add bx,15 ;round up to next paragraph size
shr bx,cl ;convert to paragraphs (16 byte units)
DOSREQ 48h ;request enough memory to hold picture
jc rnb_err ;exit with error if no memory available
mov cx,f_siz ;File size into cx
mov buff_seg,ax ;save segment of buffer
mov buff_off,0 ;set offset part of address to 0
mov bx,f_hdl ;Get file handle back in bx
push ds ;get it from stack
lds dx,buff ;Get buffer address from memory
DOSREQ 03fh ;Dos read from file or device
DOSREQ 03eh ;Close file
mov ax,ds ;Put buffer segment in ax
pop ds ;get our ds back
mov buff_seg,ax ;Reset to start of buffer
mov buff_off,si ;Save pointer to start of buffer
mov f_res,1 ;set "File Resident" logical flag
rnb_002:
;Enter here to return next byte of file
push ds ;preserve this

lds si,buff ;point to buffer
cld ;make string ops count up
lodsb ;get a byte from ds:si
pop ds ;Get our ds back
mov buff_off,si ;Save updated pointer (si)
dec f_siz ;reduce counter
jmp rnb_exit ;exit with decrement status
rnb_err:
or ah,0 ;Set Z condtion for error
rnb_exit:
pop cx
pop dx
pop si
pop di
pop es
ret ;return to calling routine
read_next_byte endp
;
;
vstor proc near
assume ds:dta
cli ;Disable interrupts
cld
cmp si,bytprln ;byte cnt > bytes/line?
jg vstor3 ;yes, advance to next line
vstor2:
stosb
inc si ;bump bytes written cnt
cmp si,bytprln ;written > scan length?
jg vstor3 ;yes, toggle banks
loop vstor2 ;continue for run length in cx
vstor_exit:
sti ;re-enable interrupts
ret ;return to caller
vstor3:
mov di,last_scan ;get last base address
add di,bytprln ;offset by scan leng
mov last_scan,di ;save new scan base
mov dx,es ;use dx for math
xor dx,200h ;toggle b800 & ba00
mov es,dx ;put toggled val in es
cmp dx,0ba00h ;compare segment , ba00
jnz vstor4 ;if not equal, skip sub
mov di,last_scan ;get scan base
sub di,bytprln ;undo add for odd lines
mov last_scan,di ;store modified base pointer
vstor4:
mov si,0 ;reset counter to 0
jmp vstor2 ;Continue for run length
vstor endp
;
;
ENDWORK
;
END




  3 Responses to “Category : Assembly Language Source Code
Archive   : GRPIC.ZIP
Filename : GRPIC.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/