+ ret
+
+ ; decode RLE from ds:si to es:di, cx: number of decoded bytes (0 means 65536)
+ ; - high bit set for the repetition count, followed by a value byte to
+ ; be repeated N times
+ ; - high bit not set for raw data that should be copied directly
+decode_rle:
+ mov al, [si]
+ inc si
+ mov bl, 1 ; default to "copy once" for raw values
+ test al, 0x80 ; test the high bit to see if it's a count or a raw value
+ jz .copy
+ ; it's a count, clear the high bit, and read the next byte for the value
+ and al, 0x7f
+ mov bl, al
+ mov al, [si]
+ inc si
+.copy: mov [es:di], al
+ inc di
+ dec cx ; decrement decoded bytes counter
+ jz .end ; as soon as it reaches 0, bail
+ dec bl
+ jnz .copy
+ jmp decode_rle
+.end: ret
+