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


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

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




your problem is that you want a "masked" sprite routine.  Probably the 
easiest masked sprite routine to make relies on using an "AND" routine to 
keep the background graphics that you want to stay, while destroying the 
data behind the sprite that you want to display.  This ensures that only 
the area, predetermined by your sprite mask is removed, taking away the 
transparent look from the sprite.  This method of masking is accomplished 
by using an "AND" sprite routine, with the 1's in the sprite standing for 
data you want to preserve, and 0's being the background inside the sprite 
that you want blank.  Then you simply "OR" the desired sprite over the same 
territory as the mask.  Sorry for lack of example, you can do this by 
making 2 sprite routines (one "or" & one "and").

-harper


At 02:15 PM 8/21/00 +0200, you wrote:

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