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


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

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




Ah, yes, that is my fault, teaches you not to write code at 5am :)

It is easy to fix.  At the top of RenderSprite, change 'ld c,0' to 'ld
c,$ff'.  And change the 'srl d \ rr e' to 'scf \ rr d \ rr e'.  This will
cause the correct mask to be generated.

> (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
> >
> >
> >
>
>
>




References: