_compressed_format_decoding.s 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. | Copyright (C) 2003 Kevin Kofler.
  2. | See License.txt for licensing conditions.
  3. .xdef __decode_compressed_offset
  4. .section _st10000
  5. __decode_compressed_offset:
  6. | Decode a compressed offset.
  7. | IN: a0: pointer to the compressed reloc table
  8. | d1: base offset
  9. | d2: nibble count
  10. | OUT: a0: auto-advanced pointer
  11. | d1: computed offset
  12. | d2: nibble count
  13. | C flag: set = end of table, clear = not end of table
  14. addq.w #4,%d1 | overlapping relocs are not allowed, so increase the offset by 4
  15. movem.l %d3/%d4,-(%sp) | save d3 and d4
  16. moveq.l #15,%d4 | mask to get a nibble
  17. | Check if we have nibbles left.
  18. tst.w %d2
  19. bne.s L.nibbles
  20. L.try_again:
  21. | No nibbles left, so decode next byte.
  22. move.b (%a0)+,%d3
  23. subq.b #1,%d3
  24. | Carry means the byte was 0. This means end of table.
  25. bcs.s L.return
  26. addq.b #1,%d3
  27. | 01-7F means we have a byte.
  28. bmi.s L.notbyte
  29. subq.b #1,%d3 | offset is byte value - 1
  30. ext.w %d3 | make full word
  31. bra.s L.add_twice_d3
  32. L.notbyte:
  33. cmp.b #0xC0,%d3
  34. | 80-BF means we have nibbles.
  35. bcc.s L.notnibbles
  36. | Get the byte count.
  37. move.w %d3,%d2
  38. lsr.b #4,%d2 | first nibble only
  39. ext.w %d2 | make full word
  40. subq.w #7,%d2 | convert to remaining byte count
  41. | We want a nibble count, so multiply the byte count by 2.
  42. add.w %d2,%d2
  43. and.w %d4,%d3 | make the nibble into a full word
  44. bra.s L.add_twice_d3
  45. L.notnibbles:
  46. | We have a word. It is encoded as C000-FFFF.
  47. lsl.w #8,%d3
  48. | Complete the word.
  49. move.b (%a0)+,%d3
  50. | FFFF is special.
  51. addq.w #1,%d3
  52. bne.s L.notFFFF
  53. | For FFFF, we have to add 16510*2=33020 to d1 and to decode another offset.
  54. add.w #33020,%d1
  55. bra.s L.try_again
  56. L.notFFFF:
  57. | The word is not FFFF. We have to subtract 49025+1=49026 (+1 because we added 1
  58. | above).
  59. sub.w #49026,%d3
  60. | fall through
  61. L.add_twice_d3:
  62. | Add twice d3. This is because we represent only even offsets.
  63. add.w %d3,%d1
  64. add.w %d3,%d1
  65. | Assuming the table is valid, this should never carry, so the C flag is 0 here.
  66. L.return:
  67. movem.l (%sp)+,%d3/%d4 | restore d3 and d4, not affecting flags
  68. rts | return
  69. L.nibbles:
  70. | Decode nibbles.
  71. | Check whether we want the first or the second nibble of the byte.
  72. btst.l #0,%d2
  73. bne.s L.second_nibble
  74. | The remaining nibble count is even, so we want the first nibble.
  75. move.b (%a0),%d3 | get the byte without advancing to the next one
  76. lsr.b #4,%d3 | first nibble only
  77. ext.w %d3 | make it into a full word
  78. bra.s L.nibbles_done
  79. L.second_nibble:
  80. | The remaining nibble count is odd, so we want the second nibble.
  81. move.b (%a0)+,%d3 | get the byte and advance to the next one
  82. and.w %d4,%d3 | make the nibble into a full word
  83. L.nibbles_done:
  84. subq.w #1,%d2 | decrease the remaining nibble count by 1
  85. bra.s L.add_twice_d3