1 /* ----------------------------------------------------------------------- * 2 * 3 * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved 4 * Copyright 2009 Intel Corporation; author: H. Peter Anvin 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 9 * Boston MA 02110-1301, USA; either version 2 of the License, or 10 * (at your option) any later version; incorporated herein by reference. 11 * 12 * ----------------------------------------------------------------------- */ 13 14 /* 15 * rllpack.inc 16 * 17 * Very simple RLL compressor/decompressor, used to pack binary structures 18 * together. 19 * 20 * Format of leading byte 21 * 1-128 = x verbatim bytes follow 22 * 129-223 = (x-126) times subsequent byte 23 * 224-255 = (x-224)*256+(next byte) times the following byte 24 * 0 = end of data 25 * 26 * These structures are stored *in reverse order* in high memory. 27 * High memory pointers point to one byte beyond the end. 28 */ 29 30 #include <com32.h> 31 #include <stddef.h> 32 #include <string.h> 33 rllpack(com32sys_t * regs)34void rllpack(com32sys_t * regs) 35 { 36 uint8_t *i = (uint8_t *) (regs->esi.l); 37 uint8_t *o = (uint8_t *) (regs->edi.l); 38 size_t cnt = regs->ecx.l; 39 size_t run, vrun, tcnt; 40 uint8_t *hdr = NULL; 41 uint8_t c; 42 43 vrun = (size_t)-1; 44 while (cnt) { 45 c = *i; 46 47 run = 1; 48 tcnt = (cnt > 8191) ? 8191 : cnt; 49 while (run < tcnt && i[run] == c) 50 run++; 51 52 if (run < 3) { 53 if (vrun >= 128) { 54 hdr = --o; 55 vrun = 0; 56 } 57 *--o = c; 58 *hdr = ++vrun; 59 i++; 60 cnt--; 61 } else { 62 if (run < 224 - 126) { 63 *--o = run + 126; 64 } else { 65 o -= 2; 66 *(uint16_t *) o = run + (224 << 8); 67 } 68 *--o = c; 69 vrun = (size_t)-1; 70 i += run; 71 cnt -= run; 72 } 73 } 74 *--o = 0; 75 76 regs->esi.l = (size_t)i; 77 regs->edi.l = (size_t)o; 78 } 79 rllunpack(com32sys_t * regs)80void rllunpack(com32sys_t * regs) 81 { 82 uint8_t *i = (uint8_t *) regs->esi.l; 83 uint8_t *o = (uint8_t *) regs->edi.l; 84 uint8_t c; 85 size_t n; 86 87 while ((c = *--i)) { 88 if (c <= 128) { 89 while (c--) 90 *o++ = *--i; 91 } else { 92 if (c < 224) 93 n = c - 126; 94 else 95 n = ((c - 224) << 8) + *--i; 96 c = *--i; 97 while (n--) 98 *o++ = c; 99 } 100 } 101 102 regs->esi.l = (size_t)i; 103 regs->ecx.l = (size_t)o - regs->edi.l; 104 regs->edi.l = (size_t)o; 105 } 106