Sunday, June 24, 2007

XeO3: Bloody bugs!!!

I've been writing the cache code, and its simple enough, but theres a bug in it, and I can't for the life of me find it!! So I thought I'd post it here to see if anyones got any ideas. I suspect I've just been looking at it too much; not that that helps me of course! Anyway, its a simple linked list but the indexes are all +1 so that 0 specifies the end of the list. To offset this I simply subtract 1 from the address to the links which allows the normal use again. Anyway, heres to code....


;
; Y = rotation index
; Temp+16 = pointer to the raw sprite info with an
; 8 byte cache index table
;
lda (Temp+16),y ; get cache index using the current rotation index
tay ; into the sprite cache index list
ldx Cache_Next-1,y ; If we are last, then do nothing!!!
beq Skip_MoveToEnd
lda Cache_Prev-1,y ; get the PREV from our current cache block
sta Cache_Prev-1,x ; and store in the NEXT's Prev

; We've now unlinked from the NEXT item, unlink from PREV item

tax ; and set the PREV of our new one to the OLD last.
beq !We_are_First
lda Cache_Next-1,y
sta Cache_Next-1,x
bne !SkipFirst

!We_are_First:
ldx Cache_Next-1,y
stx FirstCache
lda #$00
sta Cache_Prev-1,x

!SkipFirst:
; Now link the cache block to the end
lda #0
sta Cache_Next-1,y ; get the PREV from our current cache block
lax LastCache
sta Cache_Prev,y ; Set the LAST entry as our prev.
tya
sta Cache_Next-1,x ; and set the last entry's NEXT as our new item
sta LastCache ; now set thr NEW last as the new item.
Skip_MoveToEnd:


So.... There you go! If you spot anything, let me know - while I've still got hair!

4 comments:

  1. Nothing wrong based on a quick glance, but to make it bug faster you can do TAX after branch, and remove LDA from !We_are_First.

    Do you init the list correctly? Are you sure tables don't overlap?

    --
    TNT

    ReplyDelete
  2. no... pretty sure tables are okay - but theres something wrong. If I view the links without this function they are pretty much as expected - add this, and the links go to hell.

    It might be something else wrong, but I cant see it.. :(

    ReplyDelete
  3. This is a severe case of "you see what you want to see". Check the instruction after LAX, more specifically the address...

    To make it bit faster, swap first/not_first order.

    Lack of PRE tag will make this a mess, but is what I ended with:


    ldx Cache_Next-1,y
    beq .x ; last already!

    lda Cache_Prev-1,y ; NEXT.prev = THIS.prev
    sta Cache_Prev-1,x

    ; We've now unlinked from the NEXT item, unlink from PREV item

    bne .notfirst

    ldx Cache_Next-1,y ; FIRST = THIS.next
    stx FirstCache
    lda #$00 ; NEXT.prev = NULL
    sta Cache_Prev-1,x
    beq .end

    .notfirst
    tax ; = PREV

    lda Cache_Next-1,y ; PREV.next = THIS.next
    sta Cache_Next-1,x

    ; Now link the cache block to the end

    lda #0
    .end sta Cache_Next-1,y ; THIS.next = NULL

    lax LastCache ; THIS.prev = LAST

    sta Cache_Prev-1,y
    tya
    sta Cache_Next-1,x ; LAST.next = this

    sta LastCache ; LAST = this

    .x rts

    --
    TNT

    ReplyDelete
  4. THATS IT!!

    Many thanks! I knew I was getting a bit code-blind, and at work I'd usually call upon someone to act as a cardboard programmer to help me find it - but I cant do that at home.

    And thanks to both you for the optimisations as well.

    ReplyDelete