; ; LZ4 decompression algorithm - Copyright (c) 2011-2015, Yann Collet ; All rights reserved. ;Redistribution and use in source and binary forms, with or without ;modification, are permitted provided that the following conditions are met: ;1. Redistributions of source code must retain the above copyright notice, ; this list of conditions and the following disclaimer. ;2. Redistributions in binary form must reproduce the above copyright notice, ; this list of conditions and the following disclaimer in the documentation ; and/or other materials provided with the distribution. ; ;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ;ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ;DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ;ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ;(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ;ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ;(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ;SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.; ; ;The views and conclusions contained in the software and documentation are those ;of the authors and should not be interpreted as representing official policies, ;either expressed or implied, of the FreeBSD Project. ; ;====================================================================================== ; LZ4DMV by ipheion78 ; https://twitter.com/ipheion78 ; ; LZ4 RAM(ROM) ---> VRAM 展開for MSX2 ; ; HL:LZ4圧縮データのあるRAMの先頭アドレス ; DE:展開するVRAMの先頭アドレス、下位0-15ビット ; キャリーフラグ:展開するVRAMの先頭アドレス、上位16ビット。1なら10000番台。 ; 使用レジスタ:AF,BC,DE,HL,裏レジスタAF,BC,DE ; 割り込み:禁止されて戻ってくる。 ; 自己書き換えしてないので、ROMに置いてコールしても使えるぞ。 ; ; このソースコードは、マクロアセンブラzma用のため、ほかアセンブラで使用する場合は修正が必要です。 ; http://hraroom.s602.xrea.com/msx/index.html ; ; ※LZファイルはV1.4で圧縮されたものを展開。 ; ※0〜10000番台をまたぐ展開には、対応していない。 ; ※VDPI/Oポートは、0x98,0x99を直接指定しているので、MSX2バージョンアップアダプタ非対応。 ; ;========================================================================================= VDP_PORT0 = 0x98 VDP_PORT1 = 0x99 LZ4DMV: DI EXX LD D,0 RL D ; キャリーフラグから SLA D ; 裏Dレジスタに展開先アドレス16ビット目をいれとく。 SLA D ; ビット2がA16。VRAM読み書き時に使用する。 EXX CALL GET_LZ4_SIZE _LOOP: LD A,[HL] INC HL EXX LD E,A ; 裏のEにリテラル EXX AND A,0xF0 JR Z,_VRAM_to_VRAM ;長さ 0 なら既にVRAM へ転送済みのデータをコピー CALL Compare_0x0F _LDLP1: EX AF,AF' LD A,[HL] ;長さ情報の次から転送開始、これはRAM(ROM)にある EX AF,AF' EX DE,HL CALL Writing_into_VRAM EX DE,HL INC HL INC DE DEC BC LD A,B OR A,C JP NZ,_LDLP1 _VRAM_to_VRAM: LD A,L ;転送前に、展開完了チェックする EXX SUB A,C EXX LD A,H EXX SBC A,B EXX RET NC ;終了する。 LD C,[HL] INC HL LD B,[HL] ;BCにオフセット値を読み込む INC HL EXX LD A,E ;LITTERAL、裏のEレジスタ EXX AND A,0x0F ADD A,0x04 PUSH HL LD H,D LD L,E SBC HL,BC ;HL=DE-BC 既にVRAMに展開したデータを転送元とする LD B,0 LD C,A CP A,0x0F+0x04 EX [SP],HL CALL Z,_GET_LENGTH EX [SP],HL Loading_from_V_to_V: LD A,H ;既に展開したデータ転送。VRAM間転送を行う AND A,0b1100_0000 RLCA RLCA EXX OR A,D ; 裏DにA16の情報。 EXX OUT [VDP_PORT1],A LD A,14+0x080 OUT [VDP_PORT1],A LD A,L OUT [VDP_PORT1],A LD A,H AND A,0b00111111 OUT [VDP_PORT1],A EX AF,AF' IN A,[VDP_PORT0] ; 裏Aに読み込んだデータ EX AF,AF' EX DE,HL CALL Writing_into_VRAM EX DE,HL INC HL INC DE DEC BC LD A,B OR A,C JP NZ,Loading_from_V_to_V POP HL JP _LOOP Writing_into_VRAM: LD A,H AND A,0b1100_0000 RLCA RLCA EXX OR A,D ; 裏DにA16の情報。 EXX OUT [VDP_PORT1],A ; A16,15,14の指定 LD A,14+0x080 OUT [VDP_PORT1],A LD A,L OUT [VDP_PORT1],A LD A,H AND A,0b00111111 OR A,0b01000000 OUT [VDP_PORT1],A EX AF,AF' OUT [VDP_PORT0],A ; 裏Aに書き込むデータ EX AF,AF' RET ; ; LZ4圧縮RAM--->RAMに展開 ; LZ4DMM: CALL GET_LZ4_SIZE LOOP_LZ4DMM: LD A,[HL] INC HL EXX LD E,A ; 裏のEにリテラル EXX AND A,0xF0 JR Z,_RAM_to_RAM ;長さ 0 なら既にVRAM へ転送済みのデータをコピー CALL Compare_0x0F LDIR _RAM_to_RAM: LD A,L ;転送前に、展開完了チェックする EXX SUB A,C EXX LD A,H EXX SBC A,B EXX RET NC ;終了する。 LD C,[HL] INC HL LD B,[HL] ;BCにオフセット値を読み込む INC HL EXX LD A,E ;LITTERAL、裏のEレジスタ EXX AND A,0x0F ADD A,0x04 PUSH HL LD H,D LD L,E SBC HL,BC ;HL=DE-BC 既に展開したデータを転送元とする LD B,0 LD C,A CP A,0x0F+0x04 EX [SP],HL CALL Z,_GET_LENGTH EX [SP],HL LDIR POP HL JP LOOP_LZ4DMM ; ; サブルーチン 1 ; GET_LZ4_SIZE: LD BC,7 ADD HL,BC LD C,[HL] INC HL LD B,[HL] ;ヘッダの+7に圧縮データのサイズ(65535まで) INC HL INC HL INC HL ;+11 から中身 LD A,L ADD A,C EXX LD C,A ; 裏レジスタBCに終端アドレス EXX LD A,H ADC A,B EXX LD B,A EXX RET ; ; サブルーチン 2 ; Compare_0x0F: RRCA RRCA RRCA RRCA LD B,0 LD C,A CP A,0x0F RET NZ ; CALL Z,_GET_LENGTH ;長さ 0x0F なら続けて追加の長さを取得する _GET_LENGTH: ;転送バイト BC=現在の転送量 LD A,[HL] INC HL CP A,0xFF ;0xFF は長さ情報が続くサインを兼ねる JR NZ,Adding_length INC B DEC BC JR _GET_LENGTH Adding_length: ADD A,C LD C,A ADC A,B SUB A,C LD B,A ;BC=転送バイト長 RET