.z80 aseg org 100h ;::::: program na komprimaci souboru typu .COM { a asi take na obrazky.. } ;::::::::::::::::::::::: princip algoritmu::::::::::::::::::::::::::::::: ;: 1) 0xxxyyyy yyyyyyyy : o Y zpet,X b na aktualni pozici ;: 2) 101xxxxx : X bajtu neskomprimovanych za sebou ;: 2a) 10000000 : E.O.D. : end of data ;: 3) 100xxxxx bbbbbbbb : X bajtu B za sebou ;: 4) 11uxxxxx xxxxxxyy yyyyyyyy : o Y zpet,presun podle bitmapy X ;* 1a) 110bbbbb bbbbbbbb bbbxxxxx : o B zpet,X b na aktualni pos ;: (*) : hard compression : u verze 3.20 ... u=1 ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: MZLITE: ;----------------- H L A V A ------------------- ld (MZLITE),sp ; je na sto,na zacatku di,pak ei,ale uz bude znicena ld sp,STACK call SECURIT call RDPARAM ; nacti parametry ; o.k. or a jp z,VYSVETLI call DOPARAMS jp KONEC ;::: KONZPR: db "MZlite nasilne prerusen na vyzvu uzivatel",0E5h PUVNULA: dw 0 NASKONEC: pop af ld hl,ZAM03 ld e,l ld d,h inc de ld bc,VOLNARAM-ZAM03 ld (hl)," " ldir ; zamest ld sp,100h ld hl,0FBDAh res 2,(hl) ZAM04: in a,(0D1h) inc a jr nz,ZAM04 ld hl,0 push hl ld hl,0F8E5h push hl ld hl,0F402h ld (hl),31h inc hl ld (hl),0 inc hl ld (hl),1 ld de,(PUVNULA) ld hl,(1) inc hl ld (hl),e inc hl ld (hl),d ld de,KONZPR reti ZAM03: BYLPOZ: db 0 MUSTBE: db "MZLITE-3.12-CNL" SROVNAT: db 0 ENDMES: db 10,10,13,36 ERR_DATA: db 0,0,"Tato volba nenÉ v t×to verzi implementovÁna$" db 0,1,"chybnÁ relokaÃnÉ adresa$" db 0,2,"tento soubor nelze expandovat$" db 0,3,"pÒi ÃtenÉ z disku$" db 0,4,"pÒi zÁpisu na disk$" db 0,5,"pÒi zavÉrÁnÉ souboru$" db 0,6,"pÒi otevÉrÁnÉ souboru$" db 0,7,"nenÉ pamÅt na zpracovÁnÉ tohoto souboru$" db 0,9,"vÙpadek datov×ho segmentu$" db 0,10,"zastavenÉ programu na ÚÁdost uÚivatele$" db 0,11,"pÒÉliÓ mÁlo pamÅti na zpracovÁnÉ souboru$" ERRE_DATA: ERRUNKN: db 10,13,"internÉ chyba$" ; unknown error PRGABORTED: db 10,13,"Program pÒeruÓen.",10,13,36 DEDETRI: db 10,10,13,"CHYBA - ",36 MBBMZF: db "UpozornÅnÉ : MZF soubor nemÁ standardnÉ signaturu. PokraÃovat ? [a/n] ",7,36 NEZKOM: db 13,"UpozornÅnÉ : komprese bude neefektivnÉ, MÁm pÒesto pokraÃovat ? [a/n] ",7,36 MINROZ: db 10,10,13,"MinimalnÉ rozdÉl : " MINRH: db " h",10,10,13,36 EXCOMP: db " Extra k" EXCO99: COMPR: db 13,13,13,13,13,13," Kompresuji " INDRV: db " :" INNAME: db " do " OUTDRV: db " :" OUTNAME: db " $" CISLA1: db "($" PERC: db " ",13,36 PAST: db "%) ",13,36 ; cislo ,past NORML: db " " CISLA2: db " faktor ($" STOPRO: db "100%)$" INAIR: db 1 UNCOMPR: db " Expanduji " UNCO87: LAST30: dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; poslednich 30 bajtu mi dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BITMSUM: dw 0 ; kolik sbali bitova mapa ;---------------------- ROZDIL: dw 0 OUTROZ: ; vypise rozdil podle ROZDIL: ld a,(ONLYDATA) or a ret z ; nejsem treba ld hl,(UNLSIZE) ld de,(NEWSIZE) or a sbc hl,de ld a,h cp 0F0h jr c,OUTR40 ld de,0 ex de,hl or a sbc hl,de OUTR40: ld de,36 add hl,de ; sichr ld de,MINRH ld bc,256*16 ex af,af' ld a,4 OUTR01: ex af,af' xor a OUTR02: or a sbc hl,bc jr c,OUTR03 inc a jr OUTR02 OUTR03: add hl,bc exx ld hl,TRTABA ld c,a ld b,0 add hl,bc ld a,(hl) exx ld (de),a inc de ex af,af' dec a jr z,OUTR04 srl b rr c srl b rr c srl b rr c srl b rr c ; x / 16 -> 256,16,1 jr OUTR01 OUTR04: ld de,MINROZ ld c,9 call 5 ret HEX2ASC: ; hexa cislo de do asci ^hl ld a,d call HEX2A2 ld a,e HEX2A2: push af rlca rlca rlca rlca and 00001111b call HEX2A1 pop af and 00001111b call HEX2A1 ret HEX2A1: ld c,a ld b,0 ld ix,TRTABA add ix,bc ld a,(ix+0) ld (hl),a inc hl ret ;; LITEIT: call RDUNLITED ; nacti nezlajtovany call LITE ; zlajtuj call WRLITED ; uloz zlajtovany ENDING: ret ;::::---------===================----------:::::::::::::::::::: SOURDRV: db 88 ; int DESTDRV: db 88 ; int ACTDRV: db 88 ; int RDNFCB: dw 0 ; int PARAMS: dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;:::: EXTRACT: ; vyuzije k depaku dekompresni rutinu,ktera je primo ve sbalenem ; souboru,a to do TOLITE ; data fromlite : start,tolite : volna pamet ld a,2 ld (ERR_FLAG),a ld hl,(FROMLITE) ld a,(ISMZF) or a jr z,EXTR12 ld de,110Ah-10F0h add hl,de ; napis v headeru ld de,MSTBMZF ld bc,11 jr EXTR11 EXTR12: inc hl inc hl ld de,MUSTBE ld bc,SROVNAT-MUSTBE EXTR11: call CMPSTR jp nz,ERR_END ; nemuze : extra,3.02,4.xx,... ld hl,(FROMLITE) ld de,DELI80-DELITE add hl,de ; adresa,kde je delka uncomp ld hl,DELI80 ld (hl),0C9h ; return misto zacatku ldiru ld hl,(FROMLITE) ld a,(ISMZF) or a jr z,EXTR10 ld de,80h add hl,de ; preskoc header novy EXTR10: push hl ld de,(TOLITE) ; nevyjde : musim dopocitat zbytek a zpravu ven.. call EXTRCT ; vypis zpravu pop hl ld de,DELI98-DELITE add hl,de ; stat dat ld de,(TOLITE) Š call DELI99 ; rozbal hl do de ld hl,(TOLITE) ex de,hl or a sbc hl,de ld (UNLITED),hl ; to mame pro .com... ld a,(ISMZF) or a ret z ld hl,(TOLITE) ; start hlavicky ld de,1102h-10F0h add hl,de ld e,(hl) inc hl ld d,(hl) ld hl,80h add hl,de ld (UNLITED),hl ret ISMZF: db 0 FROMLITE: dw 0 ;:::::: WRUNLIT: push hl ld a,2 call CHDRV ; select destination drive ld hl,FPAR2 ld de,FCB2 ld bc,12 ldir ; spec do fcb ld de,FCB2 ld c,19 call 5 ; pro jistotu ho zrus ld de,FCB2 ld c,22 call 5 ; utvor ho cp -1 ; chyba ? jp z,VIF34 ; ANO pop bc ; delka rozbaleneho xor a rl c rl b rla ld c,b ld b,a ld a,(UNLITED) res 7,a or a jr z,WRUNL1 inc bc ; o sektor vice kvuli tem < 128 bajtum WRUNL1: ld de,(TOLITE) ; start sbaleneho i s dep. sektorem na zacatku call WRITE ; uloz to od de do ++bc*128 ret FPAR1: db 0," COM",0 ; prvni paramter FPAR2: db 0," COM",0 ; druhy parametr,usr + name[11]:12"bytu ; :::: WRLITED: ; :: ulozi skompresovany soubor na disk :: ld a,4 ld (ERR_FLAG),a ; eror writing file ld a,(ISMZF) or a jr z,WRLI66 ld de,1200h ; je to nejaky mzf.. ld hl,(UNLSIZE) ; setup konecnych ldiru v mzf.. ld bc,-128 ; bez hlavicky add hl,bc push hl ; cista size dat add hl,de ; konec nad 1200 dat ld (MOD02+1),hl pop hl push hl ld de,210h ; start dat dole add hl,de ; konec dat dole ld (MOD01+1),hl pop hl inc hl ld (MOD03+1),hl ld de,190h ld (MOD04+1),de ld (MOD05+1),de ld (XELI89+1),de ; 100-190 jsou systemove promenne od 1170 WRLI66: ld hl,(LITESIZE) ; delka sbaleneho,ktery zacina na freemem ld (DELIPS+1),hl ; uloz do prvniho sektoru ld (XELIPS+1),hl ; a pro extra ld de,256 add hl,de ; nevÉm proÃ,ale sichr... ld (NEWSIZE),hl ; a pro mzf ld de,0 ld a,(ONLYDATA) or a jr nz,WRLI68 ; bez hlavicek ld de,DELI98-DELITE ; delka rutiny normal ld a,(ISEXTRA) or a jr z,WRLI68 ; neni extra ld de,XELI98-XELITE ; ano,takze delka extra deco WRLI68: dec hl add hl,de xor a rl l rl h rla inc l dec l jr z,POST01 inc h POST01: ld l,h ld h,a ; v sektorech ld a,l or h jr nz,WRLI78 ; 0 : bylo to mensi,nez 1 sektor... WRLI76: inc hl ; o ten,ktery tam ma nejake tititi WRLI78: ld a,(ONLYDATA) or a jr nz,WRLI63 ld a,(ISMZF) or a jr z,WRLI63 inc hl ; MZF : takze bude jeste novy .MZF header WRLI63: push hl ; cela delka_128 ld a,(ISMZF) or a jr z,WRLI42 ld a,(ONLYDATA) or a jr nz,WRLI42 ld hl,(FRMBEGIN+1) ld de,1100h add hl,de ld (FRMBEGIN+1),hl ld hl,(XRMBEGIN+1) add hl,de ld (XRMBEGIN+1),hl ld hl,(DELI10+1) add hl,de ld (DELI10+1),hl ld hl,(XELI82+1) add hl,de ld (XELI82+1),hl ld a,0C9h ld (DELI80),a ld (XELI80),a ld a,(BYLPOZ) ; byl pozmenen adresa ? or a jr nz,WRLI42 ; ano... ld hl,0 ld a,21h ld (FRMDEL),a ld (FRMDEL+1),hl ld hl,0DFFFh-XELI98+XELITE ;**** spravne dffeh ld (XRMDEL+1),hl WRLI42: ld a,(ISEXTRA) or a push af call nz,CRYPTIT ; zakryptuj to,jestli je treba pop af jr z,WRLI45 ; extra neni exx ld de,DELI98-1 ; konec kam ld hl,XELI98-1 ; konec odkud ld bc,XELI98-XELITE ; kolik lddr inc de ld (EXTRST),de ; kde zacina extra sbaleny soubor.. exx ; header WRLI45: ld a,(ISMZF) or a jr z,WRLI43 ld de,(EXTRST) dec de ld hl,ENDHDR-1 ld bc,ENDHDR-NEWHDR lddr ; pod delite : hdr! inc de ld (EXTRST),de WRLI43: call ENDWO1 ; az ted vypis ratio (100%) pop hl push hl ld (PCIT),hl call NASDEL ld a,l cp 99 jr c,WRLI70 ld de,NEZKOM ld c,9 call 5 ld c,1 call 5 and 5Fh cp "A" jr z,WRLI70 cp "Y" jr z,WRLI70 ld a,10 ld (ERR_FLAG),a jp ERR_END WRLI70: ld a,2 call CHDRV ; select destination drive ld hl,FPAR2 ld de,FCB2 ld bc,12 ldir ld de,FCB2 ld c,19 call 5 ld de,FCB2 ld c,22 call 5 ; utvor ho cp -1 ; chyba ? jp z,VIF34 ; ANO ld a,(ONLYDATA) or a jr z,WRLI72 ld de,(TOLITE) ld (EXTRST),de WRLI72: ld de,(EXTRST) ; start sbaleneho i s dep. sektorem na zacatku WRLI64: pop bc push bc call WRITE ; uloz to od de do ++bc*128 pop hl call KONVYSL call OUTROZ ld de,ENDMES ld c,9 call 5 ret VIF34: jp ERR_END TOLITE: dw 0 LITESIZE: dw 0 UNLITED: dw 0 ERR_END: ld hl,ERR_DATA ld a,(ERR_FLAG) ld bc,ERRE_DATA-ERR_DATA ld e,a ERREN1: xor a cpir jr nz,ERRE2 ld a,e cp (hl) jr nz,ERREN1 ld e,l ld d,h jr ERRE3 ERRE2: ld de,ERRUNKN dec de ERRE3: inc de push de ld de,DEDETRI ld c,9 call 5 pop de ld c,9 call 5 ld de,PRGABORTED ld c,9 call 5 jp KONEC ; ::::: MSTBMZF: db "MZL-3.12-NC" EXTRST: dw DELITE ; zacatek skompresovaneho file WRITE: ;:::::::: zapise file :::::::::::: WRIT4: ld a,4 ld (ERR_FLAG),a push bc push de ld c,26 call 5 ; setdma ld de,FCB2 ld c,21 call 5 ; write pop de pop bc or a ; 0 - uspech jr nz,WIF34 ; neuspgch ld hl,80h add hl,de ex de,hl dec bc ld a,b or c jr nz,WRIT4 ld a,5 ld (ERR_FLAG),a ld de,FCB2 ld c,16 call 5 ; zavri ten soubor inc a jp z,ERR_END ret WIF34: jp ERR_END VYRBC: dw 0 FROMZBYV: dw 0 FROMZAC: dw 0 SECOND: db 0 ;::: CHDRV: ; zmeni drive na : actual {0} ,source {1} nebo destin {2} or a jr nz,CHDR02 ld a,(ACTDRV) jr CHDR04 CHDR02: dec a jr nz,CHDR03 ld a,(SOURDRV) ; 0:source jr CHDR04 CHDR03: ld a,(DESTDRV) ; 1:destin CHDR04: ld e,a ld c,14 call 5 ; vyberdsk ret LONG: db 0 ; aktualni shoda MAXLONG: db 0 ; maximalni shoda,clearuje head MAXSADR: dw 0 Š ; ::::: EXTRCT: ld hl,UNCOMPR ld de,COMPR+6 ld bc,UNCO87-UNCOMPR ldir ld de,COMPR ld c,9 call 5 ret ;::: KONVYSL: push hl ld hl,NORML ld de,PERC ld bc,5 ldir pop hl push hl push hl push hl jr PISPE9 PISPERC: ;::::::: vypise, kolik uz se udelalo :::: push hl push de push bc ld hl,(PKLIHL) ld de,(FROMLITE) or a sbc hl,de ; delka doposavad projeteho xor a rl l rl h rla ld l,h ld h,a ; hl / 128 PISPE9: ld (PCIT),hl call NASDEL ld a,l cp 101 jr c,PISPE4 ; ld a,100 PISPE4: ld hl,PERC call ATOASCI ld hl,PERC PISP1: ld a,(hl) cp " " jr z,PISP2 cp ")" jr z,PISP2 cp "%" jr z,PISP2 inc hl jr PISP1 PISP2: ex de,hl ld hl,PAST ld bc,4 ldir ld de,COMPR ld c,9 call 5 ld a,(INAIR) or a jr nz,PISPE8 ld de,CISLA2 jr PISPE5 PISPE8: ld de,CISLA1 PISPE5: ld c,9 call 5 ld de,PERC ld c,9 call 5 pop bc pop de pop hl ret NOWOFS: db 0 ; kterou polozku prave zpracovavam VYRHL: dw 0 VYRDE: dw 0 FREEMEM: dw VOLNARAM ;::: ENDWO1: xor a ld (INAIR),a ld hl,STOPRO ld de,PERC ld bc,5 ldir ld de,COMPR ld c,9 call 5 ld de,CISLA1 ld c,9 call 5 ld de,PERC ld c,9 jp 5 ;::::::::::::::: PCIT: dw 0 ; aktualni delka DCIT: dw 100 PDEL: dw 0 ; maximalni delka ; ::::::::: NASDEL: ; pcit*dcit/pdel : pro c2gray : x*0.53 = x*53/100 ld hl,0 ld de,(PCIT) ld bc,(DCIT) ld a,d or e jr z,NASD01 NASD04: srl b rr c jr nc,NASD03 add hl,de jr c,NASD02 NASD03: ld a,b or c jr z,NASD02 rlc e rl d jr c,NASD01 jr NASD04 NASD02: ; v hl vysledek nasobeni ld de,(PDEL) ld bc,0 NASD10: or a sbc hl,de inc bc jr nc,NASD10 ; podelit odcitavanim dec bc ld l,c ld h,b NASD01: ret ; hl = 0 ;:::::: vstup : a,^hl , nici vse krome ix,iy ATOBCD: ld hl,0 ld de,1 ld b,8 ATOB01: rrca jr c,ATOB02 ATOB03: ex af,af' ld a,e add a,e daa ld e,a ld a,d adc a,d daa ld d,a ex af,af' djnz ATOB01 ret ATOB02: ex af,af' ld a,l add a,e daa ld l,a ld a,h adc a,d daa ld h,a ex af,af' jr ATOB03 ATOASCI: ld (NUMERO),hl ld (hl),"0" or a ret z ; je to nula call ATOBCD ld b,0 ld a,h ld c,l or a ; >= 100 ? ld hl,(NUMERO) jr z,ATOA01 ; ne call ATOA10 ; ano,a=1 nebo 2 ld (hl),e ld b,1 inc hl ATOA01: ld a,c call ATOA10 ld a,d cp "0" jr nz,ATOA02 dec b inc b jr z,ATOA03 ATOA02: ld (hl),d inc hl ATOA03: ld (hl),e ret NUMERO: dw 0 ;: ATOA10: push af rrca rrca rrca rrca and 0Fh add a,"0" ld d,a pop af and 0Fh add a,"0" ld e,a ret ASCNUM: db " 0" ;-------- ;::: WRINOUT: ld de,COMPR ld c,9 call 5 ret ŠPOZPREP: ld bc,8 push hl POZPR1: ld a,(hl) cp " " ; jdu na ext jr z,POZPR2 ldi jp po,POZPR2 jr POZPR1 POZPR2: pop hl ld bc,8 add hl,bc ; najezd na .. ld a,"." ld (de),a inc de ld bc,3 ldir ret ;:::: UNLSIZE: dw 0 COUNT: db 0 ACT_BYTE: dw 0 BITC_BYTE: dw 0 PKLIHL: dw 0 PKLIBC: dw 0 PKLIDE: dw 0 POCOPAK: db 0 DELTA: dw 0 FCB1: db 0," ",0 dw 0,0,0,0,0,0,0,0,0,0,0,0,0 FCB2: db 0," ",0 dw 0,0,0,0,0,0,0,0,0,0,0,0,0 OKNADD: db 0 ACTADD: db 0 WPERCENT: db 8 ;--------------- V L A S T N I B A L I C I R U T I N A -------------- FIRSTO: dw 0 BYTEOPAK: db 0 BITMAP: dw 0,0,0 ; 24 bitova bitmapa BACKOPAK: db 0 BACKADR: dw 0 BITMOPAK: db 0 BITMADR: dw 0 ;:::: WILLBECOMP: ; :: zjisti,zda je mozno neco skompresovat,kdyz ano, ;::::: vrati v a - 0: zadna komprese, 1: opakujici se, 2: 8.8, 3: 9.16 ld (PKLIHL),hl ld (PKLIDE),de ld (PKLIBC),bc ld a,(hl) ld (BYTEOPAK),a call POSOOP ; zjisti po sobe se opakujici call ZAROVN ; zarovnej pro pripad konce dat ld (POCOPAK),a cp 10 jp nc,WILLIL ; uz ted neni co resit.. call BEDELTA ; zpet : 10 bitu mapa call ZAROVN ld (BITMOPAK),a ld (BITMADR),hl call BACKSTR ; zpet,souvisly retezec; call ZAROVN ld (BACKOPAK),a ld (BACKADR),hl ld a,(POCOPAK) ld hl,OPTAOPAK ld e,a ld d,0 add hl,de ld a,(hl) ; opak ld c,a ld a,(BITMOPAK) ld e,a ld hl,OPTABITM add hl,de ld a,(hl) ; bitmap cp c ; bitmap - opak jr nc,WILL01 ; opak je lepsi,nez bitmap ld c,a ; bitmap lepsi,nez opk ld hl,OPTABACK ld a,(BACKOPAK) ld e,a add hl,de ld a,(hl) ; bstr cp c ; bstr - bitmap jr z,WILL04 ; bstr = : nejlepsi jr nc,WILL02 ; bitmap nejlepsi WILL04: ld hl,(PKLIHL) ld de,(BACKADR) or a sbc hl,de ; offset ld de,-3 add hl,de ld (OFFSET),hl ; nastav offset ld a,1 ; flag 1 : "zpet , souvisly retezec" WILL99: or a ld de,(PKLIDE) ld hl,(PKLIHL) ld bc,(PKLIBC) ret WILL19: xor a jr WILL99 WILL01: ld hl,OPTABACK ld a,(BACKOPAK) ld e,a add hl,de ld a,(hl) ; zpet, retezec souvisly cp c ; bstr - opak = .. jr z,WILL03 ; opak = : nejlepsi jr nc,WILL03 ; opak je nejlepsi jr WILL04 ; bstr je nejlepsi WILL03: ; zab je nejlepsi ld a,c ; to se take mohlo stat takto : 99,99,99 .. cp 99 ; nulova komprese i u nejvyssiho ? jr z,WILL19 ; ano : ret s zero = no compression WILLIL: ld a,2 ; flag "posobe se opakujici" jr WILL99 WILL02: call MAKEBITM ld a,3 jr WILL99 ;::: ZAROVN: ;:: zarovna pocet kompresovanych bajtu tak,aby se skompresoval ;::: presne cely file,ani o bajt vice.. push af ld bc,(PKLIBC) ld a,b or a jr nz,ZARO01 ld a,c pop bc cp b ; zbyva - compr : ret c ; compr vetsi : pustit dale jen zbyva ! ld a,b ; mensi nebo rovno : muze byt compr ret ZARO01: pop af ret ;::: MAKEBITM: ; udela a ulozi bitovou mapu podle vstupu ld hl,BITMAP ld (MYBITM),hl xor a ld (hl),a inc hl ld (hl),a ld hl,(PKLIHL) ; aktualni pozice or a ld de,(BITMADR) ; misto,kde doslo ke shode sbc hl,de ; offset : ld (MAXBITM),hl ; = maximalni delka pro sum bitove mapy ld de,-4 add hl,de ; odectu ty 4 neefektivni ld (OFFSET),hl ; mam korektni delta offset..,8 nebo 9 bitovy ld de,(PKLIHL) ; odtud zacinam se zdrojem inc de ; prvni preskocim,ty mi obstara primo offset ld c,8 ; pro zaplneni bajtu ld hl,(MAXBITM) ; max. delka bitmapy : pro start na > -13 : dec hl ; minus ten prvni.. ld a,h or a jr nz,MKBM43 ld a,l cp 12 jr nc,MKBM43 ld b,a ; mensi,nez 11 : respektuj ! jr MKBM44 MKBM43: ld b,12 ; plus 12 bitmapa,13.je ^,hned ldi MKBM44: ld hl,(BITMADR) ; odtud zacinam s predkem inc hl exx ld e,0 ld d,8 exx MKBM15: ld a,(de) cp (hl) ; shoda ? jr nz,MKBM10 ; ne scf inc de ; dalsi ze zdroje - z aktualu jr MKBM11 MKBM10: xor a MKBM11: exx rl e dec d exx inc hl ; dalsi z predku dec c jr z,MKBM12 ; plny counter MKBM16: djnz MKBM15 ; plny pocet bitu, pozadovanych do bitmapy exx ld a,e push de exx pop bc MKBM17: ; b nemuze byt nikdy 0, max. 4 rlca djnz MKBM17 ld hl,(MYBITM) ld (hl),a inc hl ld (MYBITM),hl ret MAXBITM: dw 0 MKBM12: ; nemusim se starat : je to uz rotle ld c,8 exx ld a,e ld e,0 ld d,8 exx push hl ld hl,(MYBITM) ld (hl),a inc hl ld (MYBITM),hl pop hl jr MKBM16 MYBITM: dw 0 ; ::: optimalizacni tabulka :::: ;::: 9,16 ma slusne vysledky az pri 6 shodach;8,8 az pri 4{3:0.75} ;::::::::::: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 OPTABITM: db 99,99,99,99,75,60,49,43,38,33,30,27,25,23,21,19,18,17 OPTABACK: db 99,99,99,66,50,40,33,28,25,22,20 OPTAOPAK: db 99,99,99,65,49,39,32,27,24,21,19 MOZNO: db 0 ; uz je mozno kompresovat ? ;;;;: BACKSTR: ;::: zpetne retezce ld a,(MOZNO) or a ret z ld hl,(PKLIHL) ; priprava na zpetne ld a,2 ; o 2 nestojim ld (BAXLONG),a OCHRAM: ld bc,0 add hl,bc ld (BROMZAC),hl ;startovni pozice prohledavani v predku OCHRAP: ld bc,-2 ; musim zachovat deltu ld (BROMZBYV),bc XUMS06: ld hl,(BROMZAC) ; pred : kam az jsem to prohledal ld bc,(BROMZBYV) ld de,(PKLIHL) ; 0,zdroj ; dobehnout a zacit compare ld a,(de) ; pro porovnani : zdroj inc de cpir ; hledam ve zpetnem jp po,XUMS02 ; vubec se zde nenaleza,ani jednou,rovnou pryc ld (BROMZBYV),bc ; odkud zacit znova + kolik zbyva prohledat ld (BROMZAC),hl ; adresa ZA touto shodou,aut. inc hl ld a,b or a Š jr nz,XEDE44 ; x >= n-(min-1) -> n-(min-1) ld a,c ; x = n-min -> x += min-1 cp 7 ; > 10 ? ; else x +=min jr nc,XEDE44 ; ano,omez na 9 zbyvajicich add a,2 ld b,a ; potrebuji -2++ jr XEDE43 XEDE42: inc a jr XEDE43 XEDE44: ld b,9 XEDE43: ld c,1 ; init : jeden uz jsem prvnim cpir nasel XEDE10: ; ::::::::::::: hledam dalsi shody :::::::::::::: ld a,(de) ; beru dalsi bajt pro compare inc de ; { pro pred se udela aut. pri cpir } cp (hl) jp nz,XUMS03 ; uz zadna dalsi shoda neni inc hl inc c djnz XEDE10 XUMS03: ld a,c ld hl,BAXLONG ; nejlepsi : (hl) cp (hl) ; je ma shoda > maximalni ? jr c,XUMS06 ; mensi,pokracuj jr z,XUMS06 ; stejna,pokracuj ld (BAXLONG),a ld hl,(BROMZAC) dec hl ; kvuli cpir ld (BAXSADR),hl ; adresa max shody cp 10 ; mensi nez 10 = max? jr c,XUMS06 ; ano XUMS02: ; ne : nemusim se proted otravovat ld a,(BAXLONG) ; pocet cp 11 ; > 10 ? jr c,XUMS23 ; ne,o.k. ld a,10 ; ano,hezke,ale tolik nemohu zaznamenat.. XUMS23: ld hl,(BAXSADR) ; offset ret BAXSADR: dw 0 BAXLONG: db 0 BONG: db 0 BROMZAC: dw 0 BROMZBYV: dw 0 ;::::: POSOOP: ; :: vrati v a pocet stejnych bytu vuci bytu x ::: ld a,(hl) ; bajt pro shodu ld b,32 ; max. pocet dalsich,ktery mohu registrovat POSO01: inc hl cp (hl) jr nz,POSO02 ; uz neni shoda djnz POSO01 ; aspon jednou = 1 : o.k.,vrati presne tolik, POSO02: ; kolik jich tam je ld a,33 ; vcetne toho prvniho sub b ; b=0 : bylo 16 po nem + on = 17 po sobe jdoucich ret ;::::::::: rutina,zjistujici pocet shod podle vstupu ::: 9.16 nebo 8.8 :: BEDELTA: ; ::: KOLIK je za hl-de shod s hl ? ::: ld a,(MOZNO) or a ret z ld hl,(PKLIHL) ; priprava na zpetne xor a ld (MAXLONG),a OCHRIM: ld bc,0 add hl,bc ld (FROMZAC),hl ;startovni pozice prohledavani v predku OCHRIP: ld bc,-3 ; 10 bit offset,12 bit mapa ld (FROMZBYV),bc SUMS06: ld hl,(FROMZAC) ; pred : kam az jsem to prohledal ld bc,(FROMZBYV) ld de,(PKLIHL) ; 0,zdroj ; dobehnout a zacit compare ld a,b or c jr z,SUMS02 ; uz by to podteklo,minule to bylo tesne na -3 ld a,(de) ; pro porovnani : zdroj inc de cpir ; hledam ve zpetnem jr z,SUMGF8 ; muze se stat,ze po & z !,to je ale dobre ! jp po,SUMS02 ; vubec se zde nenaleza,ani jednou,rovnou pryc SUMGF8: ld (FROMZBYV),bc ; odkud zacit znova + kolik zbyva prohledat ld (FROMZAC),hl ; adresa ZA touto shodou,aut. inc hl xor a ld (LONG),a ; pocet dalsich : setup = 0 ld a,b or a jr nz,BEDE13 ld a,c BEDE96: ; je to na c:,tesne na konci ?,zbyva mene,nez 10 ? cp 9 ; pokud bych zajel do sebe : omezit ! jr nc,BEDE13 ; ne,o.k., takze normal : 12 dalsich{+3 do konce} add a,3 BEDE11: ld c,a ; jeste 3 navic vybudou... jr BEDE10 BEDE12: add a,1 jr BEDE11 BEDE13: ld bc,12 ; zbyva jeste 11 z 12,jeden uz jsem nasel BEDE10: ; ::::::::::::: hledam dalsi shody :::::::::::::: ld a,(de) ; beru dalsi bajt pro compare inc de ; { pro pred se udela aut. pri cpir } cpir ; dalsi ? jp po,SUMS03 ; uz zadna dalsi shoda neni ld a,(LONG) inc a ld (LONG),a ; dalsi shoda, o.k. jr BEDE10 SUMS03: jr nz,SUMS10 ; konec a shoda nebyla ld a,(LONG) ; a byla,takze jeste pripocist 1 inc a ld (LONG),a SUMS10: ld a,(MAXLONG) ld hl,LONG cp (hl) ; je ma shoda > maximalni ? jr nc,SUMS06 ; neni ld a,(LONG) ld (MAXLONG),a ld hl,(FROMZAC) dec hl ; kvuli cpir ld (MAXSADR),hl ; adresa max shody cp 12 ; max. shoda ? jr c,SUMS06 ; ne : hledam dale SUMS02: ld a,(MAXLONG) inc a ; musim pripocist tu prvni shodu.. ld hl,(MAXSADR) ret ;:::: NOCOMP: db 0 ; nyni zadny vhodny ke kompresi,cili hledam.. POSDB: db 0 ; bajt pro popocet POSHOD: db 0 BITMAPA: dw 0 ; bitova mapa shod ; 8/16 bitu UNPOCET: db 0 ; pocet po sobe jdoucich uncomp POPOCET: db 0 ; pocet po sobe jdoucich stejnych PKLFROM: dw 0 ACTBYTE: dw 0 ; aktualni output byte BITCBYTE: dw 0 ; aktualni output_bit_seq byte OFFSET: dw 0 ; offset shody ; 8/9 bitovy ;--------------------------------------------------------------------- ; :::: PKLI99: ;:: osetreni konce komprese,aby presne konec na unlsize-dulezite ld a,(NOCOMP) ; pro extra !! or a ; nepadam prave pri nacitani uncomp? jr z,PKLI98 ; ne call PKLI40 ; ano,zarovnej to PKLI98: ld a,10000000b call PUTBITS ; uloz ukoncovaci sekvenci - bajt ld de,(ACTBYTE) ret NOWB: db 0 ;:::------====================================================-----::::: PKLI01: ; ----:::::::-- hlavni balici cyklus --::::::::----::: ld a,b or c jr z,PKLI99 ; konec dat : sekvence 1000000b call WILLBECOMP ; bude komprese ? otravovat...,no co.. jr nz,PKLI02 ; ano : skompresuj PKLI07: ld a,1 call OCHRANA ; dalsi 1 uncomp,jakykoli ld a,(NOCOMP) or a ; poprve uncomp ? jr z,PKLI03 ; ano ld a,(UNPOCET) ; ne,zvys pocet o 1 inc a ; o jeden neskompresovany v rade vice ld (UNPOCET),a ex af,af' dec bc ld a,b or c jr z,PKLI99 ; prave na konci dat.. ex af,af' cp 32 ; maximum ? { pro 5 bitu } call z,PKLI41 ; ano,vice uz zaznamenat nemohu,zakoduj a dale PKLI32: inc hl ; zkus to s dalsim bajtem jr PKLI01 ;:::::::::::::---:::::::------ PKLI03: ; init pocitani nestejnych bytu ld a,1 ld (NOCOMP),a ; flag zacinaji uncomp byty ld a,1 ld (UNPOCET),a dec bc ld a,b or c jr z,PKLI99 ; poprve a hned konec... jr PKLI32 ;:::::::::::::::::::::::::: PKLI02: ; kompresuj ! ld (METODA),a ld a,(NOCOMP) ; osetreni minuleho stavu... or a ; prechod non -> comp ? jp z,PKLI05 ; ne,prechod comp,comp call PKLI40 ; ano,uncomp bajty uloz,a pak.. jp PKLI05 PKLI41: call PKLI40 dec hl ret PKLI40: ; obhospodari nezbalene bajty ld a,(UNPOCET) push af dec a ; 0 = 1 or 10100000b ; 101 : flag neskompresovane call PUTBITS pop af PKLI12: ld hl,(PKLFROM) ld de,(ACTBYTE) push bc ld c,a ld b,0 ldir ; presun uncomp byty ld (PKLFROM),hl ld (ACTBYTE),de pop bc xor a ld (NOCOMP),a ; asi bude,ale ja : jako ze nebyla.. ld (UNPOCET),a ; a take nic v bufferu ret ;:::::::::::::::::::::::::::: PKLI10: ; posun ukazatelu : volan pri kompresi ld hl,(PKLFROM) ld e,a ld d,0 add hl,de ; posun zdroj o ty zkompresovane byty ld (PKLFROM),hl ld h,b ld l,c or a sbc hl,de ; uber z poctu bajtu ld c,l ld b,h call OCHRANA ld hl,(PKLFROM) ld a,(NOWB) cp h jr nc,PKLI67 ; zatim neprekrocen limit Š ld a,h ld (NOWB),a call PISPERC ; napis procenta projeta : kazdych 256 bajtu outu PKLI67: jp PKLI01 ;:::::::::::::::::::::: PKLI05: ; ulozi [pocet] po sobe jdoucich stejnych bytu ld a,(METODA) cp 2 ; po sobe jdouci ? jr nz,PKLI06 ; ne ld a,(POCOPAK) push af sub 2 ; 1?3,15=17,0 = E.O.D. or 10000000b call PUTBITS ; pocet bajtu ld a,(BYTEOPAK) call PUTBITS ; byte pop af jp PKLI10 ; ...a znova ;:::::::::::::::::-----------/-----------------------::::::::: PKLI06: ; uloz offset a bitmapu podle a - 2 : 8.8 ; 3 : 9.16 cp 3 jr nz,PKLI30 ; ne ld a,(BITMAP) ; ano and 11111100b rrca rrca or 11000000b ; flag + prvnich 6 call PUTBITS ld a,(BITMAP) ; poslednich 6 : and 00000011b ; rrca rrca ; 11000000 ; 2 ld e,a ld a,(BITMAP+1) and 11110000b ; + 4 rrca rrca ; 00111100 or e ; 11111100 ld e,a ld a,(OFFSET+1) ; vyssi 2 z offsetu and 00000011b or e call PUTBITS ld a,(OFFSET) ; nizsich 8 call PUTBITS ; nizsich 8 z 12b. offsetu ld a,(BITMOPAK) ; kolik se usetrilo jp PKLI10 ;::::::::::::::::::::: PKLI30: ; uloz zpetny retezec ld a,(BACKOPAK) push af sub 3 ; 0 = 3 , 7 = 10 rlca rlca rlca rlca ; na vyssi pozici ld e,a ld a,(OFFSET+1) and 00001111b or e call PUTBITS ld a,(OFFSET) call PUTBITS pop af jp PKLI10 ;:::: PUTBITS: ; ulozi flag bajty na vystup bajtovy.. exx ld hl,(ACTBYTE) ld (hl),a inc hl ld (ACTBYTE),hl exx ret ; ::::: OCHRANA: ; ::: chrani sama sebe pred prepsanim ::: + cita min_rozdil.. ex af,af' ; mozno.. ld a,(FOCHRANA) or a ret z ; ochrana uz neni treba ld a,(MOZNO) or a jr nz,OCHR33 ; uz se kompresuje ld a,(OCHRIP+2) ; bedelta : aspon 4 or a jr nz,OCHR33 ; jdu tam zespoda od fffd!! ld a,(OCHRIP+1) cp 4 jr c,OCHR33 ld (MOZNO),a ; uz se muze spustit komprese..zadne vymazy ! OCHR33: push bc push hl push de ld hl,(OCHRIP+1) ld de,1024 ; vzdy 1024,to nema pri vetsim uspech or a sbc hl,de jr z,OCHR20 ; tuto cast uz nekontroluji ex af,af' ld e,a ex af,af' ld d,0 ld hl,(OCHRIM+1) or a sbc hl,de ; zas o neco zpet budu sahat ld (OCHRIM+1),hl ld hl,(OCHRAM+1) or a sbc hl,de ; minus snizit ld (OCHRAM+1),hl ld hl,(OCHRAP+1) add hl,de ; plus zvysit ld (OCHRAP+1),hl ld hl,(OCHRIP+1) add hl,de ld (OCHRIP+1),hl ld a,(MOZNO) or a jr z,OCHR99 ; byly by chyby..pod 0 ld de,1024 sbc hl,de jr c,OCHR99 ; je mensi,jeste ne ld hl,1024 ; tato cast uz nepotrebuje,pretekla ld (OCHRIP+1),hl ; nebo je rovna ld hl,-1024-3 ; toto kvuli tomuhle ld (OCHRIM+1),hl jr OCHR99 OCHR20: ex af,af' ld e,a ld d,0 ex af,af' ld hl,(OCHRAM+1) or a sbc hl,de ; minus snizit ld (OCHRAM+1),hl ld hl,(OCHRAP+1) add hl,de ; plus zvysit ld (OCHRAP+1),hl ld de,4096 or a sbc hl,de jr c,OCHR99 ; jeste ne xor a ld (FOCHRANA),a ; uz ano : zablokuj ochranu ld hl,4096 ld (OCHRAP+1),hl ld hl,-4096-2 ld (OCHRAM+1),hl ; tak uz to bude naporad OCHR99: pop de pop hl pop bc ret ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; ---------- NEWHDR: ; novy header bude prvni sektor filu,pak bude postaru : db 0,0,0,0,0,0,0,0 ; dekompresor_rutina[1200-12ff] + data db 0,0,0,0,0,0,0,0,0,0 ; tolite je na 1200h+4100 NEWSIZE: dw 0,1200h,1108h ; zbytek do 24 : delka,from,exec CMTH00: .phase 1108h STHDR: jr CMTHEAD CMTSTR: db "MZL-" MZFVERS: db "3.12-" MZFCF: db "NC" ; normal compression CMTHEAD: ; :::: toto na adrese 1108h ::: do 1170h :: 80h bajtu di out (0E0h),a out (0E1h),a ld sp,100h ld hl,MOD01-CMTH00+1108h ld de,0 push de ld bc,CMTH02-MOD01 ldir ; presun konce na [0] ld hl,1170h ld de,100h ld bc,91h ldir ; sys_promenne jp 1200h ; rozbal od dfff-size do 100h CMTH01: ; ::::: toto je ukoncovac : presuny na 10f0 a 1200,ldir to 1000,jp .dephase MOD01: ld hl,0 ; dole konec dat MOD02: ld de,0 ; nahore konec dat MOD03: ld bc,0 ; delka dat lddr ; presun data na 1200h ld hl,190h ld de,10F0h ld bc,128 ldir ; presun stare hlavicky ld hl,100h ld bc,90h ldir ; a promennych ld hl,NEWH03-MOD01 ld de,1000h ld bc,CMTH02-NEWH03+1 ; a exec ROMs ldir ;jinak bych ho nemohl.. jp 1000h NEWH03: ; :::: posledni instance : na 1000h a go ! :::: - zaxor koncem un dat ld sp,10F0h out (0E2h),a out (0E3h),a ld hl,1102h NEWH04: jp 0ECFCh ; dos_execute() CMTH02: ENDHDR: ;::::::::::::::: extra rutina deco ::::: XELITE: ; :: spolecna pro cp/m i mzf,u mzf pak relokuje volajici nula jr XRMDEL db "MZLITE-" XERSION: db "3.12-" XLVERS: db "C" ; verse 3.12-c XLCOMPM: db "E" ; extra komprese,Normal XLDOS: db "L" ; lec cp/m,sharp Mzf,sorD,Sinclair,Other XLENDS: db 1Ah XRMDEL: ld hl,0 ; natvrdo (6) nebo DFFF-delka deco pro mzf di out (0E3h),a ex de,hl push de ; uloz prvni adresu XRMBEGIN: ld hl,XELI10-XELITE+100h ; adresa deco1 od 100h ld bc,XELI98-XELI10+1 ; delka deco1 ldir ; presun deco1 pop hl ; start deco1 push hl ld bc,XELI98-XELI10+1 XRMB01: ; odxoruj deco jeho adresami ld a,(hl) xor h xor l ld (hl),a inc hl dec bc ld a,b or c jr nz,XRMB01 ret ; go deco1,co sem...? XELI10: ; ::::::::::: rozbalovaci rutina : :::::::::::::::::::::: dec sp dec sp pop hl XELI82: ld de,XELI98-XELITE+100h ; adresa start data XELIPS: ld bc,0 ; delka sbaleneho,doda wrlite() ex de,hl add hl,bc ; end data inc bc lddr ; presun data nahoru inc de ; start hora ex de,hl ; do hl MOD05: ld de,100h ; kam dec hl dec hl xor a ld (hl),a inc hl ld (hl),a inc hl ; prvni 2 predchudkine : nuly XELI96: ; :::::::: rozbalovaci smycka :::::::: z hl do de ppo E.O.D. :: xor a ; nejdrive chci xor byte xor h xor l ; xor zdrojem xor d xor e ; xor cilem+1 push hl exx ;1 pop hl push af dec hl dec hl ld a,(hl) ; vyssi and 00011111b ld b,a inc hl ld a,(hl) ld c,a ld hl,0E020h add hl,bc ; vypocet ROM adresy jr nc,XYP56 ; >0 ld de,-40h add hl,de ; vypocet ROM adresy,pozor na i/o brouky ! XYP56: ld e,(hl) pop af xor e ; posledni - nejdulezitejsi xor z ROM exx ;0 ld c,a ; xor byte pro uncomp ld a,(hl) xor c ld (hl),a ; pro uncomp byty bit 7,a jr z,XELI94 ; zpetny retezec : thanks to TSR inc. bit 6,a jr nz,XEBM00 ; bitmapa 10 bitu bit 5,a jr nz,XEUN00 ; uncompressed XEPO00: ; po sobe jdouci and 00011111b or a jr z,XELI99 ; flag E.O.D. je tady : konec !! inc a inc a ; 1"= 3 inc hl ex af,af' ; 1. ld a,(hl) Š inc hl ; priprav pro dalsi pouziti ex af,af' ; 0. XEPO01: ex af,af' ; 1. ld (de),a inc de ex af,af' ; 0. dec a jr nz,XEPO01 jr XELI96 XELI99: jr XELI88 XELI94: jr XEOB11 XELI95: jr XELI96 XEBM00: ; :::::::: bitova mapa :::::::: ;:::::::::::::::: 101mmmmm mmmmyyyy yyyyyyyy m : mapa l->r , y : offset inc hl ld a,(hl) and 00000011b ; offset : vyssi 2 z 10 push de exx pop de exx ld b,a inc hl ld a,(hl) ; offset : nizsich 8 ld c,a inc hl push hl exx pop hl exx dec hl dec hl dec hl push hl ld l,e ld h,d inc bc inc bc inc bc inc bc ; 0 = -4 or a sbc hl,bc ex de,hl pop hl ld a,(hl) and 00111111b ; prvnich 6 rlca rlca ld b,a ; 11111100 inc hl ld a,(hl) ; 78901200 rlca rlca ; 90120078 ld c,a ; v c posledni dva bity and 00000011b ; select 78 or b ; 00000078 or 12345600 = 12345678 ld b,a ex de,hl ; hl zespoda exx push de exx pop de ld a,8 ldi ; prvni se inc bc ; presune automaticky.. XEBM12: rlc b jr nc,XEBM13 ldi inc bc dec hl XEBM13: inc hl dec a jr nz,XEBM12 ld a,4 XEBM14: rlc c jr nc,XEBM15 ldi inc bc dec hl XEBM15: inc hl dec a jr nz,XEBM14 exx push hl exx pop hl ; nove hl XELI97: jr XELI95 XEOB11: jr XEOB00 XEUN00: ; :: nezkompresovane :: 1..32 inc hl and 00011111b inc a ; 0=1.. ld b,a XEUN01: ld a,(hl) xor c ; uncomp jsou xor vsechny kvuli utajeni ld (hl),a ld (de),a inc hl inc de djnz XEUN01 jr XELI97 XELI88: ;::: adresa xeli89 nahore ! ld hl,0 ; XELI89 nahore ld b,XELI87-XELI89 exx ld hl,0EDB0h exx XELI86: exx ld c,(hl) inc hl exx ld a,(hl) exx xor c exx xor h xor l ld (hl),a inc hl djnz XELI86 XELI89: ; ::: odxoruj to za sebou koncem rozbal. dat a pokracuj ... ld hl,100h ; a nakonec jeste odxorovat start .comu...hahaha ! ex de,hl ld bc,-64 add hl,bc ; 30 poslednich na konci ex de,hl ld b,64 ; kolik,de=cim XELI44: ld a,(de) ; presne na eod-30. bajtu uncomp. xor (hl) ld (hl),a inc hl inc de djnz XELI44 XELI80: ; ::: konec dekomprese : relokace,exec() : bude zaxorovan ld e,b ld d,b inc d push de ; de = 100h out (0E1h),a ; odmapuj hROM ei ; povol int ret ; = jp 100h XELI87: XEOB00: ; :: 0xxxyyyy yyyyyyyy ; x=pocet-3,y=-offset and 01110000b rrca rrca rrca rrca add a,3 ; 0=3 ex af,af' ; 0. = pocet ld a,(hl) inc hl and 00001111b ld b,a ; vyssi offset ld a,(hl) ld c,a ; nizsi offset inc hl push hl ; pro dalsi inc bc inc bc inc bc ; -3 : uspora ld l,e ld h,d or a sbc hl,bc ; - v cili ex af,af' ld b,0 ld c,a ; pocet : 3..10 ldir ; presun cil->cil pop hl jr XELI97 XELI98: ;:::::: VYSVETLI: ld de,VYSVTL ld c,9 call 5 jp KONEC CRYP30: ; konec,cele,start koncem ^^^^^^^^^^^^^^^^^^^ ld a,(XORBYTE) xor (hl) ld (hl),a ; zaxoruj flag 80h : E.O.D. ld hl,(XRMDEL+1) ; first nahore ld de,XELI89-XELI10 add hl,de ld (XELI88+1),hl push hl exx ;1 pop de exx ;0 ld b,XELI87-XELI89 ld hl,0EDB0h ld de,XELI89 CELI86: di out (0E3h),a ; horni ROM on ld c,(hl) out (0E1h),a ; zpet ei ld a,(de) exx ;1 xor d xor e inc de ; jako v RAM exx ;0 xor c ; EDB0++ ld (de),a inc de inc hl djnz CELI86 ; konec zaxorovan ld hl,XELI10 ld de,(XRMDEL+1) ; first akcni adresa nahore ld bc,XELI98-XELI10+1 ; delka akce CRMB01: ; zaxoruj cele deco jeho adresami ld a,(hl) xor d xor e ld (hl),a inc hl inc de dec bc ld a,b or c jr nz,CRMB01 ret SUMDECREG: ; setup registru jako pri deco ld hl,(XRMDEL+1) ; start decor nahore ld de,(XELIPS+1) ; delka baleneho or a sbc hl,de ; zdroj ld (EXZDROJ),hl ld hl,100h ld a,(ISMZF) or a jr z,SUMD1 ld hl,190h SUMD1: ld (EXCIL),hl ret COMPUXOR: xor a ; na startu musi byt matrice nulova.. push hl ld hl,(EXZDROJ) xor h xor l ; xor zdrojem ld hl,(EXCIL) xor h xor l ; xor cilem push af ld a,(PRED2) ; vyssi and 00011111b ld h,a ld a,(PRED2+1) ld l,a ld de,0E020h add hl,de ; 0=nc! proto dec hl... jr nc,CRYP56 ; >0 ld de,-40h add hl,de ; vypocet ROM adresy,pozor na i/o brouky ! CRYP56: di out (0E3h),a ; horni ROM on ld e,(hl) out (0E1h),a ; zpet ei pop af xor e ; posledni - nejdulezitejsi xor ld (XORBYTE),a pop hl ret SUMBITM: ld de,800h SUMB01: rlca jr nc,SUMB02 inc e SUMB02: dec d jr nz,SUMB01 ld a,e ret ERR_FLAG: db 0 ONLYDATA: db 0 ; pouze data... SECURIT: di ld hl,0F402h ld (hl),0C3h inc hl ld de,NASKONEC ld (hl),e inc hl ld (hl),d ld hl,(1) inc hl ld e,(hl) ld (hl),0 inc hl ld d,(hl) ld (hl),0 ; hahahaha... ld (PUVNULA),de ei ret DOPARAMS: ld a,0 ld (ERR_FLAG),a ld hl,(6) dec h dec h ld de,XELI98-XELITE+1 or a sbc hl,de ; memmax(); ld (XRMDEL+1),hl ; start : under bdos call INITVYP ; init pro vypocty procent xor a call GETFP ; je nejaky parametr ? jp z,LITEIT ; neni,takze primo lite CPM soubor ld a,"X" call GETFP ; extrakce ? jr nz,DOPA80 ; ne call RDUNLITED ; nacti zlajtovany call EXTRACT ; rozbal ho a vrat kam az v de ld e,10 ld c,2 call 5 ld hl,(UNLITED) ; delka,vytazena z dekompresoru call WRUNLIT ; uloz rozlajtovany : hl bajtu od TOLITE ret DOPA80: ; takze to je urcite komprese ... ld a,"P" call GETFP ; pod ccp ? jr nz,DOPAR1 ; ne DOPA03: ld hl,0D400h ld a,1 ld (BYLPOZ),a ld (BYLPAR),a ld a,21h ld (FRMDEL),a ld (FRMDEL+1),hl ld de,XELI98-XELITE+1 or a sbc hl,de ; memmax(); ld (XRMDEL+1),hl jr DOPA81 ; pokracujeme dale.. DOPAR1: ld a,"A" call GETFP ; relokace pod adresu xxxx ? jr nz,DOPA81 ; ne call ASC2HEX ; transform ascidohexa do hl ld (DOPA03+1),hl jr DOPA03 DOPA81: ld a,"O" call GETFP jr nz,DOPA43 ld a,1 ld (ONLYDATA),a ld (BYLPAR),a DOPA43: ld a,"R" call GETFP jr nz,DOPA76 ld a,1 ld (BYLPOZ),a call ASC2HEX ld de,NEWH03 ex de,hl xor a ld (hl),a inc hl ld (hl),a ld hl,NEWH04+1 ld (hl),e inc hl ld (hl),d DOPA76: ld a,"E" call GETFP jr nz,DOPAR2 ld (ISEXTRA),a ld (BYLPOZ),a ld (BYLPAR),a ld hl,EXCOMP ld de,COMPR+1 ld bc,EXCO99-EXCOMP ldir DOPAR2: ld a,(BYLPAR) or a jp nz,LITEIT ; nejaky param byl ld a,(BYLPOZ) ; nebyl nahodou nejaky divny parametr? or a jp z,ERR_END jp LITEIT ; nakonec se vse zalituje.. ret ;::::: KONEC: USRKONEC: ; ukoncovaci rutina : ninja rutina... di ld hl,0F402h ld (hl),31h inc hl ld (hl),0 inc hl ld (hl),1 ; zamet stopu v biosu ld de,(PUVNULA) ld hl,(1) inc hl ld (hl),e inc hl ld (hl),d ld hl,KON01 ld de,10h ld bc,KON02-KON01 ldir jp 10h KON01: ld hl,100h ld d,h ld e,l inc de ld bc,VOLNARAM-100h ld (hl)," " ldir ; smaz ld hl,10h ld e,l ld d,h inc de ld bc,0 ld (hl),0C7h ldir ; gogogo KON02: TRTABA: db "0123456789ABCDEF" COM: db "COM" NEWXSIZE: dw 0 METODA: db 0 FOCHRANA: db 1 ; nutno chranit registry ? na startu do 4096 b ano ! ISEXTRA: db 0 INASC2HEX equ 1 ACTADH: dw 0 MZF: db "MZF" db "Stack ................................." STACK: dw 0,0,0,0 ASC2HEX: ld a,INASC2HEX ld (ERR_FLAG),a ; jestli bude chyba,tak pri asc2hex ld d,h ld e,l inc de ld hl,0 ld bc,4096 ld (ACTADH),bc ld b,4 ASC2H1: push bc ld a,(de) inc de push hl ld hl,TRTABA ld bc,16 cpir jp nz,ERR_END dec hl Š push de ld de,TRTABA or a sbc hl,de ld b,l pop de pop hl push de ld de,(ACTADH) inc b jr ASC2H5 ASC2H4: add hl,de ASC2H5: djnz ASC2H4 pop de ASC2H3: ld bc,(ACTADH) srl b rr c ; /2 srl b rr c ; /4 srl b rr c ; /8 srl b rr c ; /16 ld (ACTADH),bc pop bc djnz ASC2H1 ret ;:::: GETFP: ld bc,(PARSIZE) ; delka nacteneho param. buferu ld hl,PARAMS ld (SROVNAT),a ld a,(hl) or a ret z ; : je tam nula = zadny parametr.. GETFP1: ld a,"-" cpir ; hledej ret nz ; dal uz jsem nic nenasel.. ld a,(SROVNAT) cp (hl) ; nuj parametr ? ret z ; ano ! jr GETFP1 ; ne : zkus dalsi LITE: ; :::::: zhusti (fromlite) do (tolite) , vrati (litesize) ld hl,FCB1+9 ld de,MZF ld bc,3 call CMPSTR jr nz,LITECOM ; neni to .MZF ld hl,(FROMLITE) ld a,1 cp (hl) jr z,POKR01 ld a,10 ld (ERR_FLAG),a ld de,MBBMZF ld c,9 call 5 ld c,1 call 5 and 5Fh cp "Y" jr z,POKR01 cp "A" jp nz,ERR_END ; ::::::::::: jedna se o .MZF file ::::::::::: POKR01: ld (ISMZF),a ; flag je to mzf pro wrlited Š ld hl,(FROMLITE) ld de,1102h-10f0h add hl,de ld e,(hl) inc hl ld d,(hl) ld hl,128 add hl,de ; + starou hlavicku. ld (UNLSIZE),hl ; tolik skompresovat ld hl,(FROMLITE) ld de,NEWHDR ld bc,18 ldir ; tohle musi zustat stejne LITECOM: call WRINOUT ; oznam "compressing :" ld a,(ISEXTRA) or a ld hl,(FROMLITE) jr z,LITEC1 push hl ld bc,(UNLSIZE) add hl,bc ld bc,-64 add hl,bc ld de,LAST30 ld bc,64 ldir ; presun pop de push de ld hl,LAST30 ld b,64 LITERO: ld a,(de) ; prvnich 30 na zacatku souboru je zaxorovano xor (hl) ; poslednimi 30 na konci souboru ! ld (de),a inc hl inc de djnz LITERO ; pro zmateni... pop hl LITEC1: ld de,(TOLITE) ld bc,(UNLSIZE) xor a ld (NOCOMP),a ld (ACTBYTE),de ld (PKLFROM),hl ld a,d ld (NOWB),a call PKLI01 ; zabalit.. ld hl,(TOLITE) ; a vrat zabalenou adresu posledni v de ex de,hl or a sbc hl,de ; delka zabaleneho inc hl ld (LITESIZE),hl ; ulozit. ret EXZDROJ: dw 0 EXCIL: dw 0 PRED2: dw 0 ; 2 bajty uncomp pred flag pro e000_rom XORBYTE: db 0 PARSIZE: dw 0 ; delka input dat - parametru ; -------------------------- P R O C E D U R Y -------------------------- CRYPTIT: ld a,"E" ld (MZFCF-STHDR+CMTH00),a call SUMDECREG ; vypocti hodnoty registru pri dekompresi exx ; 0 = normal,1 = prime ld hl,(TOLITE) dec hl dec hl xor a ld (hl),a inc hl ld (hl),a inc hl CRYP01: ld a,(hl) ; beru flag and 11100000b xor 10100000b ; je to uncomp ? jr z,CRYP10 ; ano : uncomp {se zaxoruji komplet},o.k. ld a,(hl) and 11000000b xor 11000000b jr nz,CRYP04 ; je to back nebo posobe call COMPUXOR ; je to bitmapa.. xor a ld (BITMSUM),a ; init ld a,(hl) and 00111111b ; prvnich sest call SUMBITM ld (BITMSUM),a inc hl ld a,(hl) ; 1.bitm+ofs ld (PRED2),a and 11111100b ; poslednich sest call SUMBITM ld e,a ld a,(BITMSUM) add a,e exx inc a ; ++ prvi pointrovy !! ld c,a ld b,0 exx inc hl ld a,(hl) ; 2.ofset ld (PRED2+1),a dec hl dec hl ld a,(XORBYTE) xor (hl) ld (hl),a inc hl inc hl inc hl ; pristi.. ld c,3 jr CRYP07 CRYP04: ; dve "dvojky" call COMPUXOR ld a,(hl) ld (PRED2),a inc hl ld a,(hl) ld (PRED2+1),a dec hl ld a,(hl) and 80h jr nz,CRYP71 ; po sobe 100X ld a,(hl) and 01110000b rlca rlca rlca rlca add a,3 exx ld c,a ld b,0 exx jr CRYP72 CRYP71: ; pocet po sobe ld a,(hl) and 00011111b or a jp z,CRYP30 ; E.O.D. exx add a,2 ld c,a ld b,0 exx CRYP72: ld a,(XORBYTE) xor (hl) ld (hl),a inc hl inc hl ld c,2 jr CRYP07 CRYP10: call COMPUXOR ld a,(hl) and 00011111b inc a ; 0=1.. ld c,a ld b,0 inc bc push bc push hl add hl,bc ; dalsi flag push hl dec hl ld a,(hl) ld (PRED2+1),a dec hl ld a,(hl) ld (PRED2),a pop de pop hl ld b,c ; staci CRYP20: ld a,(XORBYTE) xor (hl) ld (hl),a inc hl djnz CRYP20 ; u uncomp se xoruje vsechno exx pop bc push bc dec bc exx pop bc CRYP08: ld hl,(EXZDROJ) add hl,bc ld (EXZDROJ),hl exx ld hl,(EXCIL) add hl,bc ld (EXCIL),hl exx ex de,hl CRYP03: jp CRYP01 CRYP07: ld b,0 ex de,hl jr CRYP08 DELITE: DELIST: jr FRMDEL db "MZLITE-" VERSION: db "3.12-" FLVERS: db "C" FLCOMPM: db "N" FLDOS: db "L" FLENDS: db 1Ah FRMDEL: ; kde ma zacinat rozbalovaci rutina;pod bdos nebo pod ccp ld hl,(6) dec h dec h ; pro kazdy bdos..i na Sinclaira... ex de,hl push de FRMBEGIN: ld hl,DELI10-DELITE+100h ; pak bude +1200h... u .MZF ld bc,DELI98-DELI10+1 ldir ; soupne nahoru depacker pop hl jp (hl) ; a skoci do nej - do ni DELI10: ; ::::::::::: rozbalovaci rutina : :::::::::::::::::::::: ld de,DELI98-DELITE+100h ; kde zacinaji data DELIPS: ld bc,0 ; delka sbaleneho,to jedine doda pakovac{cmt-(1102)} ex de,hl add hl,bc ; konec1:hl,konec2:de {cmt-EF00} inc bc push bc ; delka zabaleneho lddr ; presun nahoru inc de ; start hora ex de,hl ; do hl pop bc ; delka zabaleneho MOD04: ld de,100h ; kam DELI99: ; :::::::: rozbalovaci smycka :::::::: z hl do de bc bajtu :: ld a,(hl) bit 7,a jr z,DELI95 ; zpetny retezec : thanks to TSR inc. bit 6,a jr nz,DEBM00 ; bitmapa 10 bitu bit 5,a jr nz,DEUN00 ; uncompressed DEPO00: ; po sobe jdouci and 00011111b or a jr z,DELI80 ; flag E.O.D. je tady : konec !! inc a inc a ; 1"= 3 inc hl ex af,af' ; 1. ld a,(hl) Š inc hl ; priprav pro dalsi pouziti ex af,af' ; 0. DEPO01: ex af,af' ; 1. ld (de),a inc de ex af,af' ; 0. dec a jr nz,DEPO01 DELI96: jr DELI99 DELI95: jr DEOB00 DEBM00: ; :::::::: bitova mapa :::::::: ;:::::::::::::::: 101mmmmm mmmmyyyy yyyyyyyy m : mapa l->r , y : offset inc hl ld a,(hl) and 00000011b ; offset : vyssi 2 z 10 push de exx pop de exx ld b,a inc hl ld a,(hl) ; offset : nizsich 8 ld c,a inc hl push hl exx pop hl exx dec hl dec hl dec hl push hl ld l,e ld h,d inc bc inc bc inc bc inc bc ; 0 = -4 or a sbc hl,bc ex de,hl pop hl ld a,(hl) and 00111111b ; prvnich 6 rlca rlca ld b,a ; 11111100 inc hl ld a,(hl) ; 78901200 rlca rlca ; 90120078 ld c,a ; v c posledni dva bity and 00000011b ; select 78 or b ; 00000078 or 12345600 = 12345678 ld b,a ex de,hl ; hl zespoda exx push de exx pop de ld a,8 ldi ; prvni se presune automaticky.. inc bc DEBM12: rlc b jr nc,DEBM13 ldi inc bc dec hl DEBM13: inc hl dec a jr nz,DEBM12 ld a,4 DEBM14: rlc c jr nc,DEBM15 ldi inc bc dec hl DEBM15: inc hl dec a jr nz,DEBM14 exx push hl exx pop hl ; nove hl DELI97: jr DELI96 DEUN00: ; :: nezkompresovane :: 1..32 inc hl and 00011111b inc a ; 0=1.. ld c,a ld b,0 ldir ; presun zdroj->cil jr DELI96 DELI80: ; ::: konec dekomprese : relokace,skok do nej ld l,a ld h,a inc h jp (hl) DEOB00: ; :: 0xxxyyyy yyyyyyyy ; x=pocet-3,y=-offset and 01110000b rrca rrca rrca rrca add a,3 ; 0=3 ex af,af' ; 0. = pocet ld a,(hl) inc hl and 00001111b ld b,a ; vyssi offset ld a,(hl) ld c,a ; nizsi offset inc hl push hl ; pro dalsi inc bc inc bc inc bc ; -3 : uspora ld l,e ld h,d or a sbc hl,bc ; - v cili ex af,af' ld b,0 ld c,a ; pocet : 3..10 ldir ; presun cil->cil pop hl jr DELI97 DELI98: ;:::::---------------------------------------------------------------::::::: RDUNLITED: ld a,3 ld (ERR_FLAG),a ld a,1 call CHDRV ; vyber source ld hl,FPAR1 ld de,FCB1 ld bc,12 ldir ; presun parametru : source ld de,FCB1 ld c,35 call 5 ; spocti delku v sektorech OPEN11: ld hl,(FCB1+33) ; hl = delka v sektorech ld (PDEL),hl xor a srl h rr l rra ld h,l ld l,a ld (UNLSIZE),hl ; delka v bytech ex de,hl ld hl,(6) ; bdos dec h dec h ; ochrana ld bc,(FREEMEM) or a sbc hl,bc ; mohu poskytnout or a sbc hl,de ; de = delka vstupu jr nc,GOGOGO ld a,11 ; s tak velkym nemuzu... ld (ERR_FLAG),a jp ERR_END GOGOGO: ld de,FCB1 ld c,15 call 5 ; otevri zdroj cp 0ffh ; je tam vubec ten soubor ? jr nz,OPEN99 ; ? je .. do roboty ! jp ERR_END ; normal shutdown OPEN99: ld de,(FREEMEM) ; sem nacist cely soubor 32kB,pode mnou uz je push de RBYTE: READ4: ; --loop nacitajici bloky,dokud neni all file nebo fullmem-- push de ld c,26 call 5 ld c,20 ld de,FCB1 call 5 pop de or a ; konec souboru ? jr nz,READOUT ; ano : view a cekam... ld hl,80h add hl,de ex de,hl ; de /DMA/ += 80h jr READ4 READOUT: ; ::::::: vlastni rozbaleni :::::: pop de ex de,hl ; hl = start1 ld bc,(UNLSIZE) ; delka nesbaleneho add hl,bc ; hl = end1 ex de,hl ; de = end1 ld hl,(6) dec h dec h dec h ; hl = end2 ex de,hl ; de=end2,hl=end1 inc bc ; bc =end1-start1 lddr ; start1 up to start2 inc de ; ldxx konci pri dalsim ! ld (FROMLITE),de ; odkud zacit balit : NAHORE ld hl,DELI98 ld (FREEMEM),hl ld (TOLITE),hl ; a kam balit : DOLE,ja uz nebudu potrebny ld hl,FCB1+9 ld de,MZF ld bc,3 call CMPSTR ret nz ; neni to mzf ld a,1 ld (ISMZF),a ret ;::: CMPSTR: ld a,(de) inc de cpi ; hl++ ret nz ret po jr CMPSTR VOLNARAM: ;::: INITVYP: ld a,(SOURDRV) add a,"A" ld (INDRV),a ld a,(DESTDRV) add a,"A" ld (OUTDRV),a Š ld hl,FPAR1+1 ld de,INNAME call POZPREP ld hl,FPAR2+1 ld de,OUTNAME call POZPREP ld a,"0" ld (PERC),a ld hl,PAST ld de,PERC+1 ld bc,3 ldir ret ;::: RDPARAM: ld de,MZLUVOD ld c,9 call 5 ld hl,80h ld a,(hl) or a ret z ; bez parametru exx ld hl,PARAMS exx inc hl call PRESKMEZ ; preskoc mezery ld a,(hl) cp "-" jr nz,RDPA01 ; bez parametru jr RDPA02 ; zatim je to tak RDPA02: ld a,(hl) cp " " jr z,RDPA54 ; po parametru : jmeno cp 3Ah jr c,RDPA44 and 5Fh RDPA44: exx ld (hl),a ; uloz dalsi parametr inc hl exx inc hl jr RDPA02 RDPA54: call PRESKMEZ ; -a-j nebo -a -j ld a,(hl) cp "-" jr z,RDPA02 ; dalsi parametr BYLPAR: db 0 RDPA01: exx ld de,PARAMS or a sbc hl,de ld (PARSIZE),hl ; delka nactenych dat exx ld de,FPAR1 call RNAME ; nacti jmeno archivu - urcite na prvnim miste ld de,FPAR2 call RNAME ; nacti file - specifikaci + ?,* ld hl,FPAR1+12 xor a or (hl) ret z ; zadny filespec ld hl,FPAR2+12 xor a or (hl) jr nz,RDPAP0 ; i druhy je specify ld a,(DESTDRV) cp 88 jr nz,RDPA03 ld a,(ACTDRV) ld (DESTDRV),a RDPA03: ld hl,FPAR1 ld de,FPAR2 ld bc,12 RDPAP2: ldir xor a inc a ret RDPAP0: ld hl,FPAR1+9 ld de,MZF ld bc,3 call CMPSTR ret nz ; neni to mzf ld hl,FPAR2+9 ld de,COM ld bc,3 call CMPSTR ret nz ; neni to .com ,takze se do toho nebudu hrabat ld hl,MZF ld de,FPAR2+9 ld bc,3 jr RDPAP2 ; :::: RNAME: ; :::::::::: nacte jmeno sowboru :::::: ld c,25 push de push hl call 5 pop hl pop de ld (ACTDRV),a ld (RDNFCB),de call PRESKMEZ ld a,(hl) or a ret z ld bc,9 ; ne delsi,nez name + "." call PRESKMEZ ; preskoc mezery inc hl ld a,(hl) cp ":" ; je specifikace drivu ? jr nz,WOC021 ; neni dec hl ld a,(hl) and 5Fh sub "A" ex af,af' ld a,(SOURDRV) cp 88 jr nz,WOC022 ; uz jedu na destin ex af,af' ld (SOURDRV),a jr WOC025 WOC022: ex af,af' ld (DESTDRV),a WOC025: inc hl ;za ni inc hl ; za: jr WOC023 WOC021: dec hl ld a,(ACTDRV) ex af,af' ld a,(SOURDRV) cp 88 jr nz,WOC024 ; uz jedu na destin ex af,af' ld (SOURDRV),a jr WOC023 WOC024: ex af,af' ld (DESTDRV),a WOC023: call PRESKMEZ ld a,(hl) or a ret z exx ld hl,(RDNFCB) ld bc,12 add hl,bc ld (hl),1 ; tato polozka je platna exx inc de WOC030: ld a,(hl) or a ret z cp " " ret z cp "." jr z,WOC031 and 5Fh ldi ld a,b or c ret z jr WOC030 WOC031: ex de,hl ld hl,(RDNFCB) ld bc,9 add hl,bc ex de,hl ld bc,3 inc hl ; preskoc "." jr WOC030 ;::: PRESKMEZ: ld a,(hl) or a ret z cp " " ret nz inc hl jr PRESKMEZ ZAM02: ;:::::: MZLUVOD: db 10,10,13 db "MZlite command compressor,Copyright (c) 1993 Svatopluk óvec,verze 3.12d,01-07-93" db 10,13,36,0,0,0,0 VYSVTL: db 13 db " Program kompresuje spustiteln× soubory pod CP/M nebo CMT .",10,10,13 db " PouÚitÉ : mzlite [-volba..] [s:]jm×no1[.ext] [d:][jm×no2][.ext]" db 10,10,13 db " VÙbÅr voleb :",10,10,13 db " : dekompresnÉ rutina se relokuje pod BDOS",10,13 db " -p : dekompresnÉ rutina se relokuje pod CCP",10,13 db " -ahhhh : dekompresnÉ rutina se relokuje pod adresu hhhh",10,13 db " -x : expanze kompresovan×ho souboru na pÊvodnÉ velikost",10,13 db " -e : extra komprese - soubor pot× nelze expandovat",10,13 db " -rhhhh : v .MZF nemapovat ROM , po dekompresi skoÃit na adresu hhhh",10,13 db " -o : vytvoÒÉ pouze zkompresovanÁ data , bez dekompresnÉ rutiny",10,10,13 db " VÙhradnÉ distributor : B B S",10,13 db " KosÁ 8 nebo Holubova 17",10,13 db " 405 02 DÅÃÉn VII.",10,10,13,7,36 ; -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==--====-=--=- end