[comp.sys.ibm.pc] forcing a graphics pixel to on or off, a question

murphys@cod.UUCP (Steven P. Murphy) (07/30/87)

Here is a question for all the assembly hacks out there.

the appended Bresenham's algorithm works great for drawing lines
on a hercules card but when you give it the color = 0 it does not
turn the pixels off this is do the "or" command (which is found just about
at the end of the program) changing it to an "and" or an "xor" is not
the solution
because ch contains all zeros except for the bit of interest (which may or
may not be a zero)

        mov ch, al
        and ch, cl
        sub cl, ch      ; 7 - (x mod 8) = bit within the byte
        mov ch, color
        sal ch, cl              ; prepare to look at the pixel
--->    or es:[bp], ch          ; or the bit with color
        mov cx, ax
        pop ax

        ret


the bottom line is " how can I force the bit to be 0 or 1 according to
color"

-------------------------------------------------------------------------------


; PXLSEG (color, page, a0, b0, a1, b1)
; function to draw line segment on graphics page 0 or 1,
; using Bresenham's algorithm,
; endpoints are give in pixel coordinates

color   db      ?

delta_a dw 0
delta_b dw 0
half    dw 0


CODE SEGMENT

public _pxlseg

_pxlseg proc    near

        PUSH    BP
        MOV     BP,SP
        PUSH    DI
        PUSH    SI

        PUSH    ES
        PUSH    DS

        mov ax, [bp+4]                  ; get whether pixel should be
        mov color, al                   ; lit or not

        cmp word [bp+6], 1              ; find out which page to write to
        je page1
        mov ax, 0b000h                  ; video ram start for page 0
        jmp set_page

page1:
        mov ax, 0b800h                  ; video ram start for page 1

set_page:
        mov es, ax

        mov si, 1
        mov cx, word [bp+8]     ; initialize a = a0 in cx
        mov ax, word [bp+12]    ; a1
        sub ax, cx              ; a1 - a0 is in ax
        jge set_delta_a
        mov si, -1
        neg ax

set_delta_a:
        mov delta_a, ax         ; delta_a = |a1 - a0|

        mov di, 1
        mov dx, word [bp+10]    ; initialize b = b0 in dx
        mov bx, word [bp+14]    ; b1
        sub bx, dx              ; b1 - b0 is in bx
        jge set_delta_b
        mov di, -1
        neg bx

set_delta_b:
        mov delta_b, bx         ; delta_b = |b1 - b0|

        cmp ax, bx      ; compare delta_a with delta_b
        jl steep        ; |slope| <= 3/2
        mov bx, ax      ; ax holds the pixel count, initially delta_a
        sar bx, 1
        mov half, bx    ; half of delta_a
        xor bx, bx      ; bx will hold the Bresenham "error term"

newpixela:
        call pixel      ; light pixel at cx, dx
        add cx, si      ; increment or decrement a
        add bx, delta_b
        cmp bx, half
        jle dcounta
        sub bx, delta_a
        add dx, di      ; increment or decrement b
dcounta:
        dec ax          ; decrement the pixel count
        jge newpixela


        POP     DS
        POP     ES

        POP     SI
        POP     DI
        POP     BP

        ret


steep:                          ; |slope| > 3/2
        mov ax, bx              ; bx holds the pixel count, initially delta_b
        sar ax, 1
        mov half, ax            ; half of delta_b
        xor ax, ax              ; ax will hold the Bresenham "error term"

newpixelb:
        call pixel              ; light pixel at cx, dx
        add dx, di              ; increment or decrement b
        add ax, delta_a
        cmp ax, half
        jle dcountb
        sub ax, delta_b
        add cx, si              ; increment or decrement a

dcountb:
        dec bx                  ; decrement the pixel count
        jge newpixelb


        POP     DS
        POP     ES

        POP     SI
        POP     DI
        POP     BP

        ret

_pxlseg endp



pixel   proc    near

        push ax
        mov bp, dx
        sar bp, 1
        sar bp, 1       ; y/4
        sal bp, 1       ; 2 * (y/4)
        mov ax, bp
        sal bp, 1
        sal bp, 1       ; 8 * (y/4)
        add bp, ax      ; 10 * (y/4)
        mov ax, bp
        sal bp, 1
        sal bp, 1
        sal bp, 1       ; 80 * (y/4)
        add bp, ax      ; 90 * (y/4) in bp
        mov ax, dx
        and ax, 3       ; y mod 4
        xchg al, ah
        sal ax, 1
        sal ax, 1
        sal ax, 1
        sal ax, 1
        sal ax, 1       ; 02000h * (y mod 4)
        add bp, ax
        mov ax, cx
        sar cx, 1
        sar cx, 1
        sar cx, 1       ; x/8
        add bp, cx      ; offset of byte containing pixel (x,y)
        mov cl, 7
        mov ch, al
        and ch, cl
        sub cl, ch      ; 7 - (x mod 8) = bit within the byte
        mov ch, color
        sal ch, cl              ; prepare to look at the pixel
        or es:[bp], ch          ; or the bit with color
        mov cx, ax
        pop ax

        ret

pixel   endp

code    ends

        end

bill@hpcvlo.HP.COM (Bill Frolik) (07/31/87)

Can't you just do a "not ch", followed by an "and es:[bp],ch"?

bf@hp-pcd

jru@etn-rad.UUCP (John Unekis) (07/31/87)

In article <779@cod.UUCP> murphys@cod.UUCP (Steven P. Murphy) writes:
>
>Here is a question for all the assembly hacks out there.
>
>the appended Bresenham's algorithm works great for drawing lines
>   ..................(more words)
>may not be a zero)
>
>        mov ch, al
>        and ch, cl
>        sub cl, ch      ; 7 - (x mod 8) = bit within the byte
>        mov ch, color
>        sal ch, cl              ; prepare to look at the pixel
>--->    or es:[bp], ch          ; or the bit with color
>        mov cx, ax
>
... try this ...


        mov ch, al
        and ch, cl
        sub cl, ch      ; 7 - (x mod 8) = bit within the byte
	mov ch,0FEH     ;  11111110 hex
        or  ch, color
        rol ch, cl              ; prepare to look at the pixel
        and es:[bp], ch          ; and the bit with color
        mov ch, color
        sal ch, cl              ; prepare to look at the pixel
        or  es:[bp], ch          ; or the bit with color
        mov cx, ax


... it is a few more instructions, but it does the job. 

P.S. - look for the code I am posting monday, it is the source to a game
       which contains a graphics routine for hercules which is faster
       than this , and is written in `C`     .