Re: A83: Re: modules operator


[Prev][Next][Index][Thread]

Re: A83: Re: modules operator




James Matthews wrote:
> 
> This is a GREAT exercise in bit-level ASM, and looking and understand real source code.  Hopefully, soon I'll get on Movax's
> case, and see if I can explain his sprite routines.

The pixel setting code you just explained and Movax's bitmap blit
routine are essentially same in the coordinate code.  The difference is
in the next steps.

<snip similar address finding code>

"hl" now contains the address to blit to in the graph buffer, and the
source address is pushed onto the stack.

        ld      b,00000111b
        and     b
        cp      0
        jp      z,ALIGN

Again, the the result of "x modulus 8" is checked.  If the remainder is
0, then control jumps to a different section of code which performs an
aligned blit, which is much simpler to do.

"a" contains the number if bits to shift by (the result of the and). 
For example, if the sprite lies between two byte boundaries like so:

    00000??? ?????000
    00000??? ?????000
    00000??? ?????000
    00000??? ?????000
    00000??? ?????000
    00000??? ?????000
    00000??? ?????000
    00000??? ?????000

then a would contain 5 because the sprite must be shifted 5 bits to the
right.

        pop     ix
        ld      d,a

Now "ix" contains the source address, and "d" contains the number of
bits to shift by.

        ld      e,8

There are eight lines to blit (this is an 8x8 sprite routine).  Movax
uses the "e" register as the outer loop register since b is used for
other purposes.

LILOP:  ld      b,(ix+0)

This loads a byte of data into "b".

        ld      c,0
        push    de

Since the data is to be blitted on an unaligned boundary, it is not
possible to write the data easily.  One must shift the data and store it
in two bytes (see the picture above).  "c" here is to contain the right
portion of the data, and "b" the left.

The second line stores the value of "d" to be used in future loop
iterations.

SHLOP:  srl     b
        rr      c
        dec     d
        jp      nz,SHLOP

For "d" iterations (the number of bytes to shift by), the bytes are
shifted.  "srl b" shifts b one bit and stores the rightmost bit in the
carry flag.  "rr" rotates the value of c right 1 bit, filling the
leftmost with the carry flag.  Then "d" is decremented and the loop
reiterated if necessary.

        pop     de

The value of "d" previously saved is restored for the next loop
iteration.

        ld      a,b
        xor     (hl)
        ld      (hl),a

The left partial byte of data is written to the graph buffer.

        inc     hl
        ld      a,c
        xor     (hl)
        ld      (hl),a

The right partial byte of data is written to the next byte of the graph
buffer.

        ld      bc,11
        add     hl,bc

Since "hl" has already been incremented, it should only be incremented
by 11, not 12 (96 pixels / 8 bits per pixel = 12 bytes).

        inc     ix

The source address is incremented by 1 only.

        dec     e
        jp      nz,LILOP

        jp      DONE1

The next line of data is processed if necessary.  Otherwise, the routine
is finished.

ALIGN:

An aligned blit is much easier and more efficient, since the complicated
bit shifting of the previous section is unnecessary.

        pop     de

In the aligned blit the source address is popped into "de" instead of
"ix", since "de" is available for use.

        ld      b,8

8 lines.

ALOP1:  ld      a,(de)
        xor     (hl)
        ld      (hl),a
        inc     de
        push    bc
        ld      bc,12
        add     hl,bc
        pop     bc
        djnz    ALOP1

This reads a byte from the source pointer, writes it to the graph
buffer, increments both pointers by the appropriate amounts, then
proceeds to the next loop iteration.

This could be made more efficient, I believe, by using "ix" as the
source register as in the unaligned section and then using "de" as the
loop counter.  This would avoid the push and pop.  This is just
speculation, however; I haven't tested this out.

DONE1:
        ret

End of routine.

-- 
John Kugelman.  kugelman@mnsinc.com

I believe we can change anything.
I believe in my dream.
    - Joe Satriani


References: