Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

;    Copyright (C) 1989, 1992 Aladdin Enterprises.  All rights reserved.
; 
; This software is provided AS-IS with no warranty, either express or
; implied.
; 
; This software is distributed under license and may not be copied,
; modified or distributed except as expressly authorized under the terms
; of the license contained in the file LICENSE in this distribution.
; 
; For more information about licensing, please refer to
; http://www.ghostscript.com/licensing/. For information on
; commercial licensing, go to http://www.artifex.com/licensing/ or
; contact Artifex Software, Inc., 101 Lucas Valley Road #110,
; San Rafael, CA  94903, U.S.A., +1(415)492-9861.

; $Id: gdevegaa.asm,v 1.4 2002/02/21 22:24:51 giles Exp $
; gdevegaasm.asm
; Assembly code for Ghostscript PC frame buffer driver

gdevegaasm_TEXT SEGMENT BYTE PUBLIC 'CODE'
        ASSUME  CS:gdevegaasm_TEXT

; Note: Turbo C uses si and di for register variables, so
; we have to preserve them.

; Normal entry and exit.  Arguments are relative to bp.
enterp  macro
        push    bp
        mov     bp,sp
        x = 6                           ; offset of arguments,
                                        ; large code model
        endm
leavep  macro
        pop     bp
        endm
; Fast entry and exit, for procedures that don't use bx until
; they've fetched all their arguments.  Arguments are relative to ss:bx.
enterf  macro
        mov     bx,sp
        x = 4                           ; offset of arguments,
                                        ; large code model
        endm
leavef  macro
        endm

; Fast call to VESA set-page routine.
; void vesa_call_set_page(void (*set_page_proc)(int), int page_no, int win_no)
        PUBLIC  _vesa_call_set_page
_vesa_call_set_page proc far
        enterf
        mov ax,4f05h
        mov dx,ss:[bx+x+4]                      ; page_no
        push ss:[bx+x+2]                        ; set_page_proc
        push ss:[bx+x]
        mov bx,ss:[bx+x+6]                      ; win_no
        ret
_vesa_call_set_page endp

; Structure for operation parameters.
; Note that this structure is shared with C code.
; Not all parameters are used for every operation.
; typedef struct rop_params_s {
p_dest  equ     0        ; fb_ptr dest;  /* pointer to frame buffer */
p_draster equ   4       ; int draster;  /* raster of frame buffer */
p_src   equ     6       ; const byte far *src; /* pointer to source data */
p_sraster equ   10      ; int sraster;  /* source raster */
p_width equ     12      ; int width;    /* width in bytes */
p_height equ    14      ; int height;   /* height in scan lines */
p_shift equ     16      ; int shift;    /* amount to right shift source */
p_invert equ    18      ; int invert;   /* 0 or -1 to invert source */
p_data  equ     20      ; int data;     /* data for fill */
; } rop_params;

; void memsetcol(rop_params _ss *rop)
; {     byte far *addr = rop->dest;
;       int yc = rop->height;
;       while ( yc-- )
;        { byte discard = *addr;
;          *addr = rop->data;
;          addr += rop->draster;
;        }
; }
        PUBLIC  _memsetcol
_memsetcol proc far
        enterf
        push    ds
        mov     ax,ss
        mov     ds,ax
        mov     bx,[bx+x]                       ; rop
        mov     cx,[bx].p_height
        jcxz    msc0                            ; height == 0
        mov     ax,[bx].p_data
        mov     dx,[bx].p_draster
        lds     bx,[bx].p_dest
; Unroll the loop -- two copies.
        inc     cx              ;round up to nearest word.  cx>=2 now.
        shr     cx,1            ;make byte count into word count.
        jnc     msc2            ;if it had been odd, do a half word first.
msc1:   mov     ah,[bx]
        mov     [bx],al
        add     bx,dx
msc2:   mov     ah,[bx]
        mov     [bx],al
        add     bx,dx
        loop    msc1
        pop     ds
msc0:   leavef
        ret
_memsetcol ENDP

; void memsetrect(rop_params _ss *rop)
; {     byte far *addr = rop->dest;
;       int yc = rop->height;
;       while ( yc-- )
;        { int cnt = rop->width;
;          while ( cnt-- ) *addr++ = rop->data;
;          addr += rop->drast - rop->width;
;        }
; }
        PUBLIC  _memsetrect
_memsetrect proc        far
        enterf
        push    ds
        mov     ax,ss
        mov     ds,ax
        mov     bx,[bx+x]                       ; rop
        mov     cx,[bx].p_height
        jcxz    msr0                            ; height == 0
        push    si
        push    di
        mov     ax,[bx].p_data
        les     di,[bx].p_dest
        cld
        mov     dx,[bx].p_draster
        mov     si,cx                           ; si = height
        mov     cx,[bx].p_width
        sub     dx,cx
        cmp     cx,10
        ja      msrl                            ; large count, use fast loop
; Small count, rep stosb is faster.
msrs:   mov     cx,[bx].p_width
        rep     stosb
        add     di,dx
        dec     si                              ; count reps
        jnz     msrs
        pop     di
        pop     si
msr0:   pop     ds
        leavef
        ret
; Large count, loop by words rather than bytes.
msrl:   mov     ah,al                   ;we may be storing words...
msr1:   mov     cx,[bx].p_width
        test    di,1                    ;test for an even address
        je      msr2                    ;if even, we can store words.
        stosb                           ;otherwise we need to even it out.
        dec     cx                      ;(cx is at least one here)
msr2:   shr     cx,1                    ;convert byte count into word count
        rep     stosw                   ;store them puppies as fast as we can.
        jnc     msr3                    ;if an odd number, store it, too.
        stosb                           ;(no need to dec cx here).
msr3:   add     di,dx
        dec     si                      ; count reps
        jnz     msr1
        pop     di
        pop     si
        pop     ds
        leavef
        ret
_memsetrect ENDP

; void memrwcol(rop_params _ss *rop)
; {     byte far *dp = rop->dest;
;       const byte far *sp = rop->src;
;       int yc = rop->height;
;       int shift = rop->shift;
;       while ( yc-- )
;        { byte discard = *dp;
;          *dp = ((*sp >> shift) + (*sp << (8 - shift))) ^ rop->invert;
;          dp += rop->draster, sp += rop->sraster;
;        }
; }
        PUBLIC  _memrwcol
_memrwcol proc far
        enterp
        push    ds
        mov     ax,ss
        mov     ds,ax
        mov     bx,[bp+x]                       ; rop
        cmp     word ptr [bx].p_height,0
        jz      short mrw0
        push    si
        push    di
; Register usage:
;   ds:si = sp, es:di = dp, bx = sraster, dx = draster, cl = shift,
;   ch = invert, ah = low byte of yc.
        push    [bx].p_height
        mov     dx,[bx].p_draster
        mov     ax,[bx].p_sraster
        mov     cl,[bx].p_shift
        mov     ch,[bx].p_invert
        les     di,[bx].p_dest
        lds     si,[bx].p_src
        mov     bx,ax
        mov     ah,[bp-8]                       ; low byte of yc
        test    ah,ah
        jz      mrw2
mrw1:   mov     al,[si]
        ror     al,cl
        xor     al,ch
        xchg    es:[di],al
        add     si,bx
        add     di,dx
        dec     ah
        jnz     mrw1
mrw2:   dec     byte ptr [bp-7]                 ; high byte of yc
        jge     mrw1
        add     sp,2                            ; pop yc
        pop     di
        pop     si
mrw0:   pop     ds
        leavep
        ret
_memrwcol ENDP

; void memrwcol2(rop_params _ss *rop)
; {     byte far *dp = rop->dest;
;       const byte far *sp = rop->src;
;       int yc = rop->height;
;       int shift = rop->shift;
;       while ( yc-- )
;        { byte discard = *dp;
;          *dp = ((sp[1] >> shift) + (*sp << (8 - shift))) ^ rop->invert;
;          dp += rop->draster, sp += rop->sraster;
;        }
; }
        PUBLIC  _memrwcol2
_memrwcol2 proc far
        enterp
        push    ds
        mov     ax,ss
        mov     ds,ax
        mov     bx,[bp+x]                       ; rop
        cmp     word ptr [bx].p_height,0
        jz      short mrw20
        push    si
        push    di
; Register usage:
;   ds:si = sp, es:di = dp, bx = sraster, dx = draster, cl = shift,
;   ch = invert.
        push    [bx].p_height
        mov     dx,[bx].p_draster
        mov     ax,[bx].p_sraster
        mov     cl,[bx].p_shift
        mov     ch,[bx].p_invert
        les     di,[bx].p_dest
        lds     si,[bx].p_src
        mov     bx,ax
mrw21:  mov     ax,[si]                         ; bytes are in wrong order...
        ror     ax,cl
        xor     ah,ch                           ; ... so result is in ah
        xchg    es:[di],ah
        add     si,bx
        add     di,dx
        dec     word ptr [bp-8]                 ; yc
        jg      mrw21
        add     sp,2                            ; pop yc
        pop     di
        pop     si
mrw20:  pop     ds
        leavep
        ret
_memrwcol2 ENDP

gdevegaasm_TEXT ENDS
        END