diff --git a/src/LZW/lzw.asm b/src/LZW/lzw.asm index 493d898..b86c2ff 100644 --- a/src/LZW/lzw.asm +++ b/src/LZW/lzw.asm @@ -25,347 +25,343 @@ -PRUCHOD .EQU $5bff ; zasobnik informaci o Pruchodu stromem -NIL .EQU 0 -ZAZ_LEK .EQU 8 ; pocet bajtu jednoho Zaznamu ve Slovniku komprese -SLOVNIK .EQU SLO_PLN+(SLO_MAX*ZAZ_LEK) ; adresa zacatku Slovniku komprese +STROM_PRUCHOD .EQU $5bff ; zasobnik informaci o Pruchodu stromem +NIL .EQU 0 +ZAZNAM_K_SIZE .EQU 8 ; pocet bajtu jednoho Zaznamu ve Slovniku komprese +SLOVNIK_K .EQU SLOVNIK_PLNY+(SLOVNIK_MAX*ZAZNAM_K_SIZE) ; adresa zacatku Slovniku komprese - ;ld hl,0 ; boot sektor (zakomentovano protoze nastaveno v nadmodulu) - ;push hl ; prvni uspesne zkomprimovany logicky sektor (zakomentovano protoze vlozeno v nadmodulu) - ;push hl ; logicky sektor ke kompresi (zakomentovano protoze vlozeno v nadmodulu) + ld b,8 ; B = pocet volnych bitu Vystupu - ld (_SPK+1),sp ; zaloha SP + ld hl,VYSTUP ; inicializace aktualniho bajtu Vystupu + ld (wVystupK),hl - ld b,8 ; B = pocet volnych bitu Vystupu + ld hl,SLOVNIK_K ; inicializace volne pozice ve Slovniku + ld (wSlovnikK),hl - ld hl,VYSTUP ; inicializace aktualniho bajtu Vystupu - ld (_VystuK+1),hl + ld h,l ; inicializace Korene stromu; H=L=0 + ld (wKoren),hl - ld hl,SLOVNIK ; inicializace volne pozice ve Slovniku - ld (_SlovK+1),hl - - ld h,l ; inicializace Korene stromu (zaruceno H=L=0) - ld (_Koren+1),hl - - pop hl ; do HL logicky sektor ke kompresi - push hl + pop hl ; do HL logicky sektor ke kompresi + push hl SektorK - push bc ; zaloha poctu volnych bitu Vystupu - - call LOGFYZ ; logicky sektor v HL na fyzickou stopu a sektor v BC - - ld a,b ; zobrazeni statistiky o zpracovanosti stop; A = informace <0;255> - inc a ; "mapovani" stop z {0..N-1} na {1..N} (aby po zpracovani posledni stopy prouzek statistiky cely zeleny) - call Statist - .BYTE 36 ; barva (zde Paper 4, Ink 4) - .BYTE STP_STA ; adresa - - ld a,(_VystuK+2) ; zobrazeni statistiky zaplnenosti Vystupu; A = informace <0;255> - sub VYSTUP>>8 - call Statist - .BYTE 36 ; barva (zde Paper 4, Ink 4) - .BYTE VYS_STA ; adresa - - push de ; zaloha Prefixu - ld hl,BUFFER ; precteni fyzickeho sektoru BC na adresu HL - ld e,3 ; tri pokusy cteni (tj. dvakrat opakovani pri chybe) - call DREAD - call D80Err ; test pouze chyby CRC (rutina DREAD=$236A nezohlednuje pripravenost mechaniky) - pop de ; obnova Prefixu - - pop bc ; obnova poctu volnych bitu Vystupu - - di ; zakazani preruseni (protoze pouzivany stinove registry) - xor a ; Carry=0 - - ld iy,BUFFER ; IY = ukaz akt. Znaku - - ; HL = < bez informace > - ld d,a ; DE = prefix akt. Znaku ; D=A=0 - ld e,(iy+0) - ;ld b,... ; B = pocet volnych bitu Vystupu - ; C = akt. Znak - - ;exx - ; HL' = < bez informace > - ;ld de,... ; DE' = vrchol zasobniku Pruchodu stromem (zakomentovano protoze nastaveno nize) - ; BC' = < bez informace > - -RepeatK inc iy ; test konce Buffru - .BYTE $fd ; meni nasledujici instrukci na Ld(A,High(IY)) - ld a,h ; Ld(A,High(IY)) - cp (BUFFER+512)>>8 - jr nc,BufCelK - ld c,(iy+0) ; do C Znak z Buffru - - exx -_Koren ld hl,$0000 ; do HL' Koren stromu ($0000 = urceno za behu) - ld de,PRUCHOD ; do DE' vrchol zasobniku Pruchodu stromem - ld bc,NIL ; do BC' Zaznam Rodice Korene stromu -HledejK ex de,hl ; v zasobniku Pruchodu vytvoreni informace o Rodici Zaznamu - dec l ; v A specificke informace o Rodici - sbc a,a ; A=-Carry - ld (hl),a - dec l - dec l ; v BC' Zaznam Rodice - ld (hl),b - dec l - ld (hl),c - ex de,hl - - inc h ; pokud HL'=Nil, Zaznam [AktPrefix,AktZnak] ve Slovniku neexistuje a nutno jej vytvorit - dec h ; nelze Ld(A,H), Or(A) protoze nutno zachovat A - jr z,ZaznamK - - ld sp,hl ; do SP Zaznam ve Slovniku - ld b,h ; do BC' zaloha zacatku Zaznamu - ld c,l - pop hl ; do HL' "pravy podstrom" - exx - pop hl ; do HL Zaznamenany Prefix - xor a - sbc hl,de - exx - jr c,HledejK ; Zaznamenany Prefix mensi nez akt. Prefix, hledani v "pravem podstromu" - pop hl ; do HL' "levy podstrom" - jp nz,HledejK ; Zaznamenany Prefix vetsi nez akt. Prefix, hledani v "levem podstromu" - exx - pop af ; do A Zaznamenany Znak - sub c - jr z,ShodaK ; Zaznamenany Znak shodny s akt. Znakem - exx - jr nc,HledejK ; Zaznamenany Znak --vetsi-- nez akt. Znak, hledani v --"levem podstromu"-- - ld h,b - ld l,c - ld sp,hl - pop hl ; do HL' opet --"pravy podstrom"-- - jp HledejK ; Zaznamenany Znak --mensi-- nez akt. Znak, hledani v --"pravem podstromu"-- - -ShodaK ; ve Slovniku nalezen Zaznam [AktPrefix,AktZnak] - pouziti Zaznamu jako aktualniho Prefixu (a pokus o jeho rozsireni dalsim znakem) - ld hl,-ZAZ_LEK - add hl,sp - ex de,hl - jp RepeatK - -BufCelK ; cely Buffer zpracovan - ld a,$21 ; zmena instrukce Jp(...) na "neskodnou" Ld(Hl,...) - ld (_BuffOk),a - xor a - jp _Vyst3K ; zapis aktualniho Prefixu na Vystup - - -SloPlnK ; vyprazdneni plneho Seznamu a Slovniku - ld hl,SLOVNIK ; inicializace volne pozice ve Slovniku - ld (_SlovK+1),hl - ld h,l ; H=L=0 (L=0 zaruceno jiz z HL=Slovnik vyse) -KorenK ld (_Koren+1),hl ; nastaveni Korene stromu - xor a - jp _Vyst2K - - -ZaznamK exx ; ve Slovniku vytvoreni Zaznamu [AktPrefix,AktZnak] -_SlovK ld sp,$0000 ; do SP volna pozice ve Slovniku ($0000 = urceno za behu) - ld h,c ; Zaznamenani Znaku v H a Vyvazenosti=0 v L - ld l,0 - push hl - ld h,l ; H=L=0 - push hl ; Zaznamenani "leveho podstromu" (=Nil) - push de ; Zaznamenani Prefixu - push hl ; zaznamenani "praveho podstromu" (=Nil) - ex af,af' ; do A' zaloha specifickych informaci o Rodici - exx - - ;ld hl,NIL ; zakomentovano protoze HL'=Nil zaruceno - add hl,sp - bit 6,h ; zaplnen-li Slovnik, vyprazdneni (6.bit=0 = H' {-1,1} - inc a - add a,(hl) ; uprava Vyvazenosti Rodice jako (HL'+6)+=A - ld (hl),a - jp z,_Vyst2K ; (zaruceno A=0); Rodic se stal idealne Vyvazenym a neovlivni Vyvazenost zadneho ze svych Nadrodicu - ld l,c ; z C' obnova Low(Rodic) - bit 0,a - ex de,hl ; do DE' Rodic (stava se Zaznamem), do HL' Zaznam (nize nahrazen rodicem Rodice) - jr z,RotaceK ; je-li Vyvazenost Zaznamu {2,-2}, nulty bit je vzdy roven 0 a Rodic je v netolerovane NeVyvazenosti - ld b,a ; do B' Vyvazenost Zaznamu - pop hl ; do HL' Rodic ze zasobniku Pruchodu stromem - xor a - or h - ld c,l ; do C' zaloha Low(Rodic) - jp nz,OvlivnK - jp _Vyst2K ; zadny dalsi Rodic (zaruceno A=0) - -_RotDvo ; dokonceni Dvojite Rotace (provedenim "vnejsi" jednoduche Rotace) - ld l,b ; obnova Low(Rodic) - ex de,hl ; do HL' Zaznam, do DE' Rodic - ccf ; "vnejsi" rotace opacny smer nez "vnitrni" rotace - bit 7,h ; aby Zero=1 (zaruceno H'<$7F) = po provedeni "vnejsi" rotace netreba zadnou dalsi rotaci - jp _RotJed - -RotaceK ; Rodic DE' je v netolerovane NeVyvazenosti A={2,-2} (v HL' Zaznam, v B' Vyvazenost Zaznamu HL') - xor b ; urceni zda nutno Jednoduchou nebo Dvojitou Rotaci - jp p,RotJedn -RotDvoj ; nutna dvojita Rotace - urceni smeru - ld hl,-12 ; nastaveni puvodnich HL' a DE' - add hl,sp - ld sp,hl - pop hl ; do HL' zpet puvodni zaznam - pop bc - pop de ; do DE' zpet puvodni rodic - pop bc -RotJedn ; nutna jednoducha Rotace - rra ; protoze 0.bit vzdy =1 - srl a ; urceni smeru Rotace -_RotJed - ld b,e ; do B' zaloha Low(Rodic) - ld c,l ; do C' zaloha Low(Zaznam) - inc bc ; BC'++ protoze nize provadeno Ldi (a to BC'--) (nelze Inc(C) protoze nutno zachovat Zero) - jr c,Rot_RR - -Rot_LL ex af,af' ; nutna Rotace LL (v HL' Zaznam, v DE' Rodic) - set 2,l ; "levy podstrom" Zaznamu HL' musi "pravym podstromem" Rodice DE' - ldi - ld a,(hl) - ld (de),a - ld (hl),d ; Rodic DE' jako "levy podstrom" Zaznamu HL' - dec l - ld (hl),b - ex de,hl ; do DE' Zaznam, do HL' Rodic - rlca ; do A: 1 <=> Rodic HL' ma "pravy podstrom", 0 <=> jinak - rlca - and 1 - set 2,l ; A -= ( 1 <=> Rodic HL' ma "levy podstrom", 0 <=> jinak ) - cp (hl) - sbc a,0 - neg ; A=-A - jp _RodVyv - -KorenDE ld (_Koren+1),de - jp _ZazVyv - -Rot_RR ex af,af' ; nutna Rotace RR (v HL' Zaznam, v DE' Rodic) - set 2,e ; "pravy podstrom" Zaznamu HL' musi "levym podstromem" Rodice DE' - ldi - ld a,(hl) - ld (de),a - ld (hl),d ; Rodic DE' jako "pravy podstrom" Zaznamu HL' - dec l - ld (hl),b - ex de,hl ; do DE' Zaznam, do HL' Rodic - rlca ; do A: 1 <=> Rodic HL' ma "levy podstrom", 0 <=> jinak - rlca - and 1 - res 2,l ; A -= ( 1 <=> Rodic HL' ma "pravy podstrom", 0 <=> jinak ) - cp (hl) - sbc a,0 - set 2,l - -_RodVyv inc l ; urceni a nastaveni Vyvazenosti Rodice HL' - ld (hl),a - ld e,c ; obnova Low(Zaznam) - pop hl ; do HL' Nadrodic (tj. rodic Rodice) (v DE' Zaznam) - ld a,h - or a - jr z,KorenDE - pop af ; do A specificke informace o Rodici - or a - ld b,l ; do B' zaloha Low(Nadrodic) (pro pripad ze nutna Dvojita rotace) - jr nz,_NadRod ; ma-li Zaznam soucasti "praveho podstromu" Nadrodice, skoc - set 2,l ; Zaznam soucast --"leveho podstromu"-- Nadrodice, pricti 4 -_NadRod ld (hl),e ; Zaznam DE' jako "pravy/levy podstrom" Nadrodice HL' - inc l - ld (hl),d - ex af,af' ; rozhodnuti zda nutna Dvojita rotace - jr nz,_RotDvo - -_ZazVyv ld a,e ; nulovani Vyvazenosti Zaznamu HL' - or 6 - ld e,a - xor a - ld (de),a + push bc ; zaloha poctu volnych bitu Vystupu + + call LOGFYZ ; logicky sektor v HL na fyzickou stopu a sektor v BC + + ld a,b ; zobrazeni statistiky o zpracovanosti stop; A = informace <0;255> + inc a ; "mapovani" stop z {0..N-1} na {1..N} (aby po zpracovani posledni stopy prouzek statistiky cely zeleny) + call Statistika + .BYTE 36,STATIST_STOPY; barva (zde Paper 4, Ink 4) a adresa + + ld a,(wVystupK+1) ; zobrazeni statistiky zaplnenosti Vystupu; A = informace <0;255> + sub VYSTUP>>8 + call Statistika + .BYTE 36,STATIST_VYSTUP; barva (zde Paper 4, Ink 4) a adresa + + push de ; zaloha Prefixu + ld hl,BUFFER ; precteni fyzickeho sektoru BC na adresu HL + ld e,3 ; tri pokusy cteni (tj. dvakrat opakovani pri chybe) + call DREAD + call D80Err ; test pouze chyby CRC (rutina DREAD=$236A nezohlednuje pripravenost mechaniky) + pop de ; obnova Prefixu + + pop bc ; obnova poctu volnych bitu Vystupu + + di ; zakazani preruseni (protoze pouzivany stinove registry) + xor a ; Carry=0 + + ld iy,BUFFER ; IY = ukaz akt. Znaku + + ; HL = < bez informace > + ld d,a ; DE = prefix akt. Znaku ; D=A=0 + ld e,(iy+0) + ;ld b,... ; B = pocet volnych bitu Vystupu + ; C = akt. Znak + + ;exx + ; HL' = < bez informace > + ;ld de,... ; DE' = vrchol zasobniku Pruchodu stromem (zakomentovano protoze nastaveno nize) + ; BC' = < bez informace > + +RepeatK inc iy ; test konce Buffru + .BYTE $fd ; meni nasledujici instrukci na Ld(A,High(IY)) + ld a,h ; Ld(A,High(IY)) + cp (BUFFER+512)>>8 + jr nc,BufCelK + ld c,(iy+0) ; do C Znak z Buffru + + exx + .BYTE OP_LD_HL_NN ; do HL' Koren stromu ($0000 = urceno za behu) +wKoren .WORD 0 + ld de,STROM_PRUCHOD ; do DE' vrchol zasobniku Pruchodu stromem + ld bc,NIL ; do BC' Zaznam Rodice Korene stromu +HledejK ex de,hl ; v zasobniku Pruchodu vytvoreni informace o Rodici Zaznamu + dec l ; v A specificke informace o Rodici + sbc a,a ; A=-Carry + ld (hl),a + dec l + dec l ; v BC' Zaznam Rodice + ld (hl),b + dec l + ld (hl),c + ex de,hl + + inc h ; pokud HL'=Nil, Zaznam [AktPrefix,AktZnak] ve Slovniku neexistuje a nutno jej vytvorit + dec h ; nelze Ld(A,H), Or(A) protoze nutno zachovat A + jr z,ZaznamK + + ld sp,hl ; do SP Zaznam ve Slovniku + ld b,h ; do BC' zaloha zacatku Zaznamu + ld c,l + pop hl ; do HL' "pravy podstrom" + exx + pop hl ; do HL Zaznamenany Prefix + xor a + sbc hl,de + exx + jr c,HledejK ; Zaznamenany Prefix mensi nez akt. Prefix, hledani v "pravem podstromu" + pop hl ; do HL' "levy podstrom" + jp nz,HledejK ; Zaznamenany Prefix vetsi nez akt. Prefix, hledani v "levem podstromu" + exx + pop af ; do A Zaznamenany Znak + sub c + jr z,ShodaK ; Zaznamenany Znak shodny s akt. Znakem + exx + jr nc,HledejK ; Zaznamenany Znak --vetsi-- nez akt. Znak, hledani v --"levem podstromu"-- + ld h,b + ld l,c + ld sp,hl + pop hl ; do HL' opet --"pravy podstrom"-- + jp HledejK ; Zaznamenany Znak --mensi-- nez akt. Znak, hledani v --"pravem podstromu"-- + +ShodaK ; ve Slovniku nalezen Zaznam [AktPrefix,AktZnak] - pouziti Zaznamu jako aktualniho Prefixu (a pokus o jeho rozsireni dalsim znakem) + ld hl,-ZAZNAM_K_SIZE + add hl,sp + ex de,hl + jp RepeatK + +BufCelK ; cely Buffer zpracovan + ld a,OP_LD_HL_NN ; zmena instrukce Jp(NN) na "neskodnou" Ld(HL,NN) + ld (bBuffOk),a + xor a + jp _Vyst3K ; zapis aktualniho Prefixu na Vystup + + +SlovnikPlnyK ; vyprazdneni plneho Seznamu a Slovniku + ld hl,SLOVNIK_K ; inicializace volne pozice ve Slovniku + ld (wSlovnikK),hl + ld h,l ; H=L=0 (L=0 zaruceno jiz z HL=Slovnik vyse) +KorenK ld (wKoren),hl ; nastaveni Korene stromu + xor a + jp _Vyst2K + + +ZaznamK exx ; ve Slovniku vytvoreni Zaznamu [AktPrefix,AktZnak] + .BYTE OP_LD_SP_NN ; do SP volna pozice ve Slovniku ($0000 = urceno za behu) +wSlovnikK .WORD 0 + ld h,c ; Zaznamenani Znaku v H a Vyvazenosti=0 v L + ld l,0 + push hl + ld h,l ; H=L=0 + push hl ; Zaznamenani "leveho podstromu" (=Nil) + push de ; Zaznamenani Prefixu + push hl ; zaznamenani "praveho podstromu" (=Nil) + ex af,af' ; do A' zaloha specifickych informaci o Rodici + exx + + ;ld hl,NIL ; zakomentovano protoze HL'=Nil zaruceno + add hl,sp + bit 6,h ; zaplnen-li Slovnik, vyprazdneni (6.bit=0 = H' {-1,1} + inc a + add a,(hl) ; uprava Vyvazenosti Rodice jako (HL'+6)+=A + ld (hl),a + jp z,_Vyst2K ; (zaruceno A=0); Rodic se stal idealne Vyvazenym a neovlivni Vyvazenost zadneho ze svych Nadrodicu + ld l,c ; z C' obnova Low(Rodic) + bit 0,a + ex de,hl ; do DE' Rodic (stava se Zaznamem), do HL' Zaznam (nize nahrazen rodicem Rodice) + jr z,RotaceK ; je-li Vyvazenost Zaznamu {2,-2}, nulty bit je vzdy roven 0 a Rodic je v netolerovane NeVyvazenosti + ld b,a ; do B' Vyvazenost Zaznamu + pop hl ; do HL' Rodic ze zasobniku Pruchodu stromem + xor a + or h + ld c,l ; do C' zaloha Low(Rodic) + jp nz,OvlivniVyvazenost + jp _Vyst2K ; zadny dalsi Rodic (zaruceno A=0) + +_RotDvo ; dokonceni Dvojite Rotace (provedenim "vnejsi" jednoduche Rotace) + ld l,b ; obnova Low(Rodic) + ex de,hl ; do HL' Zaznam, do DE' Rodic + ccf ; "vnejsi" rotace opacny smer nez "vnitrni" rotace + bit 7,h ; aby Zero=1 (zaruceno H'<$7F) = po provedeni "vnejsi" rotace netreba zadnou dalsi rotaci + jp _RotJednoducha + +RotaceK ; Rodic DE' je v netolerovane NeVyvazenosti A={2,-2} (v HL' Zaznam, v B' Vyvazenost Zaznamu HL') + xor b ; urceni zda nutno Jednoduchou nebo Dvojitou Rotaci + jp p,RotJednoducha +RotDvojita ; nutna dvojita Rotace - urceni smeru + ld hl,-12 ; nastaveni puvodnich HL' a DE' + add hl,sp + ld sp,hl + pop hl ; do HL' zpet puvodni zaznam + pop bc + pop de ; do DE' zpet puvodni rodic + pop bc +RotJednoducha ; nutna jednoducha Rotace + rra ; protoze 0.bit vzdy =1 + srl a ; urceni smeru Rotace +_RotJednoducha ld b,e ; do B' zaloha Low(Rodic) + ld c,l ; do C' zaloha Low(Zaznam) + inc bc ; BC'++ protoze nize provadeno Ldi (a to BC'--) (nelze Inc(C) protoze nutno zachovat Zero) + jr c,Rot_RR + +Rot_LL ex af,af' ; nutna Rotace LL (v HL' Zaznam, v DE' Rodic) + set 2,l ; "levy podstrom" Zaznamu HL' musi "pravym podstromem" Rodice DE' + ldi + ld a,(hl) + ld (de),a + ld (hl),d ; Rodic DE' jako "levy podstrom" Zaznamu HL' + dec l + ld (hl),b + ex de,hl ; do DE' Zaznam, do HL' Rodic + rlca ; do A: 1 <=> Rodic HL' ma "pravy podstrom", 0 <=> jinak + rlca + and 1 + set 2,l ; A -= ( 1 <=> Rodic HL' ma "levy podstrom", 0 <=> jinak ) + cp (hl) + sbc a,0 + neg ; A=-A + jp _RodVyv + +KorenDE ld (wKoren),de + jp _ZazVyv + +Rot_RR ex af,af' ; nutna Rotace RR (v HL' Zaznam, v DE' Rodic) + set 2,e ; "pravy podstrom" Zaznamu HL' musi "levym podstromem" Rodice DE' + ldi + ld a,(hl) + ld (de),a + ld (hl),d ; Rodic DE' jako "pravy podstrom" Zaznamu HL' + dec l + ld (hl),b + ex de,hl ; do DE' Zaznam, do HL' Rodic + rlca ; do A: 1 <=> Rodic HL' ma "levy podstrom", 0 <=> jinak + rlca + and 1 + res 2,l ; A -= ( 1 <=> Rodic HL' ma "pravy podstrom", 0 <=> jinak ) + cp (hl) + sbc a,0 + set 2,l + +_RodVyv inc l ; urceni a nastaveni Vyvazenosti Rodice HL' + ld (hl),a + ld e,c ; obnova Low(Zaznam) + pop hl ; do HL' Nadrodic (tj. rodic Rodice) (v DE' Zaznam) + ld a,h + or a + jr z,KorenDE + pop af ; do A specificke informace o Rodici + or a + ld b,l ; do B' zaloha Low(Nadrodic) (pro pripad ze nutna Dvojita rotace) + jr nz,_NadRod ; ma-li Zaznam soucasti "praveho podstromu" Nadrodice, skoc + set 2,l ; Zaznam soucast --"leveho podstromu"-- Nadrodice, pricti 4 +_NadRod ld (hl),e ; Zaznam DE' jako "pravy/levy podstrom" Nadrodice HL' + inc l + ld (hl),d + ex af,af' ; rozhodnuti zda nutna Dvojita rotace + jr nz,_RotDvo + +_ZazVyv ld a,e ; nulovani Vyvazenosti Zaznamu HL' + or 6 + ld e,a + xor a + ld (de),a -_Vyst2K exx -_Vyst3K or d ; (zaruceno A=0) do A horni bajt Prefixu, tj. A=D=High(Prefix) - jp z,_VystuK ; prefixem je Ascii znak - sub SLO_PLN>>8 ; A-=High(SLO_PLN) (protoze zarovnani Slovniku na $xx00) - rra ; zaruceno Carry=0 - rr e - rra - rr e - rra - rr e - inc a ; symbol ma kod "za" Ascii -_VystuK ld hl,$0000 ; do HL ukaz volne pozice Vystupu ($0000 = urceno za behu) - ld d,b ; do D pocet volnych bitu Vystupu - ld b,N_BITU ; zapis nBitu symbolu na Vystup -_Zap1K rra - rr e - rr (hl) ; zapis nejnizsiho bitu DE do Vystupniho fifo - dec d - jp nz,_Zap2K - inc hl ; dalsi bajt Vystupu - inc h ; test zaplnenosti Vystupu - jr z,KonecK ; zaplnen-li Vystup, konec (Carry=0) - dec h - ld d,8 -_Zap2K djnz _Zap1K - ld (_VystuK+1),hl ; uchovani ukaz volne pozice Vystupu - ld b,d ; do B zpet pocet volnych bitu Vystupu - ld d,0 ; aktualni Znak prefixem dalsiho znaku (D=0, E=C) - ld e,c -_BuffOk jp RepeatK ; opcode instrukce po zpracovani celeho Buffru zmenen z Jp(...) na Ld(Hl,...) - ld a,$c3 ; uprava opcodu instrukce BuffOk z Ld(Hl,...) zpet na Jp(...) - ld (_BuffOk),a - -_SPK ld sp,$0000 ; obnova SP ($0000 = urceno za behu) -__NSekt ld hl,$0000 ; do HL pocet sektoru na diskete ($0000 = urceno za behu) - pop de - inc de - push de - xor a - sbc hl,de - ex de,hl ; do HL pripadny dalsi sektor - jp nz,SektorK ; zpracovany-li vsechny sektory, komprese hotova - - inc a ; A=1, tj. cela disketa zpracovana (zaruceno ze predtim A=0) - ld (_Hotovo+1),a - ld hl,(_VystuK+1) ; do HL ukaz volne pozice Vystupu -_FifoK rr (hl) ; rolovani fifo aby na nejnizsim bitu prvni zapsany bit - djnz _FifoK - -KonecK ld sp,(_SPK+1) ; obnova SP (v pripade ze Buffer plny) +_Vyst2K exx +_Vyst3K or d ; (zaruceno A=0) do A horni bajt Prefixu, tj. A=D=High(Prefix) + jp z,_VystuK ; prefixem je Ascii znak + sub SLOVNIK_PLNY>>8 ; A-=High(SLOVNIK_PLNY) (protoze zarovnani Slovniku na $xx00) + rra ; zaruceno Carry=0 + rr e + rra + rr e + rra + rr e + inc a ; symbol ma kod "za" Ascii +_VystuK .BYTE OP_LD_HL_NN ; do HL ukaz volne pozice Vystupu ($0000 = urceno za behu) +wVystupK .WORD 0 + ld d,b ; do D pocet volnych bitu Vystupu + ld b,N_BITU ; zapis nBitu symbolu na Vystup +_Zap1K rra + rr e + rr (hl) ; zapis nejnizsiho bitu DE do Vystupniho fifo + dec d + jp nz,_Zap2K + inc hl ; dalsi bajt Vystupu + inc h ; test zaplnenosti Vystupu + jr z,KonecK ; zaplnen-li Vystup, konec (Carry=0) + dec h + ld d,8 +_Zap2K djnz _Zap1K + ld (wVystupK),hl ; uchovani ukaz volne pozice Vystupu + ld b,d ; do B zpet pocet volnych bitu Vystupu + ld d,0 ; aktualni Znak prefixem dalsiho znaku (D=0, E=C) + ld e,c +bBuffOk .BYTE OP_JP_NN + .WORD RepeatK ; opcode instrukce po zpracovani celeho Buffru zmenen z Jp(NN) na Ld(HL,NN) + ld a,OP_JP_NN ; uprava opcodu instrukce BuffOk z Ld(HL,NN) zpet na Jp(NN) + ld (bBuffOk),a + + .BYTE OP_LD_SP_NN ; obnova SP ($0000 = urceno za behu) +wSP .WORD 0 + .BYTE OP_LD_HL_NN ; do HL pocet sektoru na diskete ($0000 = urceno za behu) +nSektoru .WORD 0 + pop de + inc de + push de + xor a + sbc hl,de + ex de,hl ; do HL pripadny dalsi sektor + jp nz,SektorK ; zpracovany-li vsechny sektory, komprese hotova + + ld a,IDHOTOVO ; A=1, tj. cela disketa zpracovana (zaruceno ze predtim A=0) + ld (bHotovo),a + ld hl,(wVystupK) ; do HL ukaz volne pozice Vystupu +_FifoK rr (hl) ; rolovani fifo aby na nejnizsim bitu prvni zapsany bit + djnz _FifoK + +KonecK ld sp,(wSP) ; obnova SP (v pripade ze Buffer plny) diff --git a/src/LZW/main.asm b/src/LZW/main.asm index f7e606a..303eac9 100644 --- a/src/LZW/main.asm +++ b/src/LZW/main.asm @@ -4,261 +4,213 @@ ADRDRAM .EQU AUXBUF ; adresa v DRAM kam utilita z obrazovky presunuta aby udelala prostor pro Slovnik -#DEFINE __DEBUG__0 ; testovaci verze pro emulator - -BOR_SRC .EQU 4 ; barva Borderu pro signalizaci vlozeni zdrojove diskety -BOR_TRG .EQU 6 ; cilove -BOR_PAR .EQU 5 ; potvrzeni parametr('u) zdrojove diskety - -N_BITU .EQU 10 ; pocet bitu komprimovaneho symbolu -SLO_MAX .EQU ((1 << (N_BITU-8))-1)*256 ; max pocet zaznamu ve Slovniku -SLO_PLN .EQU $4000 ; adresa konce Slovniku komprese -VYSTUP .EQU $5d00 -VYS_PLN .EQU $ff00 -VYS_STA .EQU $21 ; zacatek zobrazeni statistiky zaplnenosti Buffru v atributove casti obrazovky ($5800+xx) -STP_STA .EQU $61 ; zacatek zobrazeni statistiky zpracovanosti stop v atributove casti obrazovky ($5800+xx) -BUFFER .EQU $3800 ; (DIRBUF) Buffer na adrese jejiz dolni bajt nulovy (tj. XX00) - - ; na adrese SrcStop mozno pretizit informaci o poctu stop na zdrojove diskete (0 = pouzita hodnota z bootu zdrojove diskety) - ; na adrese SrcStop-1 mozno pretizit informaci o poctu sektoru na jedne stope cilove diskety (vychozi hodnotou je zde 9, viz Dsk80x9) - - .ORG ADRDRAM - - exx ; zalohovani stinovych registr('u) - push hl - push bc - push de - - ld a,79 ; prestrankovani do DROM (viz ZX Magazin 6/93, str. 17) - ld hl,$3ef7 ; provedeni ekvivalentu Poke #247,79 prostrednictvim zapisu 79 do fiktivniho sekvencniho souboru zacinajiciho na adrese #247 = 16119 = $3ef7 - push hl - ld hl,$fde6 ; hodnota "-26" (protoze nize "SP-26" = zacatek tabulky udaju o zapisu do fiktivniho souboru) s 10.bitem nastavenym na 0 (protoze rutina pro zapis znaku testuje zda do buffru zapsano 512 bajtu testem 10.bitu: 0 = buffer neni plny) - push hl - add hl,sp - set 1,h ; nastaveni 10.bitu na 1 aby zacatek tabulky na spravne hodnote (SP-26) - ex de,hl - call $25ab ; provedeni zapisu (Poke #247,79) - rst 00 ; prestrankovani - pop hl - pop hl - - call Presun+(16384-ADRDRAM) ; kopie utility z obrazovky do DRAM (aby odpovidaly adresy volani rutin) - - ld hl,0 ; boot sektor -Lzw push hl ; prvni uspesne zkomprimovany logicky sektor (predpoklad) - push hl ; logicky sektor ke kompresi +#DEFINE __DEBUG__0 ; testovaci verze pro emulator + +BORDER_SRC .EQU 4 ; barva Borderu pro signalizaci vlozeni zdrojove diskety +BORDER_TRG .EQU 6 ; cilove +BORDER_PAR .EQU 5 ; potvrzeni parametr('u) zdrojove diskety + +IDCYKLUJ .EQU OP_XOR_A +IDHOTOVO .EQU OP_SCF + +N_BITU .EQU 10 ; pocet bitu komprimovaneho symbolu +SLOVNIK_MAX .EQU ((1 << (N_BITU-8))-1)*256 ; max pocet zaznamu ve Slovniku +SLOVNIK_PLNY .EQU $4000 ; adresa konce Slovniku komprese +VYSTUP .EQU $5d00 +VYSTUP_PLNY .EQU $ff00 +STATIST_VYSTUP .EQU $21 ; zacatek zobrazeni statistiky zaplnenosti Buffru v atributove casti obrazovky ($5800+xx) +STATIST_STOPY .EQU $61 ; zacatek zobrazeni statistiky zpracovanosti stop v atributove casti obrazovky ($5800+xx) +BUFFER .EQU DIRBUF ; Buffer na adrese jejiz dolni bajt nulovy (tj. XX00) + + +; na adrese SrcStop mozno pretizit informaci o poctu stop na zdrojove diskete (0 = pouzita hodnota z bootu zdrojove diskety) +; na adrese SrcStop-1 mozno pretizit informaci o poctu sektoru na jedne stope cilove diskety (vychozi hodnotou je zde 9, viz Dsk80x9) + + .ORG ADRDRAM + + ld a,79 ; prestrankovani do DROM (viz ZX Magazin 6/93, str. 17) + ld hl,SYSFLAG ; provedeni ekvivalentu Poke #247,79 prostrednictvim zapisu 79 do fiktivniho sekvencniho souboru zacinajiciho na adrese #247 = 16119 = $3ef7 + push hl + ld hl,$fde6 ; hodnota "-26" (protoze nize "SP-26" = zacatek tabulky udaju o zapisu do fiktivniho souboru) s 10.bitem nastavenym na 0 (protoze rutina pro zapis znaku testuje zda do buffru zapsano 512 bajtu testem 10.bitu: 0 = buffer neni plny) + push hl + add hl,sp + set 1,h ; nastaveni 10.bitu na 1 aby zacatek tabulky na spravne hodnote (SP-26) + ex de,hl + call $25ab ; provedeni zapisu (Poke #247,79) + rst 00 ; prestrankovani + pop hl + pop hl #IFNDEF __DEBUG__ - ld a,BOR_SRC ; signalizace vlozeni zdrojove diskety - call DskZmen ; nutno "+(.)" protoze PC odvozen od ORG (a ukazuje do DRAM) a rutina DskZmen je (zatim) na obrazovce + call 16384+PresunDoDRAM-ADRDRAM + call SignalSrc ; signalizace vlozeni zdrojove diskety #ENDIF - pop hl - push hl - ld a,h - or l - jr nz,BootOk - - call GETPAR ; do IX tabulka parametru, nacteni Bootu do $3a00(AUXBUF) = Buffer a naplneni tabulky ukazovane IX parametry vlozeneho disku - - ld hl,DRPAR_A+1 ; pretizeni informace o 40-ti stope diskete v 80-ti stope mechanice - res 5,(hl) - inc l - ld a,(SrcStop+(16384-ADRDRAM)) ; pretizeni informace o poctu stop na zdrojove diskete (0 = pouzita hodnota z bootu zdrojove diskety) - or a - jr z,Boot ; 0 = pouzita hodnota v bootu zdrojove diskety - ld (hl),a - -Boot push hl - call DSKSTP ; zastaveni mechaniky - xor a ; otevreni tiskoveho kanalu 0 - rst 28 - .WORD CHAN_OPEN - pop hl - ld a,(hl) ; zobrazeni rozpoznaneho poctu stop na zdrojove diskete ve formatu "TTxSS" - inc l - call ByteHex+(16384-ADRDRAM) ; nutno "+(.)" aby volana rutina na obrazovce protoze cast utility byla v DRAM prepsana boot sektorem diskety - ld a,'x' ; aby zobrazeno "TTxSS" - rst 10 - ld a,(hl) ; zobrazeni rozpoznaneho poctu sektoru na stopu - call ByteHex+(16384-ADRDRAM) ; nutno "+(.)" aby volana rutina na obrazovce protoze cast utility byla v DRAM prepsana boot sektorem diskety - - ld hl,AUXBUF+177 ; urceni celkoveho poctu sektoru na diskete jako Strany*Stopy*Sektory - bit 4,(hl) ; nemeni Carry, pouze nastavuje Zero - inc hl ; nelze Inc(L) protoze nutno zachovat Zero - ld e,(hl) ; do E pocet stop - inc hl ; nelze Inc(L) protoze nutno zachovat Zero - ld l,(hl) ; do L pocet sektoru - jr z,_Nasob - rl e -_Nasob xor a - ld d,a ; D=H=A=0 - ld h,a - push de ; uchovani poctu stop pro vytvoreni statistiky jejich zpracovanosti nize - rst 28 - .WORD HLMULDE ; ZX ROM rutina pro nasobeni HL*=DE - ld (__NSekt+1+16384-ADRDRAM),hl ; uprava argumentu instrukce "__NSekt" ("+1" = kod instrukce Ld) - - call Presun+(16384-ADRDRAM) ; kopie utility z obrazovky do DRAM (aby odpovidaly adresy volani rutin) - jp $+3 ; nelze "$+3-(16384-ADRDRAM)" protoze aktualni PC jiz odvozen od ORG a tedy ukazuje do DRAM + call GETPAR ; do IX tabulka parametru, nacteni Bootu do DIRBUF (=Buffer) a naplneni tabulky ukazovane IX parametry vlozeneho disku + call DSKSTP ; zastaveni mechaniky + + call 16384+PresunDoDRAM-ADRDRAM + jp $+3 ; nelze "$+3-(16384-ADRDRAM)" protoze aktualni PC jiz odvozen od ORG a tedy ukazuje do DRAM + + ld hl,DRPAR_A+1 ; pretizeni informace o 40-ti stope diskete v 80-ti stope mechanice + res 5,(hl) + inc l + ld a,(SrcStop) ; pretizeni informace o poctu stop na zdrojove diskete (0 = pouzita hodnota z bootu zdrojove diskety) + or a + jr z,Boot ; 0 = pouzita hodnota v bootu zdrojove diskety + ld (hl),a + +Boot push hl + xor a ; otevreni tiskoveho kanalu 0 + rst 28 + .WORD CHAN_OPEN + pop hl + ld b,a ; B=A=0 + ld c,(hl) ; zobrazeni rozpoznaneho formatu zdrojove diskety v podobe "TTxSS" + rst 28 + .WORD OUT_NUM_1 + inc l + ld a,'x' + rst 10 + inc b ; protoze OutNum1 nastavi B=$ff + ld c,(hl) + rst 28 + .WORD OUT_NUM_1 #IFNDEF __DEBUG__ - ld a,BOR_PAR ; signalizace pozadavku potvrzeni rozpoznaneho formatu zdrojove diskety - call DskZmen - ld a,(LASTKEY) ; nestisknuto-li P (tj. nepotvrzeny-li rozpoznane parametry zdrojove diskety), Konec - sub 'p' - ld (_Hotovo+1),a ; LastKey<>P -> Hotovo=1 - pop bc ; do BC pocet stop (vyuzito nize pri vytvoreni statistiky zpracovanosti stop) - jp nz,Konec -#ELSE - pop bc ; do BC pocet stop (vyuzito nize pri vytvoreni statistiky zpracovanosti stop) + ld a,BORDER_PAR ; signalizace pozadavku potvrzeni rozpoznaneho formatu zdrojove diskety + call DskZmen + ld a,(LASTKEY) ; nestisknuto-li P (tj. nepotvrzeny-li rozpoznane parametry zdrojove diskety), Konec + sub 'p' + jp nz,Konec #ENDIF - - ;pop bc ; vytvoreni statistiky zpracovanosti stop; A = informace <0;255> ; (zakomentovano protoze provedeno vyse) - ld a,c - call Statist - .BYTE 0 ; barva (zde Paper 0, Ink 0) - .BYTE STP_STA ; adresa - - ld a,(VYS_PLN-VYSTUP)>>8 ; vytvoreni statistiky zaplnenosti Vystupu; A = informace <0;255> - call Statist - .BYTE 0 ; barva (zde Paper 0, Ink 0) - .BYTE VYS_STA ; adresa - -BootOk call DRVSYS ; do IX tabulka parametru - + call DRVSYS ; do IX tabulka parametru zdrojoveho disku (protoze v GetPar ukazuje na dalsi jednotku, v tomto pripade "C") + call SECPERDISK ; do HL celkovy pocet sektoru na diskete + ld (nSektoru),hl + ld a,IDCYKLUJ + ld (bHotovo),a + + call LOGFYZ ; vytvoreni statistiky zpracovanosti stop; A = pocet stop + ld a,b + call Statistika + .BYTE 0,STATIST_STOPY ; barva (zde Paper 0, Ink 0) a adresa + + ld a,(VYSTUP_PLNY-VYSTUP)>>8 ; vytvoreni statistiky zaplnenosti Vystupu; A = informace <0;255> + call Statistika + .BYTE 0,STATIST_VYSTUP; barva (zde Paper 0, Ink 0) a adresa + + + ld h,c ; boot sektor; H=L=C=0 + ld l,c + push hl ; logicky sektor k dekompresi +Lzw push hl ; logicky sektor ke kompresi + ld (wSP),sp ; zaloha SP #include "lzw.asm" - - call SwapPar ; zastaveni mechaniky a prohozeni aktualnich informaci o diskete a mechanice s informacemi o cilove diskete 80x9 - - pop hl ; v zasobniku prohozeni logickeho sektoru ke kompresi a prvniho uspesne zkomprimovaneho logickeho sektoru - ex (sp),hl - push hl + call SwapPar ; zastaveni mechaniky a prohozeni aktualnich informaci o diskete a mechanice s informacemi o cilove diskete 80x9 #IFNDEF __DEBUG__ - ld a,BOR_TRG ; signalizace vlozeni cilove diskety - call DskZmen + ld a,BORDER_TRG ; signalizace vlozeni cilove diskety + call DskZmen #ENDIF - call DRVSYS ; do IX tabulka parametru disku - + pop hl ; prohozeni logickeho sektoru ke kompresi a dekompresi + ex (sp),hl + push hl #include "unlzw.asm" + call SwapPar ; zastaveni mechaniky a prohozeni aktualnich informaci o diskete a mechanice s informacemi o zdrojove diskete - call SwapPar ; zastaveni mechaniky a prohozeni aktualnich informaci o diskete a mechanice s informacemi o zdrojove diskete - -Konec pop hl ; obnova SP - pop hl -_Hotovo ld a,$00 ; opakovani cyklu Komprese-Dekomprese pro zbyvajici sektory ($00 = urceno za behu; cela disketa zpracovana =1 ) - or a - jp z,Lzw - - ld a,2*100 ; zruseni statistiky zpracovanosti stop; A = informace <0;255> - call Statist - .BYTE 56 ; barva (zde Paper 7, Ink 0) - .BYTE STP_STA ; adresa - - ld de,16384 ; presun utility zpet na obrazovku - ld hl,ADRDRAM - call _Presun - - pop de ; obnoveni puvodnich stinovych registr('u) - pop bc - pop hl - exx - - ei ; obnoveni preruseni - - jp ZXROM ; prestrankuj zpet do ZX ROM - ;ret ; zakomentovano protoze provedeno behem prestrankovani vyse - - - -BrBp ; Border A a Beep HL,DE - rst 28 ; Border; volani rutiny ZX ROM primo z DROM (automaticky potom prestrankovano zpet do DROM) - .WORD BORDER - push ix - ld de,$40 ; Beep; HL = delka kmitu (nastavi volajici), DE = pocet kmitu - rst 28 - .WORD BEEPER - pop ix - ret - -DskZmen ld hl,$300 ; signalizace pozadavku zmeny diskety v mechanice; po navratu je povoleno preruseni - call BrBp ; Border a Beep - ld bc,0 ; Pause 0 - push iy - ld iy,$5c3a ; obnova IY - rst 28 - .WORD PAUSE_1 - pop iy - ld a,7 ; Border 7 - rst 28 - .WORD BORDER - ret ; po navratu je povoleno preruseni - -D80Err xor a ; signalizace chyby mechaniky (pipnuti a cerny Border) - cp c - ret z ; nenastala-li chyba, konec - ;xor a ; Border 0 (zakomentovano protoze nastaveno vyse) - ld hl,$100 ; Beep - jr BrBp ; return - -SwapPar ld hl,DRPAR_A ; zastaveni mechaniky a prohozeni aktualnich a uchovavanych informaci o diskete (4 bajty) - ld de,Dsk80x9 - ld b,4 -_Prohod ld a,(de) - ld c,(hl) - ld (hl),a - ld a,c - ld (de),a - inc l - inc de - djnz _Prohod - jp DSKSTP ; return - -Statist pop hl ; zobrazeni statistiky; A = informace <0;255> - push bc ; do B pocet dilku statistiky jako "informace/8" - and ~7 ; nulovani dolnich tri bitu - rra - rra - rra - ld b,a - inc b ; vzdy alespon jeden dilek prouzku statistiky obarven - ld a,(hl) ; do A barva - inc hl - push de ; do DE adresa jako "zacatek atributove casti obrazovky plus offset" (tj. $5800+xx) - ld e,(hl) - inc hl - ld d,$58 -_Statis ld (de),a ; vykresleni statistiky - inc e - djnz _Statis - pop de - pop bc - jp (hl) - -ByteHex push af ; prevede hodnotu v A na dva hexa znaky a zobrazi je na aktualni tiskovou pozici - rra - rra - rra - rra - call TiskHex+(16384-ADRDRAM) ; horni pulbajt; nutno "+(.)" protoze PC odvozen od ORG (a ukazuje do DRAM) a rutina TiskHex je na obrazovce - pop af ; dolni pulbajt -TiskHex and $f - add a,$90 - daa - adc a,$40 - daa - rst 10 - ret - -Presun ld de,ADRDRAM ; presun utility z obrazovky do DRAM - ld hl,16384 -_Presun ld bc,1024 - ldir - ret - -Dsk80x9 .BYTE 129,24,80,9 ; informace o diskete 80x9 v mechanice A -SrcStop .BYTE 0 ; pretizeni informace o poctu stop na zdrojove diskete (0 = pouzita hodnota z bootu zdrojove diskety) - - - .END +bHotovo .BYTE IDCYKLUJ ; opakovani cyklu Komprese-Dekomprese pro zbyvajici sektory ($00 = urceno za behu; cela disketa zpracovana =1 ) +#IFNDEF __DEBUG__ + call nc,SignalSrc ; signalizace vlozeni zdrojove diskety +#ENDIF + pop hl ; obnova SP + jp nc,Lzw + + +Hotovo pop hl ; prenos dokoncen; obnova SP + rst 28 ; smazani obrazovky + .WORD CL_ALL + ld de,16384 ; presun utility zpet na obrazovku + ld hl,ADRDRAM + call Presun +Konec ld hl,$2758 ; Ld a Exx aby do Basicu s "Ok, 0:1" + exx + jp ZXROM ; prestrankuj zpet do ZX ROM a konec + + +D80Err ; signalizace chyby cteni/zapisu sektoru (pipnuti a cerny Border) + xor a ; pri chybe Border 0 + cp c + ret z ; nenastala-li chyba, konec + ld hl,$100 ; Beep + ;fallthrough +BrBp ; Border A a Beep HL,DE + rst 28 ; Border + .WORD BORDER + push ix + ld de,$40 ; Beep; HL = delka kmitu (nastavi volajici), DE = pocet kmitu + rst 28 + .WORD BEEPER + pop ix + ret + + +SwapPar ; zastaveni mechaniky a prohozeni aktualnich a uchovavanych informaci o diskete (4 bajty) + ld hl,DRPAR_A + ld de,Dsk80x9 + ld bc,$4ff ; nelze pouze Ld(B,4) protoze Ldi dela BC-- +_Prohod ld a,(de) + ldi + dec l + ld (hl),a + inc l + djnz _Prohod + call DSKSTP + jp DRVSYS ; do IX parametry pracovniho disku (zruseny v DskStp) + +SignalSrc ; signalizace vlozeni zdrojove diskety + ld a,BORDER_SRC +DskZmen ; signalizace pozadavku zmeny diskety v mechanice; po navratu je povoleno preruseni + ld hl,$300 ; Border a Beep + call BrBp + ld iy,ERR_NR ; obnova IY + rst 28 ; Pause 0 + .WORD WAIT_KEY_1 + ld a,7 ; Border 7 + rst 28 + .WORD BORDER + ret ; po navratu je povoleno preruseni + + +Statistika ; zobrazeni statistiky; A = informace 0..255 + pop hl + push bc ; do B pocet dilku statistiky jako "informace/8" + and ~7 ; nulovani dolnich tri bitu + rra + rra + rra + ld b,a + inc b ; vzdy alespon jeden dilek prouzku statistiky obarven + ld a,(hl) ; do A barva + inc hl + push de ; do DE adresa jako "zacatek atributove casti obrazovky plus offset" (tj. $5800+xx) + ld e,(hl) + inc hl + ld d,$58 +_Statis ld (de),a ; vykresleni statistiky + inc e + djnz _Statis + pop de + pop bc + jp (hl) + +PresunDoDRAM ld de,ADRDRAM ; kopie utility z obrazovky do DRAM (aby odpovidaly adresy volani rutin) + ld hl,16384 +Presun ld bc,1023 ; presun utility + ldir + ret + +Dsk80x9 .BYTE 129,24,80,9 ; informace o diskete 80x9 v mechanice A + +SrcStop .BYTE 0 ; pretizeni informace o poctu stop na zdrojove diskete (0 = pouzita hodnota z bootu zdrojove diskety) + + .END diff --git a/src/LZW/unlzw.asm b/src/LZW/unlzw.asm index 5d79f5a..77375e0 100644 --- a/src/LZW/unlzw.asm +++ b/src/LZW/unlzw.asm @@ -1,186 +1,177 @@ -ZAZ_LED .EQU 4 ; pocet bajtu jednoho Zaznamu ve Slovniku dekomprese -SLOVNID .EQU SLO_PLN+(SLO_MAX*ZAZ_LED) ; adresa zacatku Slovniku dekomprese +ZAZNAM_D_SIZE .EQU 4 ; pocet bajtu jednoho Zaznamu ve Slovniku dekomprese +SLOVNIK_D .EQU SLOVNIK_PLNY+(SLOVNIK_MAX*ZAZNAM_D_SIZE) ; adresa zacatku Slovniku dekomprese - ;push bc ; prvni logicky sektor ke kompresi (zakomentovano protoze vlozeno v nadmodulu) - ;push de ; logicky sektor k dekompresi (zakomentovano protoze vlozeno v nadmodulu) + ld hl,VYSTUP ; HL = akt. znak Vystupu + ; DE = akt. symbol + ; BC = predchozi symbol + exx - ld (_SPD+1),sp ; zaloha SP + ld hl,SLOVNIK_D ; HL' = < bez informace > (zde pouze inicializace prazdneho Slovniku) + ; DE' = < bez informace > + ;ld bc,... ; BC' = ukaz akt. znak Buffru (nastaveno nize) - ld hl,VYSTUP ; HL = akt. znak Vystupu - ; DE = akt. symbol - ; BC = predchozi symbol - - exx - - ld hl,SLOVNID ; HL' = < bez informace > (zde pouze inicializace prazdneho Slovniku) - ; DE' = < bez informace > - ;ld bc,... ; BC' = ukaz akt. znak Buffru (nastaveno nize) - - ld a,8 ; A' = pocet bitu Vystupu - ex af,af' + ld a,8 ; A' = pocet bitu Vystupu + ex af,af' -SektorD di - - ld sp,hl ; do SP volna pozice ve Slovniku - ld bc,BUFFER ; BC' = ukaz akt. znak Buffru - ld d,c ; do D'=C'=0 - ld hl,___1stD ; zmena adresy skoku instrukce Jp(...) = pro prvni symbol nelze vytvorit Zaznam ve Slovniku (protoze neexistuje predchozi symbol) - ld (_PrvniD+1),hl - exx - -RepeatD ; ziskani symbolu do DE - ld a,b ; zaloha B - ex af,af' - ld d,a ; do D pocet bitu Vystupu - xor a ; mezivysledek ziskavan do A':E - ld b,N_BITU -_Repe1D rr (hl) - rra - rr e - dec d - jp nz,_Repe2D - inc hl - ld d,8 -_Repe2D djnz _Repe1D - ld b,16-N_BITU -_Repe3D rra ; zaruceno Carry=0 - rr e - djnz _Repe3D - ld b,a - ld a,d - ld d,b ; do DE symbol - ex af,af' ; obnova B - ld b,a +SektorD di + ld sp,hl ; do SP volna pozice ve Slovniku + ld bc,BUFFER ; BC' = ukaz akt. znak Buffru + ld d,c ; do D'=C'=0 + ld hl,___1stD ; zmena adresy skoku instrukce Jp(NN) = pro prvni symbol nelze vytvorit Zaznam ve Slovniku (protoze neexistuje predchozi symbol) + ld (wPrvniD),hl + exx + +RepeatD ; ziskani symbolu do DE + ld a,b ; zaloha B + ex af,af' + ld d,a ; do D pocet bitu Vystupu + xor a ; mezivysledek ziskavan do A':E + ld b,N_BITU +_Repe1D rr (hl) + rra + rr e + dec d + jp nz,_Repe2D + inc hl + ld d,8 +_Repe2D djnz _Repe1D + ld b,16-N_BITU +_Repe3D rra ; zaruceno Carry=0 + rr e + djnz _Repe3D + ld b,a + ld a,d + ld d,b ; do DE symbol + ex af,af' ; obnova B + ld b,a SymbolD - ld a,d ; zjisteni zda symbol Ascii - or a - jr nz,_Symb2D - ld a,e ; Carry=0 = symbol znamy (zde Ascii) -_Symb1D exx ; symbol je Ascii - mozno jej do Buffru zapsat primo - ld (bc),a - jp _Vyst3D - -___1stD ; Zaznam ve Slovniku NEmozno vytvorit - ld hl,ZaznamD ; zmena adresy skoku instrukce Jp(...) = Buffer neprazdny = pro nasledujici symboly vytvareny Zaznamy ve Slovniku - ld (_PrvniD+1),hl - jp PredD - -SloPlnD ld hl,SLOVNID ; Slovnik plny - vyprazdneni - ld sp,hl ; nutno take do HL' pro pripad ze Buffer plny - jp PredD - - -_Symb2D ex de,hl ; symbol do HL - dec h ; zjisteni zda symbol znamy (tj. zda existuje zaznam ve Slovniku) - add hl,hl - add hl,hl - ;ld a,h ; H+=High(SLO_PLN) (protoze Slovnik zarovnan na $xx00) - ;add a,SLO_PLN>>8 - ;ld h,a - set 6,h ; ekvivalent k vyse zakomentovanemu protoze High(SLO_PLN)=$40 - sbc hl,sp ; urceni zda symbol znamy jako HL-SP (zaruceno Carry=0); znamy-li, Carry=0 - add hl,sp - ex de,hl ; DE = symbol reprezentujici aktualni vystup do Buffru - jp nc,VystupD ; Carry=0 = symbol je znamy - inc b ; symbol neni znamy (Carry=1) - jako ukazatel Zaznamu ve Slovniku pouzit predchozi symbol - dec b - ld a,c - jr z,_Symb1D ; je-li predchozi symbol Ascii, mozno jej do Buffru zapsat primo - push bc ; predchozi symbol zapsan do Buffru - .BYTE $3e ; meni nasledujici instrukci na "neskodnou" Ld(A,...) - -VystupD push de ; aktualni symbol zapsan do Buffru (provedeno pouze pokud symbol znamy) -_VystD exx - - ; urceni delky prefixu - posun ukazatele do Buffru (BC') o danou delku - pop hl ; prenos ukazatele Zaznamu ve Slovniku - ld d,h - ld e,l -_PrfxLn ld a,(hl) ; prefix - inc l - ld h,(hl) - ld l,a - inc bc - inc h ; protoze High(Prefix) ve Slovniku ulozeno o jednicku zmensene (jinak by nutno Or(H') a to zrusi Carry, symbol ne/znamy) - jp nz,_PrfxLn - - ; zapis do Buffru - push bc ; zaloha ukazatele do Buffru (BC') -_PrfxWr ex de,hl - ld e,(hl) ; prefix - inc l - ld d,(hl) - inc l ; znak - ld a,(hl) - ld (bc),a - dec bc - inc d ; protoze High(Prefix) ve Slovniku ulozeno o jednicku zmensene (jinak by nutno Or(D') a to zrusi Carry, symbol ne/znamy) - jp nz,_PrfxWr - ld a,e - ld (bc),a - pop bc ; obnova BC' - - -_Vyst3D ; je-li symbol NEznamy, zopakovani prvniho ("nejlevejsiho") znaku na konec Buffru - inc bc -_PrvniD jp nc,ZaznamD - ld (bc),a - inc bc - -ZaznamD ; ve Slovniku vytvoreni Zaznamu [AktPrefix,AktZnak] (pouze pokud se NEjedna o prvni zapisovany symbol do Buffru - tehdy zaruceno ze pro nej existuje predchozi symbol) - ld l,a ; sestaveni a zapis ctyrbajtoveho Zaznamu [Low(PredSymbol),High(PredSymbol),Znak,-] - push hl - exx - dec b ; High(PredSymbol) do Slovniku ulozeno o jednicku zmensene (viz duvod v PrfxLn vyse) - push bc - exx - - ; zaplnen-li Slovnik, vyprazdneni (6.bit=0 = D'>8 - bit 6,h ; ekvivalent k vyse zakomentovanemu - jr z,SloPlnD - -PredD bit 1,b ; test zaplnenosti Buffru (vyhodnoceni nize) - exx - ld b,d ; symbol aktualniho vystupu do Buffru je nyni predchozim symbolem - ld c,e - ;pop hl ; do HL aktualni bajt Vystupu (zakomentovano protoze zaruceno predchozim zpracovanim) - jp z,RepeatD ; vyhodnoceni testu zaplnenosti Buffru - - ld a,h ; zobrazeni statistiky zaplnenosti Vystupu; A = informace <0;255> - sub VYSTUP>>8 - exx - ex de,hl ; do DE' volna pozice ve Slovniku (nastaveno vyse pri testu zaplnenosti Slovniku) - call Statist - .BYTE 0 ; barva (zde Paper 0, Ink 0) - .BYTE VYS_STA ; adresa - -_SPD ld sp,$0000 ; obnova SP ($0000 = urceno za behu) - - pop hl ; do HL' logicky sektor k zapisu - push hl - call LOGFYZ ; logicky sektor v HL' na fyzickou stopu a sektor v BC' - - push de - ld hl,BUFFER ; zapis do fyzickeho sektoru BC' z adresy HL' - ld e,3 ; tri pokusy zapisu (tj. dvakrat opakovani pri chybe) - call DWRITE - call D80Err ; test pouze chyby CRC (rutina DWRITE=$23BE nezohlednuje pripravenost mechaniky) - pop de - - pop hl ; zpracovany-li vsechny sektory, dekomprese hotova - inc hl - pop bc - push bc - push hl - or a - sbc hl,bc - ex de,hl ; do HL' volna pozice ve Slovniku - jp c,SektorD + ld a,d ; zjisteni zda symbol Ascii + or a + jr nz,_Symb2D + ld a,e ; Carry=0 = symbol znamy (zde Ascii) +_Symb1D exx ; symbol je Ascii - mozno jej do Buffru zapsat primo + ld (bc),a + jp _Vyst3D + +___1stD ; Zaznam ve Slovniku NEmozno vytvorit + ld hl,ZaznamD ; zmena adresy skoku instrukce Jp(...) = Buffer neprazdny = pro nasledujici symboly vytvareny Zaznamy ve Slovniku + ld (wPrvniD),hl + jp PredD + +SlovnikPlnyD ld hl,SLOVNIK_D ; Slovnik plny - vyprazdneni + ld sp,hl ; nutno take do HL' pro pripad ze Buffer plny + jp PredD + +_Symb2D ex de,hl ; symbol do HL + dec h ; zjisteni zda symbol znamy (tj. zda existuje zaznam ve Slovniku) + add hl,hl + add hl,hl + ;ld a,h ; H+=High(SLOVNIK_PLNY) (protoze Slovnik zarovnan na $xx00) + ;add a,SLOVNIK_PLNY>>8 + ;ld h,a + set 6,h ; ekvivalent k vyse zakomentovanemu protoze High(SLOVNIK_PLNY)=$40 + sbc hl,sp ; urceni zda symbol znamy jako HL-SP (zaruceno Carry=0); znamy-li, Carry=0 + add hl,sp + ex de,hl ; DE = symbol reprezentujici aktualni vystup do Buffru + jp nc,VystupD ; Carry=0 = symbol je znamy + inc b ; symbol neni znamy (Carry=1) - jako ukazatel Zaznamu ve Slovniku pouzit predchozi symbol + dec b + ld a,c + jr z,_Symb1D ; je-li predchozi symbol Ascii, mozno jej do Buffru zapsat primo + push bc ; predchozi symbol zapsan do Buffru + .BYTE OP_LD_A_N ; meni nasledujici instrukci na "neskodnou" Ld(A,N) + +VystupD push de ; aktualni symbol zapsan do Buffru (provedeno pouze pokud symbol znamy) +_VystD exx + + ; urceni delky prefixu - posun ukazatele do Buffru (BC') o danou delku + pop hl ; prenos ukazatele Zaznamu ve Slovniku + ld d,h + ld e,l +_PrfxLn ld a,(hl) ; prefix + inc l + ld h,(hl) + ld l,a + inc bc + inc h ; protoze High(Prefix) ve Slovniku ulozeno o jednicku zmensene (jinak by nutno Or(H') a to zrusi Carry, symbol ne/znamy) + jp nz,_PrfxLn + + ; zapis do Buffru + push bc ; zaloha ukazatele do Buffru (BC') +_PrfxWr ex de,hl + ld e,(hl) ; prefix + inc l + ld d,(hl) + inc l ; znak + ld a,(hl) + ld (bc),a + dec bc + inc d ; protoze High(Prefix) ve Slovniku ulozeno o jednicku zmensene (jinak by nutno Or(D') a to zrusi Carry, symbol ne/znamy) + jp nz,_PrfxWr + ld a,e + ld (bc),a + pop bc ; obnova BC' + +_Vyst3D ; je-li symbol NEznamy, zopakovani prvniho ("nejlevejsiho") znaku na konec Buffru + inc bc + .BYTE OP_JPNC_NN +wPrvniD .WORD ZaznamD + ld (bc),a + inc bc + +ZaznamD ; ve Slovniku vytvoreni Zaznamu [AktPrefix,AktZnak] (pouze pokud se NEjedna o prvni zapisovany symbol do Buffru - tehdy zaruceno ze pro nej existuje predchozi symbol) + ld l,a ; sestaveni a zapis ctyrbajtoveho Zaznamu [Low(PredSymbol),High(PredSymbol),Znak,-] + push hl + exx + dec b ; High(PredSymbol) do Slovniku ulozeno o jednicku zmensene (viz duvod v PrfxLn vyse) + push bc + exx + + ; zaplnen-li Slovnik, vyprazdneni (6.bit=0 = D'>8 + bit 6,h ; ekvivalent k vyse zakomentovanemu + jr z,SlovnikPlnyD + +PredD bit 1,b ; test zaplnenosti Buffru (vyhodnoceni nize) + exx + ld b,d ; symbol aktualniho vystupu do Buffru je nyni predchozim symbolem + ld c,e + ;pop hl ; do HL aktualni bajt Vystupu (zakomentovano protoze zaruceno predchozim zpracovanim) + jp z,RepeatD ; vyhodnoceni testu zaplnenosti Buffru + + ld a,h ; zobrazeni statistiky zaplnenosti Vystupu; A = informace <0;255> + sub VYSTUP>>8 + exx + ex de,hl ; do DE' volna pozice ve Slovniku (nastaveno vyse pri testu zaplnenosti Slovniku) + call Statistika + .BYTE 0,STATIST_VYSTUP; barva (zde Paper 0, Ink 0) a adresa + + ld sp,(wSP) ; obnova SP + + pop hl ; do HL' logicky sektor k zapisu + push hl + call LOGFYZ ; logicky sektor v HL' na fyzickou stopu a sektor v BC' + + push de + ld hl,BUFFER ; zapis do fyzickeho sektoru BC' z adresy HL' + ld e,3 ; tri pokusy zapisu (tj. dvakrat opakovani pri chybe) + call DWRITE + call D80Err ; test pouze chyby CRC (DWRITE nezohlednuje pripravenost mechaniky) + pop de + + pop hl ; zpracovany-li vsechny sektory, dekomprese hotova + inc hl + pop bc + push bc + push hl + or a + sbc hl,bc + ex de,hl ; do HL' volna pozice ve Slovniku + jp c,SektorD