asm.s 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. # vim:filetype=mips
  2. # some asm utils for the Sony Emotion Engine (MIPS R5900)
  3. .set push
  4. .set noreorder
  5. .text
  6. .align 4
  7. # A1B5G5R5 abbb bbgg gggr rrrr
  8. .global do_pal_convert # dest, src
  9. .ent do_pal_convert
  10. do_pal_convert:
  11. li $t0, 0x8000800080008000 #A
  12. li $t1, 0x000E000E000E000E #R
  13. li $t2, 0x00E000E000E000E0 #G
  14. li $t3, 0x0E000E000E000E00 #B
  15. li $t4, 64 # 64 16-bit colours
  16. #Duplicate the lower dword into the upper dword of each mask (0-63 to 64-127).
  17. pcpyld $t0, $t0
  18. pcpyld $t1, $t1
  19. pcpyld $t2, $t2
  20. pcpyld $t3, $t3
  21. # 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.
  22. # PalRow=in_palette[i];
  23. # palette[i]=((PalRow&0x000E)<< 1)|((PalRow&0x00E0)<<2)|((PalRow&0x0E00)<<3) | 0x8000;
  24. pal_convert_loop:
  25. ld $t5, 8($a1)
  26. ld $t6, 0($a1)
  27. pcpyld $t5, $t5, $t6
  28. # 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). :(
  29. #Blue
  30. pand $t6, $t5, $t3
  31. psllh $t6, $t6, 3
  32. #Green
  33. pand $t7, $t5, $t2
  34. psllh $t7, $t7, 2
  35. #Red
  36. pand $t5, $t5, $t1
  37. psllh $t5, $t5, 1
  38. por $t5, $t5, $t0 #Logical OR in the alpha channel
  39. por $t5, $t5, $t6 #Logical OR in the blue channel
  40. por $t5, $t5, $t7 #Logical OR in the green channel
  41. sq $t5, ($a0)
  42. addiu $a1, $a1, 16
  43. addiu $t4, $t4, -8 #8 16-bit colours were processed.
  44. bgez $t4, pal_convert_loop
  45. addiu $a0, $a0, 16
  46. jr $ra
  47. nop
  48. .end do_pal_convert
  49. .global do_pal_convert_with_shadows # dest, src
  50. .ent do_pal_convert_with_shadows
  51. do_pal_convert_with_shadows:
  52. li $t0, 0x8000800080008000 #A mask
  53. li $t1, 0x000E000E000E000E #R mask
  54. li $t2, 0x00E000E000E000E0 #G mask
  55. li $t3, 0x0E000E000E000E00 #B mask
  56. li $a2, 0x39CE39CE39CE39CE #Shadow mask
  57. li $a3, 0x4210421042104210 #Highlight mask
  58. li $t4, 64 # 64 16-bit colours
  59. # $t5 will contain the raw converted colour, without alpha. This will be also used for conversion into the shadow alternate colours.
  60. # Duplicate the lower dword into the upper dword of each mask (0-63 to 64-127).
  61. pcpyld $t0, $t0
  62. pcpyld $t1, $t1
  63. pcpyld $t2, $t2
  64. pcpyld $t3, $t3
  65. pcpyld $a2, $a2
  66. pcpyld $a3, $a3
  67. # 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.
  68. # PalRow=in_palette[i];
  69. # palette[i]=((PalRow&0x000E)<< 1)|((PalRow&0x00E0)<<2)|((PalRow&0x0E00)<<3) | 0x8000;
  70. pal_convert_loop_sh:
  71. ld $t5, 8($a1)
  72. ld $t6, 0($a1)
  73. pcpyld $t5, $t5, $t6
  74. # 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). :(
  75. #Blue
  76. pand $t6, $t5, $t3
  77. psllh $t6, $t6, 3
  78. #Green
  79. pand $t7, $t5, $t2
  80. psllh $t7, $t7, 2
  81. #Red
  82. pand $t5, $t5, $t1
  83. psllh $t5, $t5, 1
  84. por $t5, $t5, $t6 #Logical OR in the blue channel
  85. por $t5, $t5, $t7 #Logical OR in the green channel
  86. por $t6, $t5, $t0 #Logical OR in the alpha channel
  87. sq $t6, ($a0) #Normal
  88. #Highlights
  89. por $t6, $t6, $a3
  90. sq $t6, 0x80($a0)
  91. #Shadows
  92. psrlh $t5, $t5, 1
  93. pand $t5, $t5, $a2
  94. por $t5, $t5, $t0 #Logical OR in the alpha channel
  95. sq $t5, 0x40($a0)
  96. sq $t5, 0xC0($a0)
  97. addiu $a1, $a1, 16
  98. addiu $t4, $t4, -8 #8 16-bit colours were processed.
  99. bgez $t4, pal_convert_loop_sh
  100. addiu $a0, $a0, 16
  101. jr $ra
  102. nop
  103. .end do_pal_convert_with_shadows
  104. .set pop