; bits.ash -- bit access for decompression ; ; This file is part of the UCL data compression library. ; ; Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer ; All Rights Reserved. ; ; The UCL library is free software; you can redistribute it and/or ; modify it under the terms of the GNU General Public License as ; published by the Free Software Foundation; either version 2 of ; the License, or (at your option) any later version. ; ; The UCL library is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with the UCL library; see the file COPYING. ; If not, write to the Free Software Foundation, Inc., ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ; ; Markus F.X.J. Oberhumer ; ; http://www.oberhumer.com/opensource/ucl/ ; ; ------------- ADDBITS ------------- macro(ADDBITS) #if (NRV_BB == 8) add.b d0,d0 ; sets Z, C and X ; 4 #elif (NRV_BB == 32) add.l d0,d0 ; sets Z, C and X ; 6 #endif endm #if 0 macro(ADDXBITS) #if (NRV_BB == 8) addx.b d0,d0 ; sets C and X ; 4 #elif (NRV_BB == 32) addx.l d0,d0 ; sets C and X ; 8 #endif endm #endif ; ------------- FILLBYTES_xx ------------- ; get 1 byte; then get 1 bit into both C and X macro(FILLBYTES_8) ; note: we shift the X flag through -> must init d0.b with $80 move.b (a0)+,d0 ; 8 addx.b d0,d0 ; sets C and X ; 4 endm ; get 32 bits in little endian format; then get 1 bit into both C and X macro(FILLBYTES_LE32) #if 0 move.b (a0)+,d0 ; 8 ror.l #8,d0 ; 24 move.b (a0)+,d0 ; 8 ror.l #8,d0 ; 24 move.b (a0)+,d0 ; 8 ror.l #8,d0 ; 24 move.b (a0)+,d0 ; 8 ror.l #8,d0 ; 24 add.l d0,d0 ; sets C and X ; 6 bset #0,d0 ; only changes Z ; 12 ; ----- ; 146 #elif 1 move.b 3(a0),d0 ; 12 lsl.w #8,d0 ; 22 move.b 2(a0),d0 ; 12 swap d0 ; 4 move.b 1(a0),d0 ; 12 lsl.w #8,d0 ; 22 move.b (a0),d0 ; 8 addq.l #4,a0 ; does not affect flags ; 8 add.l d0,d0 ; sets C and X ; 6 bset #0,d0 ; only changes Z ; 12 ; ----- ; 118 #else ; IMPORTANT: movep is not implemented on the 68060 # error "do not use movep" ; note: we shift the X flag through -> must init d0.l with $80000000 ; note: must use dc.l because of a bug in the pasm assembler ; note: may access past the end of the input; this is ok for UPX dc.l $01080003 ; movep.w 3(a0),d0 ; 16 move.b 2(a0),d0 ; 12 swap d0 ; 4 dc.l $01080001 ; movep.w 1(a0),d0 ; 16 move.b (a0),d0 ; 8 addq.l #4,a0 ; does not affect flags ; 8 addx.l d0,d0 ; sets C and X ; 8 ; ----- ; 72 #endif endm ; ------------- FILLBITS ------------- macro(FILLBITS) #if (NRV_BB == 8) ; no need for a subroutine FILLBYTES_8 #elif (NRV_BB == 32) # ifdef SMALL # define FILLBYTES_SR FILLBYTES_LE32 bsr fillbytes_sr ; 18 # else FILLBYTES_LE32 # endif #endif endm ; ------------- GETBIT ------------- ; get one bit into both the Carry and eXtended flag macro(GETBIT) #if defined(__A68K__) ADDBITS ; 4 / 6 bne \@ ; 10 (if jump) FILLBITS \@: #elif defined(__ASL__) ADDBITS ; 4 / 6 bne done ; 10 (if jump) FILLBITS done: #else LOCAL done ADDBITS ; 4 / 6 bne done ; 10 (if jump) FILLBITS done: #endif endm ; vi:ts=8:et