386BSD 0.1 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Sun, 26 Jan 1992 11:11:06 +0000 (03:11 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Sun, 26 Jan 1992 11:11:06 +0000 (03:11 -0800)
Work on file usr/othersrc/public/ghostscript-2.4.1/gdevegaa.asm

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.1

usr/othersrc/public/ghostscript-2.4.1/gdevegaa.asm [new file with mode: 0644]

diff --git a/usr/othersrc/public/ghostscript-2.4.1/gdevegaa.asm b/usr/othersrc/public/ghostscript-2.4.1/gdevegaa.asm
new file mode 100644 (file)
index 0000000..36676a4
--- /dev/null
@@ -0,0 +1,277 @@
+;    Copyright (C) 1989, 1990, 1991 Aladdin Enterprises.  All rights reserved.
+;    Distributed by Free Software Foundation, Inc.
+;
+; This file is part of Ghostscript.
+;
+; Ghostscript is distributed in the hope that it will be useful, but
+; WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
+; to anyone for the consequences of using it or for whether it serves any
+; particular purpose or works at all, unless he says so in writing.  Refer
+; to the Ghostscript General Public License for full details.
+;
+; Everyone is granted permission to copy, modify and redistribute
+; Ghostscript, but only under the conditions described in the Ghostscript
+; General Public License.  A copy of this license is supposed to have been
+; given to you along with Ghostscript so you can know your rights and
+; responsibilities.  It should be in a file named COPYING.  Among other
+; things, the copyright notice and this notice must be preserved on all
+; copies.
+
+; 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       ; 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, *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, *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