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
Thanks for your email Harper, but I have already found a way to accomplish
my thing. In the example below, it is just a questions of loading $FF in the
'second register'. When you shift the bytes, the 1's will stream into reg1.
I already had the AND/(X)OR bitmask/sprite data routines, but when I ANDed
the bitmask, the non-aligned blit was 'clear' in some places. This was
because I loaded $00 in the 'second register: (an example)
(we want to align an 8 bit wide sprite inside a 16 bit buffer:)
'background':
0101010101010101
'bitmask':
00110011
'sprite':
10001000
this is the wrong version:
reg1 - reg 2
before loading:
00000000 - 00000000
loading bitmask
00110011 - 00000000
shift it four times:
00000011 - 00110000
AND it with background:
bg: 0101010101010101
bm: 0000001100110000
result: 0000000100010000
this is wrong because the bg 01 combo is not in the result. The right
version is this:
reg1 - reg2
before loading:
00000000 - 11111111
loading bitmask:
00110011 - 11111111
shift it four times:
11110011 - 00111111
AND with background:
bg: 0101010101010101
bm: 1111001100111111
result: 0101000100010101 (I suppose - it works)
this is right.
Still thx for the e-mail, but can someone please clarify the timing for LDIR
/ CPIR?
Thanks in advance,
Frank Schoep
-----Oorspronkelijk bericht-----
Van: Harper Maddox <gte172i@prism.gatech.edu>
Aan: assembly-83@lists.ticalc.org <assembly-83@lists.ticalc.org>
Datum: maandag 21 augustus 2000 15:49
Onderwerp: 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
>> >
>> >
>> >
>
>