From 3c773aca8d0f886930e61e13784fb3ec87519c55 Mon Sep 17 00:00:00 2001 From: "Peter Helcmanovsky (Ped)" Date: Fri, 16 Sep 2022 02:50:23 +0200 Subject: [PATCH 1/4] z80_unpacker: add performance variant of depacker --- z80_unpacker/unpack.asm | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/z80_unpacker/unpack.asm b/z80_unpacker/unpack.asm index 6dc9097..c788a70 100644 --- a/z80_unpacker/unpack.asm +++ b/z80_unpacker/unpack.asm @@ -15,6 +15,8 @@ ;; modifies: all registers except IY, requires 10 bytes of stack space ;; +; DEFINE UPKR_UNPACK_SPEED ; uncomment to get larger but faster unpack routine + OPT push reset --syntax=abf MODULE upkr @@ -215,6 +217,10 @@ decode_bit: ld d,0 ld e,a ; DE = state_scale ; prob || (256-prob) ld l,d ; H:L = (upkr_state>>8) : 0 + + IFNDEF UPKR_UNPACK_SPEED + ;; looped MUL for minimum unpack size + ld b,8 ; counter .mulLoop: add hl,hl @@ -222,6 +228,19 @@ decode_bit: add hl,de .mul0: djnz .mulLoop ; until HL = state_scale * (upkr_state>>8), also BC becomes (upkr_state & 255) + ELSE + ;;; unrolled MUL for better performance, +25 bytes unpack size + + ld b,d + DUP 8 + add hl,hl + jr nc,000_f + add hl,de +000: + EDUP + + ENDIF + add hl,bc ; HL = state_scale * (upkr_state >> 8) + (upkr_state & 255) pop af ld d,-16 ; D = -prob_offset (-16 0xF0 when bit = 0) From b13fa05413a11686604240753f154b62bd5259ff Mon Sep 17 00:00:00 2001 From: "Peter Helcmanovsky (Ped)" Date: Sun, 18 Sep 2022 00:23:14 +0200 Subject: [PATCH 2/4] z80_unpacker: add backward variant of unpacker + example extended --- z80_unpacker/example/example.asm | 77 +++++++++++++++--- z80_unpacker/example/example.sna | Bin 49179 -> 49179 bytes .../Grongy - ZX Spectrum (2022).scr.upk | Bin 0 -> 1760 bytes .../Schafft - Poison (2017).scr.upk | Bin 0 -> 1400 bytes .../diver - Back to Bjork (2015).scr.upk | Bin 0 -> 2869 bytes ... (Forever 2014 Olympic Edition, 1).scr.upk | Bin 0 -> 4294 bytes z80_unpacker/unpack.asm | 24 ++++-- 7 files changed, 80 insertions(+), 21 deletions(-) create mode 100644 z80_unpacker/example/screens.reversed/Grongy - ZX Spectrum (2022).scr.upk create mode 100644 z80_unpacker/example/screens.reversed/Schafft - Poison (2017).scr.upk create mode 100644 z80_unpacker/example/screens.reversed/diver - Back to Bjork (2015).scr.upk create mode 100644 z80_unpacker/example/screens.reversed/diver - Mercenary 4. The Heaven's Devil (2014) (Forever 2014 Olympic Edition, 1).scr.upk diff --git a/z80_unpacker/example/example.asm b/z80_unpacker/example/example.asm index 80fd790..e3e6570 100644 --- a/z80_unpacker/example/example.asm +++ b/z80_unpacker/example/example.asm @@ -3,7 +3,8 @@ DEVICE ZXSPECTRUM48,$8FFF ORG $9000 -compressed_scr_files: ; border color byte + upkr-packed .scr file + ;; forward example data +compressed_scr_files.fwd: ; border color byte + upkr-packed .scr file DB 1 INCBIN "screens/Grongy - ZX Spectrum (2022).scr.upk" DB 7 @@ -13,37 +14,87 @@ compressed_scr_files: ; border color byte + upkr-packed .scr file DB 6 INCBIN "screens/diver - Back to Bjork (2015).scr.upk" .e: + ;; backward example data (unpacker goes from the end of the data!) +compressed_scr_files.rwd.e: EQU $-1 ; the final IX will point one byte ahead of "$" here + INCBIN "screens.reversed/diver - Back to Bjork (2015).scr.upk" + DB 6 + INCBIN "screens.reversed/diver - Mercenary 4. The Heaven's Devil (2014) (Forever 2014 Olympic Edition, 1).scr.upk" + DB 0 + INCBIN "screens.reversed/Schafft - Poison (2017).scr.upk" + DB 7 + INCBIN "screens.reversed/Grongy - ZX Spectrum (2022).scr.upk" +compressed_scr_files.rwd: ; border color byte + upkr-packed .scr file (backward) + DB 1 start: di ; OPT --zxnext -; nextreg 7,3 ; ZX Next: switch to 28Mhz - ld ix,compressed_scr_files -.slideshow_loop +; nextreg 7,3 ; ZX Next: switch to 28Mhz + + ;;; FORWARD packed/unpacked data demo + ld ix,compressed_scr_files.fwd +.slideshow_loop.fwd: ; set BORDER for next image - ldi a,(ix) ; fake: ld a,(ix) : inc ix + ld a,(ix) + inc ix out (254),a ; call unpack of next image directly into VRAM - ld de,$4000 ; target VRAM + ld de,$4000 ; target VRAM exx ; IX = packed data, DE' = destination ($4000) ; returned IX will point right after the packed data - call upkr.unpack + call fwd.upkr.unpack ; do some busy loop with CPU to delay between images + call delay + ; check if all images were displayed, loop around from first one then + ld a,ixl + cp low compressed_scr_files.fwd.e + jr nz,.slideshow_loop.fwd + + ;;; BACKWARD packed/unpacked data demo + ld ix,compressed_scr_files.rwd +.slideshow_loop.rwd: + ; set BORDER for next image + ld a,(ix) + dec ix + out (254),a + ; call unpack of next image directly into VRAM + ld de,$5AFF ; target VRAM + exx + ; IX = packed data, DE' = destination + ; returned IX will point right ahead of the packed data + call rwd.upkr.unpack + ; do some busy loop with CPU to delay between images + call delay + ; check if all images were displayed, loop around from first one then + ld a,ixl + cp low compressed_scr_files.rwd.e + jr nz,.slideshow_loop.rwd + + jr start + +delay: ld bc,$AA00 .delay: .8 ex (sp),ix dec c jr nz,.delay djnz .delay - ; check if all images were displayed, loop around from first one then - ld a,ixl - cp low compressed_scr_files.e - jr z,start - jr .slideshow_loop + ret ; include the depacker library, optionally putting probs array buffer near end of RAM DEFINE UPKR_PROBS_ORIGIN $FA00 ; if not defined, array will be put after unpack code - INCLUDE "../unpack.asm" + + MODULE fwd + INCLUDE "../unpack.asm" + ENDMODULE + + MODULE rwd + DEFINE BACKWARDS_UNPACK ; defined to build backwards unpack + ; initial IX points at last byte of compressed data + ; initial DE' points at last byte of unpacked data + + INCLUDE "../unpack.asm" + ENDMODULE SAVESNA "example.sna",start diff --git a/z80_unpacker/example/example.sna b/z80_unpacker/example/example.sna index a1f9f56b4e1b2fcf97dd33ac8ef27758dea43e6a..78df3d8a2cf9da82d8237271b0d006240e53706b 100644 GIT binary patch delta 10753 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 diff --git a/z80_unpacker/example/screens.reversed/Grongy - ZX Spectrum (2022).scr.upk b/z80_unpacker/example/screens.reversed/Grongy - ZX Spectrum (2022).scr.upk new file mode 100644 index 0000000000000000000000000000000000000000..0e8777ca71bea9bd53ddb8b703f453a8566c2f0f GIT binary patch literal 1760 zcmV<61|RuAL&E+wP`Njy?RTOVMy1>6$+CyhG3WJ)#NizUu%54!cWJ;$uhuuaiSF%W zL|};2iLmOA*Ip4R+*yZItYx*iUMl*y>CS2Si-66DbKtU~ImPqSU+sR98aKsus{ni$ z%yt*Jg?TUMyc#G{wW)0@a)yX=erljZx1y54=_W)buAlBTrW{~zKl;aN_OGW-MH0%I zhYUp`HlKWFJIf#NS7s3#u}KcG*o((T`x;t3`%xq=J`_ZE=d2vXu+2o_l_Cvj(=0AZ znKowV-UF=+LVFVVG<&pC_=0#WKNAqOE_|a9IanPay!n*k^MExYpGF>p;l^tCybOT4c=p1t=AG0JX8c4v@v776OHKF$KQ6R|glS z6oYh_-QRZ_OJY|=M=}y`GXDAgdWZyow9>S&CW(Z;O+DT4Yu#bd=VPKI)1p$cvxhdu za`^>6$vwJNu`64`4CdGRzt!T}9aKcH#Ii@5BzwIxlN5S6acdV#(`Q!A74VvB%Po4{ zQi$T!!6nu2TZg$-5Bb16=2w_n#M(AjOdWzX>jn;f(pfGTC)(_~!%+t*7L5Q{qeTAm znI^qYG2AF=SC^*&!40W68tDX#o5Ir}MGP3VaHZTcC*t&5B`D83elxgQ7T@WSIuulE0Ai+KSg8$`pQT%|u2LE3Ggp5QR-hOj z0Tx1}p?4;wX?<&$i!ig#EMzA($FokzlG51J^NE5$Fj+jIXvO5PN`e&>O zB-nqsPJA?Dvx&R3k)ka#Yezy+n3BZ~K#}$xtD!C(TsQ&Jok=)`awrDw8j9bd38o67H& zT3cFidN(G_k=>u(> z*eU%X-150r2ssouZRKS^w0;27UoAV#*0d6-1P?}haiTs3Dv;_V!EnHJF`aJ@6IV{O`*?XxawGbR~>= z4IOxT6K3P4|Gd-?HBzI!`7VZOKUqNlLBF)H@?a&<0%X(J)*I2Pxj8Fkjyhc>8oo_A znq+F?RxDmblNtDxdQrsGIBLB4`k4%$FLsowQ3{tZPZhvsRsAh=HMeT;$t_sq6=K#2 z5-v6o$zjy-O{WN8(G1H>^!CjJ#r-FJ`F^C#n4vMLmh$LZXZvPV?~Nf3p^bTSR|xC2#4|`U5*c4 zWP2I;A$+U$&T>-3w4m=kcx;&91&_7Rbquy?=HWR5%HKY%HglT7xa8+MX*NJS6&=87 z$Vcp07ux#AdZj|-E93Rmpp9%oLps)@%E(&|u10x!U57Jd`G^k^df#Y^Qgyo!RQO3~ zKF-{KNf5MSs{r`k%|=bemqDM8*%>w-u?$SX_P)3$36GlHSQPodu5~d0KP>gQ^ zbC5*Zf3Ef(iXfZu@U1ZCDu&rRNfa)l*8TAQOx7QPamgYth%_#iV?%DAbWr~OV?7t+)3mM@&YSjrOb!-plQ}<0J^Z1tk+%ht@g?Rc)y@eNM~^BUR%u zg%SgAZGJ=ExC4X=I3=C&{nG?G^WM>{thx{PiK{2nXR~?whT(b@xa!+qP}tF>a|{CI CiDSY5 literal 0 HcmV?d00001 diff --git a/z80_unpacker/example/screens.reversed/Schafft - Poison (2017).scr.upk b/z80_unpacker/example/screens.reversed/Schafft - Poison (2017).scr.upk new file mode 100644 index 0000000000000000000000000000000000000000..32f540144e1f9afba3a593429cbbbfc19b19a5f8 GIT binary patch literal 1400 zcmV-;1&8`T=q>8Yw7aFTw3lEQq`9S}%^d3TZ*uZ*ow6A+9w^ntD>58yG&LZ4ikwpi z{~Pihe1q{k})!dLC5{Ji}e7g3OA95IQVIeTVor=wqNY`f_ zljmONA^j0Z^mh0k%ikjQbKLJSO0w4a@@U})CwRClR!JqSWSD#2dd_(M3zPi)XyXpU z_D#1j#!xBir{j4mI8Ilu3dco?2is*rx;jhFJ6j=>4$d0c;z$TN8MOGgH*(I$lN5k& zp)@1SnYh91`2f~h11ebbVpjrJOMauuY;%(m4MRhAgoO-TeNsPXS`28HdQ?D>#Fj9I zmUYei1K9NG?n>MqrR~d$fFOCR!1C&IfWVU2W$ESupkpe7<{rbFOS+)#<tC;1 zAm$awFn0~in&i9&lAff#S0P1EfvY5youldw9-pZ_hquYG0x@KMp?|rB zAMKAijt7VF)%?!snxz@edgRrLFgfr?lcA+-r8s_6aJ)mV&Pgg>MM4Yg*meHuF+fU= zt_HQ_3w`^;pv73$Xqi(_$>t$4jO^mS+0&Z0n`pBh%22P?lX>UYwop(=zW+8g zoD5#Fn0>qf9)iRJc?>A9)%QxnT6nkZ*F_Yp13GFrh@mjsJn5LMH)w(UwurZg`Bn*Y zlu7uXL=inmqXEs}6$ljig}~b;Qh(PkWJ}o;VZzYWaN=K2X#w* zyqG=y+8AGqViHRidL{;TO~7stOplJ(^hhdf308+yNgCSWaSF1ui-NT&5{QMAEI9(! zU(yAkB#Vv}%3eE6TL!QqCFwtm{7iQLQDhOfdyZki671(XR6@y7dv& G^ABeJ>${@> literal 0 HcmV?d00001 diff --git a/z80_unpacker/example/screens.reversed/diver - Back to Bjork (2015).scr.upk b/z80_unpacker/example/screens.reversed/diver - Back to Bjork (2015).scr.upk new file mode 100644 index 0000000000000000000000000000000000000000..423885a734913b562da69b2de445e22139268d87 GIT binary patch literal 2869 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 some bits + stop bit still available ; CF=1 (by stop bit) ld a,(ix) - inc ix ; upkr_current_byte = *upkr_data_ptr++; + IFNDEF BACKWARDS_UNPACK : inc ix : ELSE : dec ix : ENDIF ; upkr_current_byte = *upkr_data_ptr++; adc a,a ; CF=data, b0=1 as new stop bit .has_bit: adc hl,hl ; upkr_state = (upkr_state << 1) + (upkr_current_byte >> 7); @@ -306,12 +314,12 @@ decode_number: ; reserve space for probs array without emitting any machine code (using only EQU) IFDEF UPKR_PROBS_ORIGIN ; if specific address is defined by user, move probs array there - ORG UPKR_PROBS_ORIGIN +probs: EQU ((UPKR_PROBS_ORIGIN) + 255) & -$100 ; probs array aligned to 256 + ELSE +probs: EQU ($ + 255) & -$100 ; probs array aligned to 256 ENDIF - -probs: EQU ($+255) & -$100 ; probs array aligned to 256 -.real_c: EQU 1 + 255 + 1 + 2*NUMBER_BITS ; real size of probs array -.c: EQU (.real_c + 1) & -2 ; padding to even size (required by init code) +.real_c: EQU 1 + 255 + 1 + 2*NUMBER_BITS ; real size of probs array +.c: EQU (.real_c + 1) & -2 ; padding to even size (required by init code) .e: EQU probs + .c DISPLAY "upkr.unpack probs array placed at: ",/A,probs,",\tsize: ",/A,probs.c From d4bce4bf7cb1095a797ca5853c0c01fcba4f603f Mon Sep 17 00:00:00 2001 From: "Peter Helcmanovsky (Ped)" Date: Sun, 18 Sep 2022 22:54:10 +0200 Subject: [PATCH 3/4] z80_unpacker: optimisation: -3B and ~-10T in decode_bit = 174B unpack zx48.rom is now ~22.6s (from 23.0s) (performance version is now 199 bytes, zx48.rom unpack 19.4s -> 19.0s) --- z80_unpacker/example/example.sna | Bin 49179 -> 49179 bytes z80_unpacker/unpack.asm | 31 +++++++++++++++---------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/z80_unpacker/example/example.sna b/z80_unpacker/example/example.sna index 78df3d8a2cf9da82d8237271b0d006240e53706b..515f5d68690562b02a92e501cbcea636569d53df 100644 GIT binary patch delta 175 zcmbQ;z&yKwd4u>u#tV}r7KZU{eJEYE`NZ4c^oM*3XSYtSS!ge8z$7XeFaPY1yuAFm z50l@z9As*md~uD(w zP|{@GMM_Mnk0vi%C}n`fyo)CV|JO@!f=!b;Ee)bAKG~lJGA(|d+^G0Ve51i5mdPdi GmjeKk{!YRG delta 167 zcmbQ;z&yKwd4u>u#>7KZWdcqm=9`NZ4c^oM*3XLn4lS!gdN_Q8NTKvgpS*$;Uj z=z8nYe2}The)74620BWQEChJYDm^+aXz;W0rjYc_0Ew3sEW55KJu=|oIh*kaVwS`s upjjD{wH7HcX*`;|aG{h2b|WvI6#QQ=!3j1{>a;YF-rT$Bq0Hox{mTKZu}H!I diff --git a/z80_unpacker/unpack.asm b/z80_unpacker/unpack.asm index b7e5120..b1bcbce 100644 --- a/z80_unpacker/unpack.asm +++ b/z80_unpacker/unpack.asm @@ -250,27 +250,26 @@ decode_bit: ENDIF add hl,bc ; HL = state_scale * (upkr_state >> 8) + (upkr_state & 255) - pop af - ld d,-16 ; D = -prob_offset (-16 0xF0 when bit = 0) + pop af ; restore prob and CF=bit jr nc,.bit_is_0_2 - ld d,b ; D = -prob_offset (0 when bit = 1) (also does fix following ADD) - dec h - add hl,de ; HL += -prob (HL += (256 - prob) - 256) -.bit_is_0_2: ; HL = state_offset + state_scale * (upkr_state >> 8) + (upkr_state & 255) ; new upkr_state + dec d ; DE = -prob (also D = bit ? $FF : $00) + add hl,de ; HL += -prob + ; ^ this always preserves CF=1, because (state>>8) >= 128, state_scale: 7..250, prob: 7..250, + ; so 7*128 > 250 and thus edge case `ADD hl=(7*128+0),de=(-250)` => CF=1 +.bit_is_0_2: ; *** adjust probs[context_index] - ld e,a ; D:E = -prob_offset:prob, A = prob - and $F8 + ld e,a ; preserve prob + rra ; + (bit<<4) ; part of -prob_offset, needs another -16 + and $FC ; clear/keep correct bits to get desired (prob>>4) + extras, CF=0 rra rra - rra - rra - adc a,d ; A = -prob_offset + ((prob + 8) >> 4) - neg - add a,e ; A = prob_offset + prob - ((prob + 8) >> 4) + rra ; A = (bit<<4) + (prob>>4), CF=(prob & 8) + adc a,-16 ; A = (bit<<4) - 16 + ((prob + 8)>>4) ; -prob_offset = (bit<<4) - 16 + sub e ; A = (bit<<4) - 16 + ((prob + 8)>>4) - prob ; = ((prob + 8)>>4) - prob_offset - prob + neg ; A = prob_offset + prob - ((prob + 8)>>4) pop bc - ld (bc),a ; update probs[context_index] - add a,d ; bit=0: A = 23..249, D = 240 -> CF=1 || bit=1: D=0 -> CF=0 - ccf ; resulting CF = bit restored + ld (bc),a ; probs[context_index] = prob_offset + prob - ((prob + 8) >> 4); + add a,d ; restore CF = bit (D = bit ? $FF : $00 && A > 0) pop de ret From 165f593a11f176c544cfda0a6dcd9614d47671d1 Mon Sep 17 00:00:00 2001 From: "Peter Helcmanovsky (Ped)" Date: Sun, 18 Sep 2022 23:04:37 +0200 Subject: [PATCH 4/4] z80_unpacker: (codestyle) whitespace + temporary label rename --- z80_unpacker/unpack.asm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/z80_unpacker/unpack.asm b/z80_unpacker/unpack.asm index b1bcbce..26e47b7 100644 --- a/z80_unpacker/unpack.asm +++ b/z80_unpacker/unpack.asm @@ -227,8 +227,8 @@ decode_bit: ld l,d ; H:L = (upkr_state>>8) : 0 IFNDEF UPKR_UNPACK_SPEED - ;; looped MUL for minimum unpack size + ;; looped MUL for minimum unpack size ld b,8 ; counter .mulLoop: add hl,hl @@ -236,15 +236,16 @@ decode_bit: add hl,de .mul0: djnz .mulLoop ; until HL = state_scale * (upkr_state>>8), also BC becomes (upkr_state & 255) - ELSE - ;;; unrolled MUL for better performance, +25 bytes unpack size + ELSE + + ;;; unrolled MUL for better performance, +25 bytes unpack size ld b,d DUP 8 add hl,hl - jr nc,000_f + jr nc,0_f add hl,de -000: +0: EDUP ENDIF