rle_decompress.S
1 // Note this is a fairly suboptimal approach now, see tmds_encode_1bpp in 2 // tmds_encode.S for a faster and more general solution 3 4 // Taking the encoder from DVI spec, with initial balance 0: 5 // 6 // - Encoding either 0x00 or 0xff will produce a running balance of -8, with 7 // output symbol of 0x100 or 0x200 8 // 9 // - Subsequently encoding either 0x01 or 0xfe will return the balance to 0, with 10 // output symbol of 0x1ff or 0x2ff 11 // 12 // So we can transform a black and white image to TMDS symbols with the 13 // following table: 14 // 15 // x % 2 | Colour | Output 16 // ------+--------+-------- 17 // 0 | 0 | 0x100 18 // 0 | 1 | 0x200 19 // 1 | 0 | 0x1ff 20 // 1 | 1 | 0x2ff 21 // 22 // We will use this to unpack bytes encoded in the following RLE: 23 // 24 // 7|6|5 0 25 // a|b|nnnnnn 26 // 27 // where a, b are the colours of a two-pixel pair, and n is a repeat 28 // count between 1 and 64. 29 30 // r0: Input buffer (byte-aligned) 31 // r1: Output buffer (word-aligned) 32 // r2: Input size (bytes) 33 .global rle_to_tmds 34 .type rle_to_tmds,%function 35 .thumb_func 36 rle_to_tmds: 37 push {r4, lr} 38 add r2, r0 39 mov ip, r2 40 adr r4, tmds_table 41 b 3f 42 1: 43 ldrb r2, [r0] 44 add r0, #1 45 46 // Load symbol pair 47 lsr r3, r2, #6 48 lsl r3, #2 49 ldr r3, [r4, r3] 50 51 // run length - 1 in r2: 52 lsl r2, #26 53 lsr r2, #26 54 2: 55 stmia r1!, {r3} 56 sub r2, #1 57 bcs 2b 58 3: 59 cmp r0, ip 60 bne 1b 61 pop {r4, pc} 62 63 .align 2 64 tmds_table: 65 .word 0x7fd00 // 00 66 .word 0xbfd00 // 10 67 .word 0x7fe00 // 01 68 .word 0xbfe00 // 11