home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.update.uu.se
/
ftp.update.uu.se.2014.03.zip
/
ftp.update.uu.se
/
pub
/
rainbow
/
msdos
/
decus
/
RB140
/
grlib03a.arj
/
RWCELL.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-12-08
|
12KB
|
518 lines
TITLE RWCELL.ASM
PAGE ,132
include asmc.h
SEGEND CODE
SEGDEF DATA
include asmd.h
SEGEND DATA
SEGDEF CODE
PUBLIC rd_cell
PUBLIC wr_cell
IF @BIGMODEL
EXTRN a_fgbg:FAR, a_alups:FAR, a_gbmsk:FAR, a_mode:FAR
EXTRN cxy2cp:FAR, free:FAR, gdc_nb:FAR, malloc:FAR
ELSE
EXTRN a_fgbg:NEAR, a_alups:NEAR, a_gbmsk:NEAR, a_mode:NEAR
EXTRN cxy2cp:NEAR, free:NEAR, gdc_nb:NEAR, malloc:NEAR
ENDIF
;******************************************************************************
;* *
;* F U N C T I O N rd_cell(strctr) *
;* struct g_cell *strctr; *
;* *
;* purpose: Read one plane of the 'cell' (specified as 'bottom left' *
;* 'top right') into an array. The structure will be filled *
;* in appropriately if successful and a value of '1' will be *
;* returned. If memory could not be allocated, a 'NULL' is *
;* returned. *
;* 'strctr' is defined in graph.h and is of the form: *
;* *
;* struct g_cell { *
;* int c_corner[4], *
;* c_plane, *
;* c_rows, *
;* c_bytes; *
;* unsigned char *c_segment, *
;* c_offset[]; *
;* }; *
;* *
;* Before calling rw_cell(), fill in the c_corner[] array with *
;* the bottom-right & top-left 'xy' co-ordinates and set c_plane *
;* to the plane number you want to read. (0 to 1 or 3, depending *
;* on high or medium resolution workstation type.) *
;* 'c_segment' would not normally be used explicitly by the user *
;* unless the whole bitmap needs to be read. If the function is *
;* called with 'c_segment' = 0, memory will be automatically *
;* requested and the current data seg will be used. *
;* *
;* ****************************************************************** *
;* ******* REMEMBER TO 'free(strctr->c_offset)' IT AFTERWARDS ******* *
;* ****************************************************************** *
;* *
;* To set up an external area, use the msdos get memory function *
;* *
;* The bytes in the array at c_offset will be bit aligned. *
;* Any particular bit may then be accessed/changed eg. *
;* *
;* r = strctr->c_rows - 1; *
;* b = strctr->c_bytes; *
;* strctr->c_offset[(r * b) + b] |= 128; *
;* *
;* Will set the first bit in the last byte of the last row of *
;* the plane read, as long as the array is in your current data *
;* segment. If not, you will need to play around moving chunks *
;* into your DS, change it, then move it back again. *
;* *
;******************************************************************************
;LOCAL READ SUBROUTINE
Lrd_bytes PROC NEAR
in al,56H ;byte ready to be read?
test al,01H
jz Lrd_bytes ;jump if not.
in al,57H ;read the byte.
stosb
loop Lrd_bytes
ret
Lrd_bytes ENDP
PROCDEF rd_cell
push si
push di
push bp
mov bp,sp
sub sp,8 ; -2[bp] alups reg.
; -4[bp] No. of pixels.
; -6[bp] No. of bytes per row.
; -8[bp] No. of rows.
mov ax,cs:eseg_sav ;just in case!
mov es,ax
cld ;make the coming stosb instruction increment di.
mov si,WORD PTR 8[bp] ;get pointer to the structure.
mov ax,WORD PTR 4[si] ;top right 'x'
sub ax,WORD PTR [si] ;minus bottom left 'x'
inc ax ;equals No. of pixels.
mov WORD PTR -4[bp],ax
add ax,7
mov cl,3
shr ax,cl ;number of bytes in one array element.
mov WORD PTR -6[bp],ax
mov cx,ax
mov ax,WORD PTR 6[si] ;top right 'y'
sub ax,WORD PTR 2[si] ;minus bottom left 'y'
inc ax ;equals No. of rows.
mov WORD PTR -8[bp],ax
mul cx ;bytes * rows.
cmp WORD PTR 14[si],0000H ;any segment defined ?
jnz L2
push si
push ax
call malloc ;allocate space in our Data seg.
add sp,2
pop si
or ax,ax ;did it work ?
jnz L1a
jmp Lexit ;quit on failure.
L1a: mov WORD PTR 16[si],ax ;update the structure's c_offset
mov ax,ds ;and c_seg info.
mov WORD PTR 14[si],ax
L2: mov di,si ;point DI to strctr.c_rows.
add di,000AH
mov ax,WORD PTR -8[bp]
stosw ;number of rows.
mov ax,WORD PTR -6[bp]
stosw ;number of bytes per row.
mov al,alups ;save old alups on the stack.
mov WORD PTR -2[bp],ax
mov alups,0fH ;disable all writes.
call gdc_nb
call a_alups
mov ax,WORD PTR 8[si] ;juggle mode for the specified plane.
and al,3
shl al,1
shl al,1
and gbmod,0a1H
or gbmod,al
call a_mode
mov ax,ymax ;convert 'y' co-ord to top left origin.
sub ax,WORD PTR 2[si]
mov y_start,ax
mov ax,WORD PTR [si] ;set up the starting 'x' co-ordinate.
mov bx,ax
and ax,0fff0H ;make 'x' a word address.
mov x_start,ax
mov ax,bx ;get 'x' address
and ax,07H ;x % 8
add ax,WORD PTR -4[bp] ;add the number of pixels.
add ax,7 ;is last byte an odd address?
Lrd1: mov cl,03H
shr ax,cl
mov cx,ax ;CX = total bytes to read.
mov dl,0 ;if first byte is on an odd address
test bl,08H ; DL = 1 and we need to throw away the
jz Lrd2 ; first byte read in.
inc dl
inc ax
Lrd2: test al,01H ;still an odd number of bytes ?
jz Lrd3 ;jump if not.
inc ax
Lrd3: shr ax,1 ;AX = number of words to read.
mov WORD PTR nmritl,ax
mov ax,WORD PTR [di] ;get the es seg
mov di,WORD PTR 2[di] ;and offset.
Lrd4: push dx
push cx
push di
push ax
call cxy2cp
lea di,gp_buff ;DI register points to gp_buff_.
mov al,4aH ;set all bits in gdc mask.
out 57H,al
mov al,0ffH
out 56H,al
out 56H,al
mov al,4cH ;assert the figs command.
out 57H,al
mov al,2 ;direction is to the right.
out 56H,al
mov ax,WORD PTR nmritl
out 56H,al
mov al,ah
out 56H,al
mov al,0a0H ;start the read operation now.
out 57H,al
or dl,dl ;is first byte on an odd address ?
jz Lrd5
push cx ;read first byte and throw it away.
mov cx,1
call Lrd_bytes
pop cx
dec di
Lrd5: call Lrd_bytes
pop ax
mov es,ax
pop di
lea si,gp_buff ;point SI to the bytes read.
mov ax,bx ;'x' start
and al,07
mov cl,08
sub cl,al
mov dx,WORD PTR -6[BP] ;get bytes/row
Lrd6: lodsw
xchg ah,al
shr ax,cl
stosb
dec si
dec dx
jnz Lrd6
push es
mov ax,ds
mov es,ax
pop ax
pop cx
pop dx
dec WORD PTR -8[bp] ;decrement 'row' count
jz Lrd7
dec y_start ;point to next screen line.
jmp Lrd4
Lrd7: mov al,6fH ;send a 'do nothing' to turn the fifo round.
out 57H,al
or gbmod,10H ;The following chunk of code is included
call a_mode ;because the GDC has a problem writing to
mov al,4cH ;the bitmap after a read sequence has been
out 57H,al ;completed.
xor al,al
out 56H,al
out 56H,al
out 56H,al
mov al,22H
out 57H,al
mov al,0ffH
out 56H,al
out 56H,al
mov ax,WORD PTR -2[bp]
mov alups,al
call gdc_nb
call a_alups
mov ax,1
Lexit: mov sp,bp
pop bp
pop di
pop si
ret
PROCEND rd_cell
;******************************************************************************
;* *
;* F U N C T I O N wr_cell(strctr) *
;* struct g_cell *strctr; *
;* *
;******************************************************************************
;LOCAL WRITE SUBROUTINE
; Enters with : BX = number of bytes to write.
; CH = number of bits displayed in left-hand byte.
; DH = number of bits in the right-hand byte.
; DL = 0 - first byte is EVEN, last byte is ODD.
; 1 - first byte is ODD.
; 2 - last byte is EVEN.
; 3 - first byte is ODD, last byte is EVEN.
Lwrite PROC NEAR
call cxy2cp
lea si,gp_buff
mov ax,0ffffH
test dl,01H ;is first byte ODD ?
jnz Lwr4 ;jump if it is.
inc al ;AX = 0xff00
Lwr4:
xchg cl,ch ;make the left hand mask.
shl ax,cl
mov WORD PTR gbmskl,ax
mov WORD PTR nmritl,0000H ;one word to be written.
mov cx,0002H ;first bytes always on a word boundary.
sub bx,cx
jnz Lwr4b
push bx
mov bx,0ffffH
mov cl,dh
test dl,02H
jnz Lwr4a
inc bh
Lwr4a: shr bx,cl
or ax,bx
pop bx
Lwr4b: mov WORD PTR gbmskl,ax
call Lrit
or bx,bx
jnz Lwr4c
ret
Lwr4c:
mov WORD PTR gbmskl,0000H ;set mask and count for 'words'.
mov WORD PTR nmritl,0007H
Lwr5: ;Loop to write 16 bytes at a time.
mov cx,0010H
sub bx,cx
js Lwr6
call Lrit
jmp Lwr5
Lwr6:
add bx,0010H
cmp bx,02H
jz Lwr8
sub bx,02H
mov cl,bl
shr bx,01
dec bx
mov WORD PTR nmritl,bx
call Lrit
Lwr8: ;Write the last byte[s].
mov WORD PTR nmritl,0000H
mov ax,0ffffH
mov cl,dh
test dl,02H
jnz Lwr9
mov ah,00H
Lwr9: shr ax,cl
mov WORD PTR gbmskl,ax
mov cl,02H
Lrit:
call gdc_nb
mov al,0feH ;select the write buffer.
out 53H,al
out 51H,al ;zero the counter.
Lrit0:
lodsb
out 52H,al
loop Lrit0
mov al,0feH ;reset the counter to zero.
out 53H,al
out 51H,al
call a_gbmsk
mov al,4aH ;set the GDC mask to enable:
out 57H,al
mov al,0FFH
out 56H,al
out 56H,al
mov al,4cH ;assert the figs command.
out 57H,al
mov al,02H ;direction is to the right.
out 56H,al
mov ax,WORD PTR nmritl ;number of words to write.
out 56H,al
mov al,ah
out 56H,al
mov al,22H ;start the write operation now.
out 57H,al
mov al,0ffH
out 56H,al
out 56H,al
ret
Lwrite ENDP
PROCDEF wr_cell
push si
push di
push bp
mov bp,sp
sub sp,6 ; -2[bp] alups reg.
; -4[bp] number of rows.
; -6[bp] number of bytes per row.
mov ax,cs:eseg_sav ;just in case!
mov es,ax
cld ;make the coming stosb instruction
;increment di.
mov al,alups ;save old alups on the stack.
mov WORD PTR -2[bp],ax
mov si,WORD PTR 8[bp] ;get structure pointer.
mov ax,ymax ;convert 'y' co-ord to top left origin.
sub ax,WORD PTR 2[si]
mov y_start,ax
mov ax,WORD PTR [si] ;set up the starting 'x' co-ordinate.
mov bx,ax
and ax,0fff0H ;make 'x' a word address.
mov x_start,ax
mov dx,WORD PTR 4[si]
sub dx,WORD PTR [si] ;number of pixels to write.
inc dx
mov ax,bx
and bx,000fH
add bx,dx
push dx
mov cl,03H
test bx,0007H
jz Lw1
add bx,0008H
Lw1: shr bx,cl
test bx,0001H
jz Lw1a
inc bx
Lw1a:
mov ch,al
xor dl,dl
test ch,08H
jz Lw2
inc dl
Lw2: and ch,07H
pop di
add ax,di
dec ax
mov dh,al
test ax,08H
jnz Lw3
or dl,02H
Lw3: and dh,07H
inc dh
mov cl,08H
sub cl,ch
xchg cl,ch
add si,0008H ;SI register points to the stucture.
push cx
mov cx,WORD PTR [si] ;get plane # and adjust alups to only
mov al,01H ; write to this one.
shl al,cl
xor al,0fH
and BYTE PTR alups, 0F0H
or alups,al
mov fgbg,0FH ;enable foreground writes.
call gdc_nb
call a_fgbg
call a_alups
and gbmod,0FDh ;set mode to WORD writes.
or gbmod,8H
call a_mode
pop cx
mov ax,WORD PTR 2[si] ;number of rows.
mov WORD PTR -4[bp],ax
mov ax,WORD PTR 4[si] ;bytes per row.
mov WORD PTR -6[bp],ax
mov si,WORD PTR 8[si] ;array offset.
Lw4: push si
lea di,gp_buff ;gp_buff will hold the word aligned bit pattern
test dl,1
jz Lw4a
inc di
Lw4a: push ds
push bx
mov bx,WORD PTR 8[bp]
mov ax,WORD PTR 14[bx]
mov ds,ax
pop bx
push bx
Lw5: ;loop to bit align 'array' on a word boundary
lodsb ;at gp_buff.
ror ax,cl
stosb
xchg cl,ch
ror ax,cl
xchg cl,ch
dec bx
jnz Lw5
pop bx
pop ds
push bx
push cx
call Lwrite ;WRITE one line.
pop cx
pop bx
pop si
add si,WORD PTR -6[bp]
dec WORD PTR -4[bp]
jz Lw6
dec y_start
jmp Lw4
Lw6:
mov ax,WORD PTR -2[bp]
mov alups,al
call gdc_nb
call a_alups
mov sp,bp
pop bp
pop di
pop si
ret
PROCEND wr_cell
include epilogue.h
END