123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- # vim:filetype=mips
- # some asm utils for the Sony Emotion Engine (MIPS R5900)
- .set push
- .set noreorder
- .text
- .align 4
- # A1B5G5R5 abbb bbgg gggr rrrr
- .global do_pal_convert # dest, src
- .ent do_pal_convert
- do_pal_convert:
- li $t0, 0x8000800080008000 #A
- li $t1, 0x000E000E000E000E #R
- li $t2, 0x00E000E000E000E0 #G
- li $t3, 0x0E000E000E000E00 #B
- li $t4, 64 # 64 16-bit colours
- #Duplicate the lower dword into the upper dword of each mask (0-63 to 64-127).
- pcpyld $t0, $t0
- pcpyld $t1, $t1
- pcpyld $t2, $t2
- pcpyld $t3, $t3
- # I couldn't do this with qword loads and stores in C (There's no 128-bit literal data type definition), but here's the 16-bit (1 colour per literation) equivalent in C for a reference.
- # PalRow=in_palette[i];
- # palette[i]=((PalRow&0x000E)<< 1)|((PalRow&0x00E0)<<2)|((PalRow&0x0E00)<<3) | 0x8000;
- pal_convert_loop:
- ld $t5, 8($a1)
- ld $t6, 0($a1)
- pcpyld $t5, $t5, $t6
- # lq $t5, 0($a1) #This won't work because the CRAM palette may not be aligned to a 128-bit address (And unless the source code of Picodrive is modified for that purpose, use two dword loads instead). :(
- #Blue
- pand $t6, $t5, $t3
- psllh $t6, $t6, 3
- #Green
- pand $t7, $t5, $t2
- psllh $t7, $t7, 2
- #Red
- pand $t5, $t5, $t1
- psllh $t5, $t5, 1
- por $t5, $t5, $t0 #Logical OR in the alpha channel
- por $t5, $t5, $t6 #Logical OR in the blue channel
- por $t5, $t5, $t7 #Logical OR in the green channel
- sq $t5, ($a0)
- addiu $a1, $a1, 16
- addiu $t4, $t4, -8 #8 16-bit colours were processed.
- bgez $t4, pal_convert_loop
- addiu $a0, $a0, 16
- jr $ra
- nop
- .end do_pal_convert
- .global do_pal_convert_with_shadows # dest, src
- .ent do_pal_convert_with_shadows
- do_pal_convert_with_shadows:
- li $t0, 0x8000800080008000 #A mask
- li $t1, 0x000E000E000E000E #R mask
- li $t2, 0x00E000E000E000E0 #G mask
- li $t3, 0x0E000E000E000E00 #B mask
- li $a2, 0x39CE39CE39CE39CE #Shadow mask
- li $a3, 0x4210421042104210 #Highlight mask
- li $t4, 64 # 64 16-bit colours
- # $t5 will contain the raw converted colour, without alpha. This will be also used for conversion into the shadow alternate colours.
- # Duplicate the lower dword into the upper dword of each mask (0-63 to 64-127).
- pcpyld $t0, $t0
- pcpyld $t1, $t1
- pcpyld $t2, $t2
- pcpyld $t3, $t3
- pcpyld $a2, $a2
- pcpyld $a3, $a3
- # I couldn't do this with qword loads and stores in C (There's no 128-bit literal data type definition), but here's the 16-bit (1 colour per literation) equivalent in C for a reference.
- # PalRow=in_palette[i];
- # palette[i]=((PalRow&0x000E)<< 1)|((PalRow&0x00E0)<<2)|((PalRow&0x0E00)<<3) | 0x8000;
- pal_convert_loop_sh:
- ld $t5, 8($a1)
- ld $t6, 0($a1)
- pcpyld $t5, $t5, $t6
- # lq $t5, 0($a1) #This won't work because the CRAM palette may not be aligned to a 128-bit address (And unless the source code of Picodrive is modified for that purpose, use two dword loads instead). :(
- #Blue
- pand $t6, $t5, $t3
- psllh $t6, $t6, 3
- #Green
- pand $t7, $t5, $t2
- psllh $t7, $t7, 2
- #Red
- pand $t5, $t5, $t1
- psllh $t5, $t5, 1
- por $t5, $t5, $t6 #Logical OR in the blue channel
- por $t5, $t5, $t7 #Logical OR in the green channel
- por $t6, $t5, $t0 #Logical OR in the alpha channel
- sq $t6, ($a0) #Normal
- #Highlights
- por $t6, $t6, $a3
- sq $t6, 0x80($a0)
- #Shadows
- psrlh $t5, $t5, 1
- pand $t5, $t5, $a2
- por $t5, $t5, $t0 #Logical OR in the alpha channel
- sq $t5, 0x40($a0)
- sq $t5, 0xC0($a0)
- addiu $a1, $a1, 16
- addiu $t4, $t4, -8 #8 16-bit colours were processed.
- bgez $t4, pal_convert_loop_sh
- addiu $a0, $a0, 16
- jr $ra
- nop
- .end do_pal_convert_with_shadows
- .set pop
|