Posted By
   indi on 2006-01-24 14:58:03
  |   Fast allocator....
  I thought I'd share this.... I've no idea if anyone else does this already, but since I just stumbled over it....I thought I'd "share and enjoy".
  In the old days (when I was doing C64 stuff), my allocation routines tended to be bog standard, and very simple, like this....(in fact...I still tend to do this now...)
 
  Alloc:      ldx   #MAX_OBJECTS CheckAll:              lda   InUse,x              beq GotOne              dex              bpl  CheckAll              rts GotOne:            lda #$ff            sta BullInUse,x             rts
 
 
  Now this is all very well and good, but the more "slots" you have the worse it'll get. The easy  answer is a simple linked list or something... but this requires you to link and unlink, and setup is't as simple either, not to mention the overhead of the links themselves.
  So, while I was struggling to find a solution, I stated thinking of some sort of "stack" method... and stumbled into this method- timings were based on 16 slots. (hope the code comes out readable)
 
 
  ;**************************************************************************************** ; ;	Allocate/Free a bullet. ;	Out:	X=spare slot or -1 for error ; ;	Alloc - BEST/WORST	-	12/25 ;	Free - Best/Worst	-	24	  (constant) ;	 ;**************************************************************************************** FreeList	db	0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,$ff
  ; ; Usage:-	AllocBullet	[x|y]		Specify the X or Y register that hold the bullet to free ; AllocBullet	macro	             ld    FreeIndex                    ; 3          ldx  FreeIndex            lda    FreeList,                     ; 4          lda  FreeList            bmi   !NoneFree                    ; 2          bmi  !NoneFree            in                                      ; 2          inx            st    FreeIndex                    ; 3          stx  FreeIndex            ta                                      ; 2          tax            dec   BullInUse,                   ; 7          dec  BullInUse,x !NoneFree:                                      ;             tax            ta                                      ; 2		 get next free bullet (or $ff for none left)            endm
  ; ; Usage:-	FreeBullet	[x|y]		Specify the X or Y register that hold the bullet to free ; FreeBullet   macro                  t a                                       ; 2		txa                  ld   FreeIndex                        ; 3		ldx	FreeIndex                  de                                       ; 2		dex                  st   FreeIndex                       ; 3		stx	FreeIndex                  sta   FreeList,                        ; 5		sta	FreeList,x                  ta                                       ; 2		tax				-	restore index                  lda   #0                                 ; 2		lda	#0                  sta   BullInUse,                     ; 5		sta	BullInUse,x                  endm
 
 
 
  Now, the best thing about it is that it doesn't matter how many you have, its aconstant speed, and all you need to do is setup an array with the freelist in it. You can type it in here as I've done, or calculate it at runtime... In effect its a simple stack, but it never occured to me to use a stack as an allocator before, its very quick and thanks to macros, you can use X or Y to allocate depending on your needs....
  I used this for bullet allocation, and when firing many at once, I took a huge hit... now  allocation is virtually invisible... which is nice  
  |