Well, I've been trying to make a code that looks for an object's palette bits based on what each palette is. I've made a 64 byte "palette table" in ram where the first 32 bytes contain individual numbers that correspond to different palettes and where the second 32 bytes say how many objects are currently using the palette. In the code, it first looks at the first 32 bytes to see if any of the existing palettes match the one you are trying to add, and if none of them do, you go to the last 32 bytes that if 0, you can create a new palette in the area in the first 32 bytes that corresponds to the last 32 bytes and also add 1 to the spot you found the empty palette slot in in the last 32 bytes to say that the slot is being occupied. I think I commented pretty good, but If you're unsure about something or just don't get it, you can ask me to better explain. There are a few thing's I'm not sure about that I commented on, and if you have a really good idea for a better way to check for palettes, you can also say that.
This code is for ca65, but I'm sure you can understand it if you don't have it.
This code is for ca65, but I'm sure you can understand it if you don't have it.
Code:
.proc start_palette_checker
rep #$30 ; A=16, X/Y=16
ldx #$0000
palette_checker_loop1:
lda PaletteTable,x ;first 32 bytes specify what palette is in the palette slot
cmp PaletteRequest ;sees if the color in the palette slot matches with the one you are trying to add
bne prepare_for_palette_checker_loop
done:
lda PaletteTable+32,x ;the last 32 bytes say how many objects are using that palette
inc ;so if it is 0, it is safe to overwrite it. a new object is using that palette,
sta PaletteTable+32,x ;so increase it by 1.
sep #$20
ldx
ora Attributes+1 ;this will be direct paged for object slots, I just forgot how to do it without having to do a:.
sta Attributes+1 ;Attributes is the exact same thing as bytes 3 and 4 in oam.
rts
prepare_for_palette_checker_loop:
inx ;we're using 16 bits, so you increase x by 2.
inx
cpx #$0020 ;sees if we're at the second half of the palette table.
bcc palette_checker_loop1
palette_checker_loop2:
lda PaletteTable,x
bne prepare_for_palette_checker_loop ;0 means that no objects are using the palette slot,
;so it is safe to overwrite it.
done2:
ldx
ror ;same thing as dividing by 2? How is asl any different than rol then?
ora Attributes+1 ;this will be direct paged for object slots.
sta Attributes+1 ;Attributes is the exact same thing as bytes 3 and 4 in oam.
lda PaletteRequest
sta PaletteTable-32,x ;remember, x is twice as much here as it would be in done1 (64/2 = 32)
lda PaletteTable,x ;the last 32 bytes say how many objects are using that palette
inc ;so if it is 0, it is safe to overwrite it. a new object is using that palette,
sta PaletteTable,x ;so increase it by 1.
sep #$20 ;how do you get an 8 bit x, because I'm pretty sure that's what you need here
ldx ;(by the way, this next section is going to be pretty rough, because I've never directly worked with DMA...)
asl ;since a palette is 32 bytes and we already have the palette number times 4,
asl ;we multiply it by 8 for the result.
asl
asl
stx $2121 ;says which color to start at
lda PaletteRequest
sta $4302 ; Store data offset into DMA source offset (PaletteRequest is really an adress,
lda #$01 ; and because I'm only using 1 bank for palettes, every number can be its own adress)
sta $4304 ; Store data bank into DMA source bank (bank 1)
lda #$10
sta $4305 ; Store size of data block (32 bytes = 1 16 color palette)
stz $4300 ; Set DMA Mode (byte, normal increment)
lda #$22 ; Set destination register ($2122 - CGRAM Write)
sta $4301
lda #$01 ; Initiate DMA transfer
sta $420B
rts
.endproc
rep #$30 ; A=16, X/Y=16
ldx #$0000
palette_checker_loop1:
lda PaletteTable,x ;first 32 bytes specify what palette is in the palette slot
cmp PaletteRequest ;sees if the color in the palette slot matches with the one you are trying to add
bne prepare_for_palette_checker_loop
done:
lda PaletteTable+32,x ;the last 32 bytes say how many objects are using that palette
inc ;so if it is 0, it is safe to overwrite it. a new object is using that palette,
sta PaletteTable+32,x ;so increase it by 1.
sep #$20
ldx
ora Attributes+1 ;this will be direct paged for object slots, I just forgot how to do it without having to do a:.
sta Attributes+1 ;Attributes is the exact same thing as bytes 3 and 4 in oam.
rts
prepare_for_palette_checker_loop:
inx ;we're using 16 bits, so you increase x by 2.
inx
cpx #$0020 ;sees if we're at the second half of the palette table.
bcc palette_checker_loop1
palette_checker_loop2:
lda PaletteTable,x
bne prepare_for_palette_checker_loop ;0 means that no objects are using the palette slot,
;so it is safe to overwrite it.
done2:
ldx
ror ;same thing as dividing by 2? How is asl any different than rol then?
ora Attributes+1 ;this will be direct paged for object slots.
sta Attributes+1 ;Attributes is the exact same thing as bytes 3 and 4 in oam.
lda PaletteRequest
sta PaletteTable-32,x ;remember, x is twice as much here as it would be in done1 (64/2 = 32)
lda PaletteTable,x ;the last 32 bytes say how many objects are using that palette
inc ;so if it is 0, it is safe to overwrite it. a new object is using that palette,
sta PaletteTable,x ;so increase it by 1.
sep #$20 ;how do you get an 8 bit x, because I'm pretty sure that's what you need here
ldx ;(by the way, this next section is going to be pretty rough, because I've never directly worked with DMA...)
asl ;since a palette is 32 bytes and we already have the palette number times 4,
asl ;we multiply it by 8 for the result.
asl
asl
stx $2121 ;says which color to start at
lda PaletteRequest
sta $4302 ; Store data offset into DMA source offset (PaletteRequest is really an adress,
lda #$01 ; and because I'm only using 1 bank for palettes, every number can be its own adress)
sta $4304 ; Store data bank into DMA source bank (bank 1)
lda #$10
sta $4305 ; Store size of data block (32 bytes = 1 16 color palette)
stz $4300 ; Set DMA Mode (byte, normal increment)
lda #$22 ; Set destination register ($2122 - CGRAM Write)
sta $4301
lda #$01 ; Initiate DMA transfer
sta $420B
rts
.endproc