A83: Re: Re: LDIR/CPIR clock timing, AND sprite routine


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

A83: Re: Re: LDIR/CPIR clock timing, AND sprite routine




(please excuse me for this long mail, it is needed to explain my problem)

Thank you for your email. The blitting is still not perfect, but I know what
the fault is, except I don't know how to resolve it. The AND mask screws up
in this way:

Suppose you have these pixels:

0000111100001111

you have this bitmask (0 means 'sprite here' 1 means 'keep this pixel')

00110011

this is the official sprite:

10101010

Now, we want the sprite blitted in the middle of the 16 pixels:

current pixels: 0000111100001111
we shift the bitmask:

reg 1 - reg 2
before load:
00000000 - 00000000
now load mask in 1:
00110011 - 00000000
shift 1:
00011001 - 10000000
shift 2:
00001100 - 11000000
shift 3:
00000110 - 01100000
shift 4:
00000011 - 00110000

the mask is perfect, isn't it? No - it is not:
thanks to the shifting, the left bits of Reg1 are 0's, which erase the
background. This is also the case with the right bits of Reg2. So: the bits
that are shifted out of each register should be 1. The mask I should have
looks like this:

(shift 4 example from above:) this is wrong:
00000011 - 00110000
this should be:
11110011 - 00111111

This mask will not overwrite the background. XOR does not have this problem,
because zero's mean that the pixels are preserved. I don't know if anyone
has a way to make sure the outer (shifted) bits become 1's, please tell me.

This problem does not occur when the sprite is aligned to a bit, because
there are no 0's shifted in the registers...

The routine you have sent me works perfectly, except that it has this
'shifting' problem. I don't know if this is a serious problem, but you
coderz should be able to come up with a solution. I have a fully working
sprite AND XOR routine, but it erases the background when non-aligned...

Thanks in advance,
Frank Schoep

-----Oorspronkelijk bericht-----
Van: David Phillips <david@acz.org>
Aan: assembly-83@lists.ticalc.org <assembly-83@lists.ticalc.org>
Datum: maandag 21 augustus 2000 13:13
Onderwerp: A83: Re: LDIR/CPIR clock timing, AND sprite routine


>
>> - What is the clock timing for LDIR and CPIR? I've read in ASM GURU that
>> LDIR takes 21/1 clocks, does this mean it takes 21+1*(number of bytes to
>> copy) clocks, or is it just 21? (same questions for CPIR - 21/1 clocks)
>
>Asm Guru is wrong, as were earlier versions of the Assemby Studio help
file.
>This is due, most likely, to the z80time.txt file having incorrect (or at
>least mis-interpreted) fall-through timings for some instructions.  In the
>case of the repeat instructions, fall through is not quite the proper term.
>First, you need to understand how the repeat instructions work.  You may
>have noticed, for example, that LDIR and LDI are very similiar.  This is
>because an LDIR is a Repeated LDI.  Everytime the instruction copies data,
>it takes 21 clock cycles.  So the timing is 21 times BC (or in the case of
>CPIR, it can early out if A = (HL)).  When the instruction ends, you have
>the fall through time.  This is not 1 (the same as it is not 1 for a JP),
>but I don't remember what the proper timing would be (7 seems right).
>
>Because the processor treats it as executing multiple LDI or CPI
>instructions, interrupts can occur in the middle of the operation.  Now
that
>I think about it, I can't remember how the processor retains the internal
>registers when this occurs.  My guess is that it pushes the return address
>as the start of the repeat instruction, and assumes that the interrupt
>handler preserves the state of the registers.  This should be fairly easy
to
>test, although I do not know if every z80 emulates it properly (though I
>would think it should).  I don't have time at the moment to research this
>further.  The z80 core from MAME would be a good place to check (it is the
>one used in VTI and afaik is completely acurate).
>
>> - Is there any decent AND sprite routine available? I've tried modifying
>> MOVAX' XOR sprite routine (e.g.: change all 'xor (hl)' commands into 'and
>> (hl)'. This does not seem to be working OK. The aligned sprite blitting
is
>> OK, but the non-aligned blitting screws up. Does anybody know why?
>
>This is off the top of my head (not tested), but should work.  As with most
>sprite routines, aligned blitting is not optimized as a special case (this
>makes it smaller).  If you want the sprite to be passed in HL, add a "push
>hl \ pop ix" at the beginning.  I leave adding extras such as masks as an
>excericise to the reader  :)
>
>; ix = sprite (8x8), bc = x,y coords
>PutSprite:
> call FindAddress
> ld de,VideoBuffer         ; this is the graph screen or wherever to draw
>the sprite
> add hl,de
> ld c,a
> ld b,8
>RenderSprite:
> ld d,(ix+0)
> ld e,0
> inc ix
> ld a,c
> or a
> jr z,ShiftDone
>Shift:
> srl d
> rr e
> dec a
> jr nz,Shift
>ShiftDone:
> ld a,(hl)
> and d            ; this is where the AND takes place, this can be OR or
>probably XOR
> ld (hl),a
> inc hl
> ld a,(hl)
> and e            ; AND here as well
> ld (hl),a
> ld de,11
> add hl,de
> djnz RenderSprite
> ret
>
>; bc = x,y coords
>; returns: hl = offset in video buffer (96x64), a = number of times to
shift
>FindAddress:
> ld a,c                 ; this part is not optimized
> add a,a
> add a,a
> ld e,a
> ld h,0
> ld d,h
> ld l,a
> add hl,hl
> add hl,de
> ld a,b
> rra
> rra
> rra
> and %00011111
> ld e,a
> add hl,de
> ld a,b
> and %00000111
> ret
>
>
>




Follow-Ups: