home *** CD-ROM | disk | FTP | other *** search
- _DATA segment word public 'DATA'
-
- include blit.def
-
- count_begin macro
- thisone = $
- dw ?
- endm
-
- count_end macro a
- ifdif <a>,<>
- org $-a
- endif
- thatone = $
- org thisone
- dw thatone-thisone-2
- org thatone
- endm
-
- ;note that the two words previous to the given verb must be the offsets
- ; (in the data segment!) of two routines. The first (cs:put_byte_subr-4) is
- ; a routine that puts the byte in al with a mask of 0ffh. The second
- ; (cs:put_byte_subr-2) is a routine that puts the byte in al using the mask
- ; in dl.
-
- put_byte_subr dw ? ;our transfer mode.
-
- count dw ?
-
- smaller_delta dw ?
- larger_delta dw ?
- epsilon dw ?
-
- new_x_size dw ?
- old_x_size dw ?
- smaller_line dw ?
- larger_line dw ?
- compression db ?
- not_compression db ?
-
- bit_count dw ? ;count of bits in source bitmap.
- line_count dw ? ;count of lines in source bitmap.
- scan_line_count dw ? ;count of lines so far done.
-
- ;we precompute several things:
-
- src_align dw ? ;source bit alignment, 0..7
- src_seg dw ? ;segment of source bitmap
- src_bytes dw ? ;width of source bitmap in bytes
- src_left_bit db ? ;leftmost bit in source bitmap
-
- dest_align dw ? ;destination bit alignment, 0..7
- dest_bytes dw ? ;width of dest bitmap in bytes
- dest_left_bit db ? ;leftmost bit in dest bitmap
-
- ;this following table is used to provide shifts of differing counts.
- ; On a V20, and 80x86; x=1,2,3 we could use the shift with immediate count
- ; instruction, but then we're screwed on 808x processors.
-
- get_byte_ptr dw ?
- get_ptrs label word
- dw 0 ;shift count of zero - not used.
- dw shifted_1_get ;special case - shift count of 1.
- dw shifted_get
- dw shifted_get
- dw shifted_get
- dw shifted_get
- dw shifted_get
- dw shifted_7_get ;special case = shift count of -1 mod 8.
-
- shifted_get label byte
- count_begin
- mov ax,[si] ;get the next two bytes.
- inc si
- rol ax,cl ;align to screen byte.
- count_end
-
- shifted_1_get label byte
- count_begin
- mov ax,[si] ;get the next two bytes.
- inc si
- rol ax,1 ;align to screen byte.
- count_end
-
- shifted_7_get label byte
- count_begin
- mov ax,[si] ;get the next two bytes.
- inc si
- xchg ah,al ;rol ax,7 == xchg ah,al;ror ax,1
- ror ax,1 ;align to screen byte.
- count_end
-
- pset_verb_1 label byte
- count_begin
- stosb
- count_end
- pset_verb_2 label byte
- count_begin
- xor al,es:[di]
- and al,dl
- xor es:[di],al
- inc di ;go to the next byte.
- count_end
-
- and_not_verb_1 label byte
- count_begin
- not al
- and es:[di],al
- inc di ;go to the next byte.
- count_end
- and_not_verb_2 label byte
- count_begin
- not al
- not dl
- or al,dl
- and es:[di],al
- inc di ;go to the next byte.
- count_end
-
- preset_verb_1 label byte
- count_begin
- not al
- stosb
- count_end
- preset_verb_2 label byte
- count_begin
- not al
- xor al,es:[di]
- and al,dl
- xor es:[di],al
- inc di ;go to the next byte.
- count_end
-
- and_verb_1 label byte
- count_begin
- and es:[di],al
- inc di ;go to the next byte.
- count_end
- and_verb_2 label byte
- count_begin
- not dl
- or al,dl
- and es:[di],al
- inc di ;go to the next byte.
- count_end
-
- or_verb_1 label byte
- count_begin
- or es:[di],al
- inc di ;go to the next byte.
- count_end
- or_verb_2 label byte
- count_begin
- and al,dl ;only set the bits given in al.
- or es:[di],al
- inc di ;go to the next byte.
- count_end
-
- or_not_verb_1 label byte
- count_begin
- not al
- or es:[di],al
- inc di ;go to the next byte.
- count_end
- or_not_verb_2 label byte
- count_begin
- not al
- and al,dl ;only set the bits given in al.
- or es:[di],al
- inc di ;go to the next byte.
- count_end
-
- xor_verb_1 label byte
- count_begin
- xor es:[di],al
- inc di ;go to the next byte.
- count_end
- xor_verb_2 label byte
- count_begin
- and al,dl ;only xor the bits given in al.
- xor es:[di],al
- inc di ;go to the next byte.
- count_end
-
- _DATA ends
-
- _TEXT segment byte public 'CODE'
- assume cs:_TEXT, ds:_DATA, ss:_DATA
-
- put_sized:
- mov compression,1 ;assume we're compressing zeroes.
- mov not_compression,0
- cmp put_byte_subr,offset _pset_verb
- jne put_sized_1
- mov compression,-1 ;we're compressing ones
- mov not_compression,1
- put_sized_1:
-
- mov ax,bit_count
- mov old_x_size,ax ;remember the old h size.
-
- mov cx,src_align ;compute the src left bit.
- mov al,80h
- shr al,cl
- mov src_left_bit,al
-
- mov ax,[di].right ;compute the new h size.
- sub ax,[di].left
- mov new_x_size,ax ;remember the new h size.
-
- mov dest_align,bp ;compute the dest left bit.
- mov cx,bp
- mov al,80h
- shr al,cl
- mov dest_left_bit,al
-
- mov ax,[di].bot ;compute the new v size.
- sub ax,[di].top
-
- cmp ax,line_count ;which is larger?
- jb put_shrink_1 ;go if we're shrinking
- ;expand it here. We have more lines in the dest than the source.
- mov bx,line_count ;don't include the last scan line.
- mov smaller_delta,bx
-
- mov larger_delta,ax
- mov line_count,ax
- mov epsilon,0
-
- call blit_setup
- mov src_seg,ax
-
- mov bx,src_bytes
- mov scan_line_count,bx
- put_expand_2:
- push si
- push di
- call put_sized_line
- pop di
- pop si
-
- mov bx,epsilon
- mov dx,larger_delta
- add bx,smaller_delta
- cmp bx,dx ;past the larger yet?
- jl put_expand_3 ;no.
- sub bx,dx ;yes - subtract it.
- add si,src_bytes ;advance to next line.
- put_expand_3:
- mov epsilon,bx
-
- add di,dest_bytes
- dec line_count
- jne put_expand_2
- ret
-
- put_shrink_1:
- ;shrink it here. We have more lines in the source than in the dest.
- mov smaller_delta,ax
-
- mov ax,line_count
- mov larger_delta,ax
- mov epsilon,0
-
- call blit_setup
- mov src_seg,ax
-
- mov scan_line_count,0
-
- put_shrink_2:
- mov bx,src_bytes
- add scan_line_count,bx ;include another scan line in the processing.
-
- mov bx,epsilon
- mov dx,larger_delta
- add bx,smaller_delta
- mov epsilon,bx
- cmp bx,dx ;past the larger yet?
- jl put_shrink_3 ;no.
- sub bx,dx ;yes - subtract it off.
- mov epsilon,bx
-
- push si
- push di
- call put_sized_line
- pop di
- pop si
-
- add si,scan_line_count ;move the source down a line.
- mov scan_line_count,0
-
- add di,dest_bytes ;move to the next line.
-
- put_shrink_3:
- dec line_count
- jne put_shrink_2
- ret
-
-
- put_sized_line:
- ;ds:si->array, es:di->screen, bp=destination alignment,
- ; scan_line_count=number of scan lines to process.
- ;don't destroy bp.
-
- mov ax,new_x_size ;are we changing the x size?
- cmp ax,old_x_size
- jb put_smaller_line ;yes - it's shorter.
- ja put_larger_line ;yes - it's longer.
- mov bx,ax
- mov bp,dest_align ;get the destination alignment.
- jmp put_scan_line ;no - same size.
-
- put_larger_line:
- mov larger_line,ax ;new is larger.
- mov bit_count,ax
- xor bx,bx
-
- mov ax,old_x_size
- mov smaller_line,ax
-
- mov dl,dest_left_bit
- mov dh,src_left_bit ;dh=source mask.
-
- mov cx,bit_count
-
- push ds
- mov ds,src_seg
- assume ds:nothing
-
- mov ah,[si] ;get the first source byte.
- inc si
- put_larger_line_1:
-
- xor al,al
- test dh,ah ;is the source bit set?
- je put_larger_line_2 ;no.
- mov al,dl ;yes - get the dest bit in question.
- put_larger_line_2:
- call put_byte_subr ;put this byte.
-
- add bx,smaller_line
- cmp bx,larger_line
- jb put_larger_line_3
- sub bx,larger_line
-
- ror dh,1 ;move over a source bit.
- jnc put_larger_line_3
- mov ah,[si]
- inc si
- put_larger_line_3:
-
- ror dl,1 ;move over a dest bit.
- adc di,0 ;if cy, move over in di.
- loop put_larger_line_1 ;no.
-
- cmp dh,80h ;did we use any of the source bits?
- jne put_larger_line_5
- dec si ;no - backup.
- put_larger_line_5:
- pop ds
- assume ds:_DATA
- ret
-
-
- put_smaller_line:
- mov smaller_line,ax
-
- mov ax,old_x_size
- mov larger_line,ax
- mov bit_count,ax
- xor bx,bx
-
- mov cx,bit_count
-
- mov dl,dest_left_bit
- mov dh,src_left_bit ;dh=source mask.
-
- push ds
- mov ds,src_seg
- assume ds:nothing
-
- mov ah,7fh ;init the sampling sum.
- put_smaller_line_1:
-
- push bx
-
- mov bx,0
- put_smaller_line_6:
- add ah,not_compression
- test [si+bx],dh ;is the source bit set?
- je put_smaller_line_2 ;no.
- add ah,compression ;yes - count this bit.
- put_smaller_line_2:
- add bx,src_bytes ;move down a scan line.
- cmp bx,scan_line_count ;have we done all of them?
- jne put_smaller_line_6 ;no.
-
- pop bx
-
- add bx,smaller_line
- cmp bx,larger_line
- jb put_smaller_line_4
- sub bx,larger_line
-
- xor al,al ;assume not set.
- xor ah,compression ;flip the sense if necessary.
- test ah,80h ;more ones than zeroes?
- je put_smaller_line_3 ;no.
- mov al,dl ;yes - set this bit.
- put_smaller_line_3:
- call put_byte_subr ;put this byte.
- mov ah,7fh ;init the sampling sum.
-
- ror dl,1 ;move over a dest bit.
- adc di,0 ;if cy, move over in di.
- put_smaller_line_4:
-
- ror dh,1 ;move over a source bit.
- adc si,0
- loop put_smaller_line_1 ;no.
-
- cmp dh,80h ;did we use any of the dest bits?
- je put_smaller_line_5 ;no.
- inc si ;yes - skip to next byte.
- put_smaller_line_5:
- pop ds
- assume ds:_DATA
- ret
-
-
- put_sized_j_1:
- jmp put_sized
-
- public _blit
- _blit:
- push bp
- mov bp,sp
- push si
- push di
- mov si,4[bp]
- mov di,6[bp]
- mov ax,8[bp]
- mov put_byte_subr,ax
- call blit
- pop di
- pop si
- pop bp
- ret
-
- blit_1:
- ret
- blit:
- ;enter with si->source bitmap, di->dest bitmap, put_byte_subr=transfer mode.
- mov ax,[si].right ;compute the h size.
- sub ax,[si].left
- je blit_1 ;if empty, exit now.
- mov bit_count,ax
- mov ax,[si].bot ;compute the v size.
- sub ax,[si].top
- je blit_1 ;if empty, exit now.
- mov line_count,ax
-
- mov bp,[di].left ;compute the destination alignment.
- and bp,7
-
- mov ax,[si].left ;compute the source alignment.
- and ax,7
- mov src_align,ax
-
- mov ax,[si].bytes ;get the source width.
- mov src_bytes,ax
-
- mov ax,[di].bytes ;get the destination width.
- mov dest_bytes,ax
-
- mov ax,[di].right ;are we changing the h size?
- sub ax,[di].left
- cmp ax,bit_count
- jne put_sized_j_1 ;yes.
- mov ax,[di].bot ;are we changing the v size?
- sub ax,[di].top
- cmp ax,line_count
- jne put_sized_j_1 ;yes.
-
- cmp bit_count,8 ;does it fit in one byte?
- jbe blit_2 ;yes - do it "quickly"
- jmp compile_blit ;no - do it "slowly"
- blit_2:
- call blit_setup
-
- mov dx,00ffh ;compute the mask.
- mov cx,bit_count
- ror dx,cl ;make the necessary number of bits.
-
- mov dl,0 ;get rid of the unnecessary bits.
- mov cx,bp
- shr dx,cl ;shift the mask to where it should be.
-
- mov cx,bp ;shift count is dest align-src align.
- sub cx,src_align
- and cl,16-1 ;only 16 bits in a register.
-
- mov bx,put_byte_subr ;get the byte store routine.
- mov bp,dest_bytes
- dec bp
- push ds ;save our data segment,
- mov ds,ax ; and get the source segment.
- assume ds:nothing
- blit_3:
- mov ax,[si] ;get the byte into ax
- add si,src_bytes ;move down a line.
- ror ax,cl ;shift it to where it should be.
- xchg dh,dl
- ;put the byte in al at es:di using the mask in dl
- call bx ;bx=put_byte_subr
- inc di ;move over one byte.
- xchg dh,dl ;get the right mask.
- mov al,ah ;get the right byte.
- call bx ;bx=put_byte_subr
- add di,bp ;bp=dest_bytes.
- dec line_count
- jne blit_3
-
- pop ds
- assume ds:_DATA
- ret
-
-
- copy_code macro
- lodsw
- mov cx,ax
- rep movsb
- endm
-
-
- compile_blit:
-
- push si
- push di
-
- push cs
- pop es
- mov di,offset put_rect_subr
-
- ;in the following code, bp is the destination alignment,
- ; dx is the byte count, si and cx are scratch, bx is used temporarily,
- ; and es:di->the code that we're compiling.
-
- cmp bp,src_align
- je compile_aligned
- jmp compile_shifted
- compile_aligned:
- push di ;remember where to loop back to.
-
- mov bx,bit_count ;get the number of bits left to do.
-
- or bp,bp ;dest alignment zero?
- je compile_aligned_2 ;yes - don't mask on the left.
-
- mov al,0b2h ;opcode of "mov dl,immed8"
- mov cx,bp ;store the mask.
- mov ah,0ffh
- shr ah,cl
- stosw
-
- mov al,0ach ;opcode of lodsb
- stosb
-
- mov si,put_byte_subr ;compile the masked version.
- mov si,cs:[si-2]
- copy_code
-
- add bx,bp ;say that we've done the first few bits.
- sub bx,8 ;. .
- compile_aligned_2:
- shr bx,1 ;truncate to an even number of bytes.
- shr bx,1
- shr bx,1
- cmp put_byte_subr,offset _pset_verb ;are we doing pset?
- jne compile_aligned_7 ;no - have to do it "slowly"
-
- shr bx,1 ;prepare to move words.
- jnc compile_aligned_8 ;is the count odd? go if not.
- mov al,0a4h ;opcode of "movsb"
- stosb
- compile_aligned_8:
- mov al,0b9h ;opcode of "mov cx,immed16"
- stosb
- mov ax,bx
- stosw
- mov ax,0f3h + 0a5h*256 ;opcode of "rep movsw"
- stosw
- jmp short compile_aligned_5
- compile_aligned_7:
- mov dx,bx ;remember the total number of bytes.
- inc bx ;round up.
- shr bx,1 ;remember the number of loop iterations.
- or bx,bx ;are there any iterations at all?
- je compile_aligned_5 ;no - skip the loop.
- mov al,0b9h ;opcode of "mov cx,immed16"
- stosb
- mov ax,bx
- stosw
-
- test dx,1 ;do we need to jump to the second store?
- je compile_aligned_6 ;no.
- mov ax,0ebh + 256*0 ;opcode of "jmp short $+2"
- stosw
- compile_aligned_6:
-
- mov bx,di ;remember where the jump is.
- ;bx now holds the offset of the jump into the loop, which is also
- ; the beginning of the loop.
-
- mov al,0ach ;opcode of lodsb
- stosb
-
- mov si,put_byte_subr ;compile the unmasked version.
- mov si,cs:[si-4] ;get the address of it.
- copy_code
-
- test dx,1 ;are we jumping into the loop here?
- je compile_aligned_4 ;no.
- mov ax,di ;yes - compute the jump offset.
- sub ax,bx
- mov cs:[bx-1],al ;store it.
- compile_aligned_4:
-
- mov al,0ach ;opcode of lodsb
- stosb
-
- mov si,put_byte_subr ;compile the unmasked version.
- mov si,cs:[si-4] ;get the address of it.
- copy_code
-
- mov al,0e2h ;opcode of "loop"
- stosb
-
- mov ax,bx ;compute the jump offset.
- sub ax,di
- dec ax ;because bx->jump offset, not afterward.
- stosb
-
- compile_aligned_5:
- mov cx,bit_count
- add cx,bp ;dest_align
- and cx,7 ;does it align to a right edge?
- je compile_aligned_1 ;yes - skip the right mask.
-
- ;cx now holds the right mask bit count.
- mov ax,00ffh ;rotate the bits into ah.
- ror ax,cl
- mov al,0b2h ;opcode of "mov dl,immed8"
- stosw
-
- mov al,0ach ;opcode of lodsb
- stosb
-
- mov si,put_byte_subr ;compile the masked version.
- mov si,cs:[si-2]
- copy_code
-
- compile_aligned_1:
- jmp compile_blit_2 ;join with the shifting code.
-
-
- compile_shifted:
- mov si,src_align ;use the proper get byte routine.
- sub si,bp
- and si,7 ;only eight different ones.
- shl si,1 ;index into word table.
- mov si,get_ptrs[si]
- mov get_byte_ptr,si
-
- mov al,0b1h ;opcode of "mov cl,immed8"
- stosb
- mov ax,src_align ;shift count is src align-dest align.
- sub ax,bp
- and al,7 ;don't shift too far.
- stosb
-
- cmp bp,src_align ;if we're shifting right, we need to
- jbe compile_shifted_0 ; backup the source by one.
- mov al,4eh ;opcode of "dec si"
- stosb
- compile_shifted_0:
-
- push di ;remember where the loop code starts.
-
- mov bx,bit_count ;get the bit count.
-
- or bp,bp ;is dest alignment zero?
- je compile_shifted_2 ;yes - don't bother masking the left.
-
- mov al,0b2h ;opcode of "mov dl,immed8"
- mov cx,bp ;store the mask.
- mov ah,0ffh
- shr ah,cl
- stosw
-
- mov si,get_byte_ptr ;compile the code to get a byte.
- copy_code
-
- mov si,put_byte_subr ;compile the masked version.
- mov si,cs:[si-2]
- copy_code
-
- add bx,bp ;say that we've done the first few bits.
- sub bx,8 ;. .
- compile_shifted_2:
-
- shr bx,1 ;truncate to an even number of bytes.
- shr bx,1
- shr bx,1
- mov dx,bx ;remember the total number of bytes.
- inc bx ;round up.
- shr bx,1 ;remember the number of loop iterations.
- or bx,bx ;are there any iterations at all?
- je compile_shifted_5 ;no - skip the loop.
-
- mov al,0bbh ;opcode of "mov bx,immed16"
- stosb
- mov ax,bx
- stosw
-
- test dx,1 ;do we need to jump to the second store?
- je compile_shifted_6 ;no.
- mov ax,0ebh + 256*0 ;opcode of "jmp short $+2"
- stosw
- compile_shifted_6:
-
- mov bx,di ;remember where the jump is.
- ;bx now holds the offset of the jump into the loop, which is also
- ; the beginning of the loop.
-
- mov si,get_byte_ptr ;compile the code to get a byte.
- copy_code
-
- mov si,put_byte_subr ;compile the unmasked version.
- mov si,cs:[si-4] ;get the address of it.
- copy_code
-
- test dx,1 ;are we jumping into the loop here?
- je compile_shifted_4 ;no.
- mov ax,di ;yes - compute the jump offset.
- sub ax,bx
- mov cs:[bx-1],al ;store it.
- compile_shifted_4:
-
- mov si,get_byte_ptr ;compile the code to get a byte.
- copy_code
-
- mov si,put_byte_subr ;compile the unmasked version.
- mov si,cs:[si-4] ;get the address of it.
- copy_code
-
- mov ax,4bh + 256*75h ;opcodes of "dec bx" and "jne"
- stosw
-
- mov ax,bx ;compute the jump offset.
- sub ax,di
- dec ax ;because bx->jump offset, not afterward.
- stosb
-
- compile_shifted_5:
- mov cx,bit_count
- add cx,bp ;dest_align
- and cx,7 ;does it align to a right edge?
- je compile_blit_2 ;yes - skip the right mask.
-
- ;bx now holds the right mask bit count.
- mov ax,00ffh ;rotate the bits into ah.
- ror ax,cl
- mov al,0b2h ;opcode of "mov dl,immed8"
- stosw
-
- mov si,get_byte_ptr ;compile the code to get a byte.
- copy_code
-
- mov si,put_byte_subr ;compile the masked version.
- mov si,cs:[si-2]
- copy_code
-
- compile_blit_2:
- ;compute the number of bytes that we've affected.
- mov ax,81h+11000111b*256 ;opcode of "add di,immed16"
- stosw
-
- mov bx,bit_count ;get the bit count.
- add bx,bp ;add align (take care of left edge)
- add bx,7 ;round up (take care of right edge)
- shr bx,1
- shr bx,1
- shr bx,1
-
- mov ax,dest_bytes ;get the width of the dest bitmap.
- sub ax,bx ;sub the number of bytes we've done.
- stosw ;ax=# bytes to next line.
-
- mov ax,81h+11000110b*256 ;opcode of "add si,immed16"
- stosw
-
- mov ax,src_bytes ;get the width of the dest bitmap.
- sub ax,bx ;sub the number of bytes we've done.
- stosw ;ax=# bytes to next line.
-
- mov ax,4dh + 256*75h ;opcodes of "dec bp" and "jne"
- stosw
-
- pop ax ;jump back to the beginning.
- sub ax,di ;subtract target-(di+1),
- dec ax ; because di->after opcode, not operand
- stosb ;store the jump offset
-
- ;if we're shifting right, include the following code:
- cmp bp,src_align ;are we shifting right?
- jbe compile_blit_3 ;no.
- mov al,46h ;opcode of "inc si"
- stosb
- compile_blit_3:
-
- mov ax,01fh + 0c3h*256 ;opcodes of "pop ds" and "ret"
- stosw
-
- pop di ;restore the bitmap pointers.
- pop si
-
- mov bp,line_count ;get the scan line count.
- call blit_setup
- push ds
- mov ds,ax
-
- put_rect_subr:
- db 100h dup(90h)
-
-
- blit_setup:
- ;enter with ds:si->source bitmap, ds:di->dest bitmap.
- ;exit with ax:si->source bits, es:di->dest bits
- mov bx,[di].left ;get x
- shr bx,1 ;get rid of bit position
- shr bx,1
- shr bx,1
- mov ax,[di].top ;compute y-position*dest_bytes
- mul [di].bytes
- add bx,ax
- les di,[di].pntr ;get the pointer to the bitmap.
- add di,bx ;add the offset into the bitmap.
-
- mov bx,[si].left ;get x
- shr bx,1 ;get rid of bit position
- shr bx,1
- shr bx,1
- mov ax,[si].top ;compute y-position*src_bytes
- mul [si].bytes
- add bx,ax
- mov ax,[si].pntr.segm ;get the segment into ax.
- mov si,[si].pntr.offs ;get the offset into si.
- add si,bx ;add the offset into the bitmap.
- ret
-
-
- put_scan_line:
- ;ds:si->array, es:di->screen, bx=bit count, bp=destination alignment
- ;don't destroy bp.
- mov cx,bp ;get destination alignment.
- jcxz put_noshift ;go if it aligns.
- mov dl,0ffh ;al=source mask
- shr dl,cl
- mov al,[si] ;dh=source byte
- shr al,cl ;align to screen byte.
- add bx,bp ;pretend that we've done a whole byte.
- sub bx,8 ;more bytes?
- jle put_scan_line_2
- mov cx,8 ;make cl=8-shift count.
- sub cx,bp
- cmp put_byte_subr,offset _pset_verb
- je put_scan_line_8
- call put_byte_subr
- inc di ;go to the next byte.
- mov dl,0ffh ;eight bits in the rest of the bytes.
- jmp short put_scan_line_5
- put_scan_line_8:
- mov ah,es:[di] ;get the dest byte.
- xor al,ah ;flip the pattern using the dest bits.
- and al,dl ;get rid of the bits we won't change.
- xor al,ah ;flip using only the bits that change.
- put_scan_line_7:
- stosb
- mov ax,[si] ;get the next two bytes.
- inc si ;go to the this byte.
- rol ax,cl ;align to screen byte.
- sub bx,8 ;more bytes?
- ja put_scan_line_7 ;yes - keep doing them
- mov dl,0ffh ;eight bits in the next byte.
- jmp short put_scan_line_2 ;no - finish off the last.
- put_scan_line_4:
- ;put the byte in al at es:di using the mask in dl
- call put_byte_subr
- inc di
- put_scan_line_5:
- mov ax,[si] ;get the next two bytes.
- inc si ;go to the next byte.
- rol ax,cl ;align to screen byte.
- sub bx,8 ;more bytes?
- ja put_scan_line_4 ;yes - keep doing them
- put_scan_line_2:
- add bx,8
- mov cl,bl
- shr dl,cl
- not dl ;we're not including the bits to the right.
- call put_byte_subr
- cmp bp,bx ;did we use any bits from the right byte.
- jae put_scan_line_3 ;no.
- inc si ;yes - skip past it.
- put_scan_line_3:
- ret
-
-
- put_noshift:
- ;ds:si->array, es:di->screen, bx=bit count, bp=destination alignment (0).
- mov dl,0ffh ;eight bits in the rest of the bytes.
- mov cx,bx
- shr cx,1
- shr cx,1
- shr cx,1
- and bx,7
- jcxz put_noshift_2
- cmp put_byte_subr,offset _pset_verb
- jne put_noshift_4
- shr cx,1 ;move words.
- jnc put_noshift_1
- movsb
- put_noshift_1:
- rep movsw
- jmp short put_noshift_2
- put_noshift_4:
- ;put the byte in al at es:di using the mask in dl
- lodsb
- call put_byte_subr
- inc di
- loop put_noshift_4
- put_noshift_2:
- mov cx,bx ;get the number of bits in the next byte.
- jcxz put_noshift_3 ;if none, just skip.
- mov al,[si]
- inc si
- mov dx,0ff00h ;shift the bits in from ah.
- shr dx,cl
- call put_byte_subr
- put_noshift_3:
- ret
-
-
- ;note that the two words previous to the given verb must be the offsets
- ; (in the data segment!) of two routines. The first (cs:put_byte_subr-4) is
- ; a routine that puts the byte in al with a mask of 0ffh. The second
- ; (cs:put_byte_subr-2) is a routine that puts the byte in al using the mask
- ; in dl.
-
- ;new old
- ; | 0 1
- ;-----------
- ; 0 | 0 0
- ; 1 | 1 1
- dw pset_verb_1
- dw pset_verb_2
- public _pset_verb
- _pset_verb:
- xor al,es:[di]
- and al,dl
- xor es:[di],al
- ret
-
-
- ;new old
- ; | 0 1
- ;-----------
- ; 0 | 0 1
- ; 1 | 0 0
- dw and_not_verb_1
- dw and_not_verb_2
- public _and_not_verb
- _and_not_verb:
- not al
- not dl
- or al,dl
- not dl
- and es:[di],al
- ret
-
-
- ;new old
- ; | 0 1
- ;-----------
- ; 0 | 1 1
- ; 1 | 0 0
- dw preset_verb_1
- dw preset_verb_2
- public _preset_verb
- _preset_verb:
- not al
- xor al,es:[di]
- and al,dl
- xor es:[di],al
- ret
-
-
- ;new old
- ; | 0 1
- ;-----------
- ; 0 | 0 0
- ; 1 | 0 1
- dw and_verb_1
- dw and_verb_2
- public _and_verb
- _and_verb:
- not dl
- or al,dl
- not dl
- and es:[di],al
- ret
-
-
- ;new old
- ; | 0 1
- ;-----------
- ; 0 | 0 1
- ; 1 | 1 1
- dw or_verb_1
- dw or_verb_2
- public _or_verb
- _or_verb:
- and al,dl ;only set the bits given in dl.
- or es:[di],al
- ret
-
-
- ;new old
- ; | 0 1
- ;-----------
- ; 0 | 1 1
- ; 1 | 0 1
- dw or_not_verb_1
- dw or_not_verb_2
- public _or_not_verb
- _or_not_verb:
- not al
- and al,dl ;only set the bits given in dl.
- or es:[di],al
- ret
-
-
- ;new old
- ; | 0 1
- ;-----------
- ; 0 | 0 1
- ; 1 | 1 0
- dw xor_verb_1
- dw xor_verb_2
- public _xor_verb
- _xor_verb:
- and al,dl ;only xor the bits given in dl.
- xor es:[di],al
- ret
-
-
- _TEXT ends
-
- end
-