ASM sprite routine stuff

Got questions? Got answers? Go here for both.

Moderator: MaxCoderz Staff

ssartell
Regular Member
Posts: 76
Joined: Fri 02 Dec, 2005 5:39 pm

ASM sprite routine stuff

Post by ssartell »

Alright so I started doing asm yadda yadda. And I really just want to do graphics stuff with it so I'm jumping right into programming a sprite routine. Alright so I tried my hand at just displaying sprites and having them move without clipping but with overlapping on bytes, but my routine just seems really slow and I'm looking for some help on what I can do to make things faster.

Code: Select all

Disp:
   LD IX, sprite
   LD B, 15

Loop:
   LD C, (IX)	;Write current row to registers
   INC IX
   LD D, (IX)
   INC IX
   LD E, 0

   LD A, (xbyte)
Shift:		;Shift row to straddle bytes
   CP 0
   JR Z, EndShift
   SRL C
   RR D
   RR E
   DEC A
   JR Shift
EndShift:

   LD (HL), C	;Load in row
   INC HL
   LD (HL), D
   INC HL
   LD (HL), E

   INC HL	;Get new row
   INC HL
   INC HL
   INC HL
   INC HL

   INC HL
   INC HL
   INC HL
   INC HL
   INC HL
   DEC B
   JR NZ, Loop
   
   RET   
This assumes HL is the address of where the sprite goes in the buffer, sprite is where the actual sprite is held, and xbyte is how many bits to shift the sprite to the right (straddle bytes). This also assumes that the sprite is 16X16. Any help on making this thing faster? Please? With sugar on top?
User avatar
KermMartian
Calc Wizard
Posts: 549
Joined: Tue 05 Jul, 2005 11:28 pm
Contact:

Post by KermMartian »

*cough* IonLargeSprite *cough*
Just look in the sourcecode of Ion.
Image Image Image
Liazon
Calc Guru
Posts: 962
Joined: Thu 27 Oct, 2005 8:28 pm

Post by Liazon »

THe ion libraries don't do clipped do they?
Image Image Image
User avatar
kalan_vod
Calc King
Posts: 2932
Joined: Sat 18 Dec, 2004 6:46 am
Contact:

Post by kalan_vod »

calcul831415 wrote:THe ion libraries don't do clipped do they?
It does.

What way are you detecting key presses? You may wanna check into direct input.
ssartell
Regular Member
Posts: 76
Joined: Fri 02 Dec, 2005 5:39 pm

Post by ssartell »

If by direct input you mean IN's and OUT's then yeah I'm using it. And I don't plan on using the ION libraries.

Does my code look pretty good or does anybody know a much better way of doing this?
Spencer
Extreme Poster
Posts: 346
Joined: Mon 17 Jan, 2005 8:56 am
Location: Indiana

Post by Spencer »

I can't really tell to where you're trying to draw this. But I noticed a few things:
- Lose the "while" structure in your shift loop, assembly outstandingly conforms to "do-while." You need to be getting a remainder of 8 somewhere to know how many shifts you need to do. For example:

Code: Select all

ld a,(xc)
and %00000111
jr z,aligned ;and sets the z flag if remainder is zero
Increment and decrement also effect the flags.
- dec b \ jr nz,xxx is the same as djnz xxxx. The latter is faster and one byte smaller.
- I cannot think of a case where you should use cp 0. Use or a instead.
- If you lack registers, but still need to add a large value to hl, try this:

Code: Select all

push bc
ld bc,10
add hl,bc
pop bc
User avatar
NanoWar
Extreme Poster
Posts: 365
Joined: Fri 17 Dec, 2004 6:39 pm
Location: #$&"%§!
Contact:

Post by NanoWar »

Hmm ionlargesprite?
There you go: http://www.revsoft.org/phpBB2/viewtopic.php?t=175
Weeee 8)
Revolution Software
Stickmanofdoom
Regular Member
Posts: 86
Joined: Fri 17 Dec, 2004 8:20 pm
Contact:

Post by Stickmanofdoom »

if you are adding an unsigned number smaller than 256 to hl, or any 16-bit register, you could always do this:

Code: Select all

ld a,number
add a,l
ld l,a
adc a,h
sub h
ld h,a
you could also change this:

Code: Select all

Loop:
   LD C, (IX)   ;Write current row to registers
   INC IX
   LD D, (IX)
   INC IX
   LD E, 0

   LD A, (xbyte)
Shift:      ;Shift row to straddle bytes
   CP 0
   JR Z, EndShift

to this:

Code: Select all

   ld a,(xbyte)
   ld (shift-1),a

Loop:
   LD C, (IX)   ;Write current row to registers
   INC IX
   LD D, (IX)
   INC IX
   LD E, 0

   or A, $00
Shift:      ;Shift row to straddle bytes
   JR Z, EndShift 
This way, you only load xbyte from a memory address once (a time consuming process), and modify your code to load the value in (xbyte) into A, as if it were a constant.
Also, doing OR instead of LD in fron of the loop, simultainously loads xbyte into A and affects the flags, eliminating the need for OR A or CP 0.
Last edited by Stickmanofdoom on Sat 31 Dec, 2005 12:24 am, edited 2 times in total.
DarkerLine
Calc Wizard
Posts: 526
Joined: Tue 08 Mar, 2005 1:37 am
Location: who wants to know?
Contact:

Post by DarkerLine »

ld a,number
add l,a
ld l,a
adc a,h
sub a
ld h,a
That makes very little sense (add l, a isn't even an instruction).
If you want to add a number smaller than 256, you can still do

ld bc, number
add hl, bc

(de would also work)

The second optimization isn't as useful, reading from an address doesn't take that much time. And or isn't a replacement for ld, you would have

Code: Select all

ld a, 0 / or a
anyways.
just try to be nice to people.
_________________
My TI Blog - http://mpl.unitedti.org/
Stickmanofdoom
Regular Member
Posts: 86
Joined: Fri 17 Dec, 2004 8:20 pm
Contact:

Post by Stickmanofdoom »

Fine, so "add l,a" doesn't exist, but "add a,l" does. Sorry if the typo caused confusion. The "adc a,h / sub h / ld h,a" part just adds the carry flag to h. Also, the example was given for when all the other registers are in use.

The second optimization not only saves 6 clock-cycles per loop, which can add up, but it lets you use the "or $00" optimization.

"or" is certainly not a replacement for "ld" in all cases, but it works in this case. Right before the shift label, A will equal either xbyte or 0. Therefore , "or $00" does the same thing as "ld a,$00" in this case, but it also affects the flags.
Last edited by Stickmanofdoom on Sat 31 Dec, 2005 12:25 am, edited 1 time in total.
ssartell
Regular Member
Posts: 76
Joined: Fri 02 Dec, 2005 5:39 pm

Post by ssartell »

well beyond small optimization tricks are there any major flaws in the design of my routine? I was hoping for more structural advice or methods of writing the sprite data to the screen buffer. Any help?

Spencer: I listed where all the important variables were contained in the registers. HL contains the address of what byte the top left corner of the sprite is being placed in.

I did a quick hack to get around the remainder thing. xbyte contains how much the sprite is shifted and then xpos contains which byte of the 12 in each row that the left most byte should be written to.
Stickmanofdoom
Regular Member
Posts: 86
Joined: Fri 17 Dec, 2004 8:20 pm
Contact:

Post by Stickmanofdoom »

The largest bottleneck in your code is the usage of ix. The four lines after the loop label take 84 cc (clock-cycles). If you could use hl instead, the number of cc would decrease to 26. You would likely have to make use of the stack and/or the ex commands to do that.
ssartell
Regular Member
Posts: 76
Joined: Fri 02 Dec, 2005 5:39 pm

Post by ssartell »

I fixed a bunch of issues I was having with speed and so I've moved on to play with other things as well.

Do most asm coders use ION libraries or just code their own routines?
User avatar
tr1p1ea
Maxcoderz Staff
Posts: 4141
Joined: Thu 16 Dec, 2004 10:06 pm
Location: I cant seem to get out of this cryogenic chamber!
Contact:

Post by tr1p1ea »

Id say it is mostly split. Generally beginner-intermediate asm coders will use shell support routines, until their curiosity about how they work or guilt gets to them, then they will write and use their own :).
"My world is Black & White. But if I blink fast enough, I see it in Grayscale."
Image
Image
ssartell
Regular Member
Posts: 76
Joined: Fri 02 Dec, 2005 5:39 pm

Post by ssartell »

Well I was just asking cause I'm really not at all interested in using any routines from shells and thought maybe I was giving myself a large disadvantage.
Post Reply