Here's a little collection of random code snippets that could use some serious optimization. Honestly, this is not crucial, but I wanted to learn some more and see if anyone had any recommendations or ideas. Feel free to do whatever you may please. Very Happy

Perhaps use a lookup table for this one?

Code:

GetCircleStuff:
   ld   hl,(EnemyPTR)
   ld   a,(RadiusSize)
   inc   hl
   inc   hl
   inc   hl
   inc   hl
   inc   hl
   ld   (hl),a
   inc   hl
   ld   (hl),84
   ld   a,(ScreenSelect)
   dec   a
   ret   z
   ld   (hl),10   
   dec   a
   ret   z
   ld   (hl),21   
   dec   a
   ret   z
   ld   (hl),31
   dec   a
   ret   z
   ld   (hl),42
   dec   a
   ret   z
   ld   (hl),52
   dec   a
   ret   z
   ld   (hl),63
   dec   a
   ret   z
   ld   (hl),73
   ret


This one just looks awful:

Code:
   push   hl
   pop   ix
   ld   (hl),0
   inc   hl
   ld   (hl),0
   inc   hl
   ld   (hl),0
   inc   hl
   ld   (hl),0
   xor   a
   ld   (NeedAnInput),a
   ld   a,3
   ld   b,a
   inc   b
   call   GetString
   set   7,(iy+20)
   ret


Don't know about this one...


Code:
   inc   hl
   call   LoadRealY
   ld   (hl),a
   inc   hl
   call   LoadRealX
   ld   (hl),a

   inc   hl
   inc   hl
   inc   hl
   inc   hl
   inc   hl

   xor   a
   ld   (hl),a
   ld   a,(EnemyType)   
   or   a
   ret   z
   dec   a
   ret   z


In this one, the first byte holds the amount of bytes to add for each address.


Code:
   ld   hl,12
   ld   de,(PickupData)
   ld   d,0
   add   hl,de
   ld   de,(EnemyData)
   ld   d,0
   add   hl,de
   ld   de,(MapRAM)
   ld   d,0
   add   hl,de
   ld   (NewSize),hl


Hopefully you don't actually commit too much time to this... just an interesting idea... This could be a good way to try and improve our coding. Thanks!
Well, for starters, your last code chunk is 27 bytes by my count. This version is 23 bytes, and almost definitely could be optimized further, especially by changing where all that data is stored. If you put it in three sequential bytes, it would be even easier.

Code:
   ld   hl,12
   ld   a,(PickupData)
   ld   e,a
   ld   d,0
   add   hl,de
   ld   a,(EnemyData)
   ld e,a
   add   hl,de
   ld   a,(MapRAM)
   ld   e,a
   add   hl,de
   ld   (NewSize),hl
Thanks! I probably will be unable to rearrange where the actual data is stored, as the first byte holds the byte amount of each data table, which is then followed by the data table. It would take a while to rearrange everything now... Good idea for later development though. Thanks again!Smile
Sure thing. Smile Above all, those de loads followed by setting d to zero seem rather silly to me, although I sort of understand why you're doing that. Here, I'll take a crack at another one, which is 30 bytes:
Code:
   push   hl
   pop   ix
   ld   (hl),0
   inc   hl
   ld   (hl),0
   inc   hl
   ld   (hl),0
   inc   hl
   ld   (hl),0
   xor   a
   ld   (NeedAnInput),a
   ld   a,3
   ld   b,a
   inc   b
   call   GetString
   set   7,(iy+20)
   ret
Let's try this, which is the same size but faster and more readable:
Code:
   push hl
      pop ix
   xor a
   ld (ix),a
   ld (ix+1),a
   ld (ix+2),a
   ld (ix+3),a
   ld (NeedAnInput),a
   ld a,3
   ld b,4
   call   GetString
   set   7,(iy+20)
   ret
Could I also Do something like this?

Code:
   push   hl
   pop   ix
   xor  a
   ld   (hl),a
   inc   hl
   ld   (hl),a
   inc   hl
   ld   (hl),a
   inc   hl
   ld   (hl),a
   ld   (NeedAnInput),a
   ld   a,3
   ld   b,a
   inc   b
   call   GetString
   set   7,(iy+20)
   ret


That might save even more... Let me check...
Yes, that saves you an additional four bytes. Smile You're getting the hang of this. Also, while ld b,a \ inc b is clever, it doesn't save any space, and it slows things down.
Here's my take on a couple of these:


Code:
GetCircleStuff:
   ld hl,(EnemyPTR)
   ld a,(RadiusSize)
   ld bc,5
   add hl,bc
   ld (hl),a
   inc hl
   ld a,(ScreenSelect)
   ld c,a         ;b = 0 because of the ld bc,5
   ex de,hl      ;de now = (EnemyPTR)+6
   ld hl,table-1   ;-1 because it seems like ScreenSelect starts at 1, so we offset it
   add hl,bc
   ld a,(hl)
   ld (de),a      ;copy 1 byte from hl (table) to de ((EnemyPtr)+6)
   ret
table:
.db 84
.db 10
.db 21
.db 31
.db 42
.db 52
.db 63
.db 73
Btw, often times if you have something like enemy data where you've got your data like: id, x, y, animation frame, action, action counter, etc. it can be nice to use ix with some equates, eg:


Code:
E_ID   = 0
E_X      = 1
E_XVEL   = 2
E_Y      = 3
E_YVEL   = 4
E_ANIM   = 5
E_ANIM_CTR = 6
E_ACT   = 7
E_ACT_CTR = 8

ENEMY_SIZE = 9

handle_enemies:
   ld a,(num_enemies)
   ld b,a
enemy_loop:
   ld a,(ix)               ;or ld a,(ix+E_ID)
   inc a
    jr z,enemy_dead
   push bc
      add a,(E_ANIM)         ;add the animation frame to the id
      ld l,a
      ld h,0
      add hl,hl
      add hl,hl
      add hl,hl            ;(enemy id + 1)*8 (we'll suppose that enemy sprites are 8 bytes)
      ld a,(ix+E_ANIM_CTR)
      inc a
      and $F
       jr nz,$+13
         ld (ix+E_ANIM_CTR),a
         ld a,(ix+E_ANIM)
         xor 1
         ld (ix+E_ANIM),a   ;swap animation back and forth between 0 & 1
      ld a,(ix+X)
      add a,(ix+XVEL)
      ld (ix+X),a            ;add x velocity to enemy x
      ld e,a               ;save x position into e
      ld a,(ix+Y)
      add a,(ix+YVEL)
      ld (ix+Y),a            ;add y velocity to enemy y
      ld bc,enemy_sprites
      add hl,bc
;e = x, a = y, hl = enemy sprite address
      call draw_sprite
   pop bc
enemy_dead:
   ld de,ENEMY_SIZE
   add ix,de
   djnz enemy_loop
   ret
It might not always be as small or as fast as inc/dec'ing hl, but it is much cleaner and when your code starts to get more complex it can be amazing to know that when you've loaded an enemy you can access any part you need easily, for example when detecting collisions you can pull the x and y out and change the id easily if it's been killed, things like that. I guess i got a little sidetracked there, though.

For your second bit of code, this is two bytes smaller than the original:

Code:
   xor a         ;1 4
   ld (hl),a      ;1 7
   ld e,l         ;1 4
   ld d,h         ;1 4
   inc de         ;1 6
   ld bc,3         ;3 10
   ldir         ;2 21 21 16
...but it's definitely much faster and smaller to load (hl) with a here. With regards to the ld b,a \ inc b, 8-bit register to 8-bit register operations take 4 clock cycles (so ld b,a = 1 byte and 4 cycles, as does inc b). Loading an immediate number into an 8-bit register takes 2 bytes (1 byte for the opcode and 1 byte for the number) and 7 cycles. 16-bit registers are a bit slower. Also, (hl) can be used nearly everywhere that b, c, d, e, h, and l can be used, it just can't be used with ix/iy, since those are actually the same opcodes as the hl instructions just with a prefix ($DD and $FD respectively). That's why ix commands are in general 4 cycles slower and 1 byte larger than the normal 16-bit registers. When they have an offset (even if that is zero) they are even slower and take an extra byte for the offset, so you've got the $DD/$FD prefix and the 8-bit offset.

For the next one you can replace all those inc hl's with a ld bc,5 \ add hl,bc. For the last part of that routine, i'm not sure what you really need. Is it important for a to = 0? Or just to quit if a <= 1? You could just cp 2 \ ret c.

Code:
   ld bc,5         ;4 bytes and 21 t states
   add hl,bc
   ld (hl),b
   ld a,(EnemyType)
   cp 2         ;or sub 2 if you want a to = 0 afterwards
    ret c


For the last one, here's an alternative to Kerm's that's 2 bytes smaller and slightly faster:

Code:
   ld de,12
   ld hl,(PickupData)
   ld h,d            ;set h to 0
   add hl,de
   ld a,(EnemyData)
   ld e,a
   add hl,de
   ld a,(MapRAM)
   ld e,a
   add hl,de
   ld (NewSize),hl
...or if NewSize won't go over 255:

Code:
   ld a,(PickupData)
   add a,12
   ld hl,EnemyData
   add a,(hl)
   ld hl,MapRAM
   add a,(hl)
   ld l,a
   ld h,0
   ld (NewSize),hl


EDIT: Oops, forgot to put the equates in the ix example.
Chickendude, I don't think that I ever properly thanked you for these optimizations. Thank you for your help; I did use them, just totally blanked on my thanks. Smile

EDIT: Great work as well, this must have taken you quite some time. Cool
No problem, i'm glad i was able to help out a little. I've been getting my hands wet again with some coding lately, too Smile
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement