home *** CD-ROM | disk | FTP | other *** search
- ; putbits() - by Mike Salisbury - August 25, 1989
- ;
- ; call from C as: putbits(x,y,width,height,bufferptr,fgcolor)
- ; x : x position
- ; y : y position
- ; width : character width in bits
- ; height : character height in bits
- ; bufferptr : pointer to byte buffer holding character
- ; fgcolor : foreground color of character (bg stays same)
- ;
- ; putbits will draw a laserjet formatted character to an ega screen.
- ; x does not have to be byte aligned, but I have included an optimized
- ; routine for drawing byte aligned characters. I have only tested
- ; this on an EGA, but I believe it should work in VGA mode as well.
- ; This is a Turbo Assembler module. I really only save the registers
- ; I have to (CS,SS,DS,BP,SI,DI).
- ;
-
- .model small,C
- .code
-
- PUBLIC putbits
-
- putbits PROC
- ARG x:WORD,y:WORD,w:WORD,h:WORD,buf:PTR WORD,color:BYTE
- LOCAL endinc:WORD,count:WORD,color_shift:WORD,startmask:BYTE,endmask:BYTE
- LOCAL shorter:BYTE
- USES si,di
-
- mov ax,0a000h
- mov es,ax ; Set up EGA video segment
- mov dx,w
- dec dx
- mov cl,3
- shr dx,cl
- inc dx
- mov count,dx ; Save byte size width (rounded up from pixels)
- mov ax,80
- sub ax,dx ; ax = end of line increment
- mov endinc,ax
- mov ax,y
- mov dx,80
- mul dx
- mov dx,x
- mov cl,3
- shr dx,cl ; Save byte size x offset
- add ax,dx
- mov di,ax ; di = video offset
-
- mov cx,h
- jcxz pbab1
- mov si,buf ; si = character data pointer
- mov dx,03ceh ; dx = video port
- mov ax,0a05h ; set Read mode 1, write mode 2
- out dx,ax
- mov ax,0007h ; Set color don't care for all planes
- out dx,ax
- mov ax,x
- and ax,7 ; check if byte aligned
- jnz shifted
-
- mov bl,color
- mov al,8 ; al = Bit Mask register
- pb1:
- push cx
- mov cx,count
- pb2:
- mov ah,[si] ; Byte Aligned
- out dx,ax
- and es:[di],bl ; Draw foreground
- inc si
- inc di
- loop pb2
-
- pop cx
- add di,endinc
- loop pb1
- jmp pbexit
-
- pbab1:
- jmp pbabort ; stepping stone to exit for jcxz above
-
- shifted:
- mov ah,00
- mov shorter,ah ; initialize shorter flag
- mov cx,w ; si,di, and dx already set upon entry
- dec cx
- and cx,7
- xor cl,7
- mov ah,0ffh
- shl ah,cl ; ah = original end mask
- mov cl,al
- xor cl,7
- inc cl ; cl = bits to shift
- mov ch,color
- mov color_shift,cx ; save color and shift
- mov al,ah
- cbw ; ax = original end mask
- mov bx,00ffh ; bx = original start mask
- shl ax,cl
- shl bx,cl ; shift both start and end masks
- mov startmask,bh
- dec endinc
- or al,al
- jnz pb3
- dec count ; decrement total byte count
- inc endinc
- mov al,01
- mov shorter,al ; shifted bytes fit in same space flag
- mov al,ah
- pb3:
- mov endmask,al ; both start and end mask are now set
- mov bx,count
- or bx,bx
- jnz pb4
- and al,startmask
- mov startmask,al ; if only one byte, combine masks
- pb4:
- mov cx,h
- pbrept:
- push cx
- mov cx,color_shift
- mov bx,count
- lodsw ; AL = first byte, AH = second byte
- dec si ; point back to second
- rol ax,cl ; AH = cond+fi, AL = rst+sec
- and ah,startmask
- pb5:
- mov al,8 ; bit mask register
- out dx,ax
- and es:[di],ch ; write bits
- inc di
- cmp bx,1
- jle pb6
- dec si
- dec bx
- lodsw
- rol ax,cl
- mov ah,al
- jmp short pb5 ; go do next byte
- pb6:
- or bx,bx
- jz pb7 ; if only one byte to start with, do next
- dec si
- lodsw
- rol ax,cl
- mov bl,shorter
- or bl,bl
- jnz pb8 ; if shorter flag not set, decrement buffer ptr
- dec si
- pb8:
- mov ah,al
- and ah,endmask
- mov al,8
- out dx,ax ; write ending byte
- and es:[di],ch
- inc di
- pb7:
- add di,endinc
- pop cx
- loop pbrept ; repeat for all lines
-
- pbexit:
- mov ax,0005h ; Reset read/write mode
- out dx,ax
- mov ax,0ff08h ; Reset Bit mask
- out dx,ax
- mov ax,00f07h ; Reset color don't care for all planes
- out dx,ax
- pbabort:
- ret
-
- putbits ENDP
-
- END