From 39d5e5e91eb7d858bd77ed78d4898362aa17a7cb Mon Sep 17 00:00:00 2001 From: chrisly42 Date: Wed, 28 Dec 2022 15:24:03 +0100 Subject: [PATCH] Optimized pattern / song advance code. Prepared release 1.1. --- README.md | 33 ++++--- binaries/raspberry_casket.bin | Bin 6446 -> 6228 bytes binaries/readme.txt | 4 +- example/plastic_duff.exe | Bin 6560 -> 6448 bytes example/readme.txt | 4 +- src/raspberry_casket.asm | 164 ++++++++++++++-------------------- 6 files changed, 93 insertions(+), 112 deletions(-) diff --git a/README.md b/README.md index b63ab78..b58d56b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Raspberry Casket A fast and small open source Pretracker replayer -## Raspberry Casket Player V1.0 (26-Dec-2022) +## Raspberry Casket Player V1.1 (28-Dec-2022) Provided by Chris 'platon42' Hodges @@ -83,12 +83,15 @@ The original code compressed with *Blueberry's* Shrinkler goes from 18052 bytes down to 9023 bytes. Raspberry Casket, depending on the features compiled in, is about -6374 bytes and goes down to ~4410 bytes (in isolation). +6216 bytes and goes down to ~4348 bytes (in isolation). So this means that the optimization is not just "on the outside". ### Timing +Sample generation is a bit faster (I guess around 10-15%), but most of the time is spent on muls operations, so this is the limiting factor. +Raspberry Casket is about twice as fast as the old replayer for playback. + Unfortunately, the replayer is still pretty slow and has high jitter compared to other standard music replayers. @@ -103,24 +106,30 @@ solve this problem. ### Known issues - Behaviour for undefined volume slides with both up- and down nibble specified is different (e.g. A9A, hi Rapture!). Don't do that. -- Don't use loops with odd lengths and offsets. +- Don't use loops with odd lengths and offsets (even if Pretracker allows this when dragging the loop points). - Don't stop the music with F00 and use a note delay (EDx) in the same line. - Don't try to play music with no waves, instruments or patterns. -- Shinobi seemed to have used an early beta version of Pretracker where it was possible to specify a Subloop Wait of 0. That's illegal. +- Pattern breaks with target row >= $7f will be ignored. +- Shinobi seemed to have used an early beta version of Pretracker where it was possible to specify a Subloop Wait of 0. That's illegal and unsupported. +- Pattern break (Dxx) + Song pos (Bxx) on the same line does not work in original Pretracker & Player: New Dxx position is ignored. + There is code to enable it in the player, so you could in theory make backwards running tracks like in Protracker. + But this doesn't make sense as long as the tracker itself does not support it. ## Changelog -### V1.1 (unreleased) -- Optimized base displacement by reordering variables -- Further optimized ADSR code -- Optimized wave loop code -- Bake in this strange vibrato speed multiplication to precalculated vibrato value (where possible) -- Various small optimizations -- Store instrument number * 4 on loading to avoid using two adds every frame +### V1.1 (28-Dec-22) +- Optimized base displacement by reordering variables. +- Further optimized ADSR code. +- Optimized wave loop code. +- Bake in this strange vibrato speed multiplication to precalculated vibrato value (where possible). +- Various small optimizations. +- Store instrument number * 4 on loading to avoid using two adds every frame. - Optimized speed/shuffle code. Idea of using xor turned out to make things too complicated for pattern breaks/jumps. - Rearranged code for more short branches. - Optimized track delay code further. -- Drop-in replacement code size: 6304 bytes. +- Optimized pattern / song advance code. +- Maximum jitter now about one rasterline less, average about 0.5 rasterlines less (measurements, your mileage may vary). +- Drop-in replacement code size: 6228 bytes. ### V1.0 (26-Dec-22) diff --git a/binaries/raspberry_casket.bin b/binaries/raspberry_casket.bin index 25808b166fe8280c4f00809c0bce77ef06ec9986..2f641c2070bf47d7278ba39701dcd23146f90307 100644 GIT binary patch delta 3108 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 delta 3314 zcmaJ@e{2)?75{wCXU8!nIm}_=m>(v9Lt;C>=4Q?hg718Gk_%8{M>J!o95nTdJtD-wE+_ zSs%MBP4nN5mg&yObD+^qX?Y@bLgV|x7fZYOzxdRO9Ijq*G;0v zq*?KBWV+ar`wjP4)>GrJE+Ru}fzR7FeJf}lXG6HU#M?Lbif2%8RO)*mkB;B9mfPdL}a>ph2y;Af@9S2&hP&sr>jei6T07D zT`JTHXxpbsy7eT{>)`tKAorkYB|DfKG5wlZa@S11EH0zFeON?VExSrQIS>B`6LN?7 z7nX=R@W*p^vvd8U8s^ev7S&(v&efP*gjdZSg=Kvf<%zO%by@C&xx7M5J)R(byB~aY zX$n822TIQSP@#)uMY>>crfd!5Rg&5X?F$%946)B1Wci5Az7DE2&k~fD79E>YEk$cYS;fh9bC#`RkANQwW8vwbaRIf_n z^EPiiw6Z}s4TiIkelBD(*mKVmR#XVmS8cd_7X>$;Nh-nzolkAKGB+zwevs)KcGSBcp=9yrzP9zQzoZLEUbngxtkb}qjn81+FiHd1 z5UgTvPssE{CuB;#i{qn%5XI9~tf3p+k2T23)4!N5WMA6@mtESSmb(W*_Y8Zty9`_@zc4Y{z4}xM7a?x`yVOBG^VH z)|pS88j)(rhk}F=@VcfLf*PpZl?v|cJ*3S61kc5~E%PkHFlb-i4eLBT&gav`O4)WM z8Py%hCxf4ny)JdpK2j33v;M<)VUN(n5G-xsR^Ea^!Pf$S7%OkFm-M3HDA z+>ZU^rMzF(kyq?xX*kEtB5K2L`Q}-W z2otuBN}(_)QbY}>dn-5miZFc=<5NG_#k{T`9+3GwBCsx zSnV>8UK$_4W*+(5!tNd{fI@zIF-U%+J`>hIOe%Vi7I1*RW0SpTBk?hNRzY!pU%nkG zRE5v&+L#DHxkk-^A8V|QLsMvG(TSZWoKVUq%##Y?UJuoVq49gU;pfTA$}uIx1?gAj zw36n7ytabW;1JfF!<;*V=LsL};Rf*%HBCb(DKAf{bZfcp$R>HWg7TEj=$OPt9Wz2R z;kNoXbJTipyZt}_%iWLC56pu>U;dXSfC4o_c8sY^FI9as2gKX$)ER>^VaT?c{@_tr zt0NEAC8dW}5XOLmpJVWSW#n zFn3z&=IL!artI>}Q#NJh=1>!2s+_9S%8tsx#UZYlds*tS8ux^lCX$`Od_ZcbrYy<% z0x{H3{;P&cdc?>QId4hxy~TLD-OCJZ%YuS){C7SHorVG-E~y-goQ?ExgB%Iy%B!)> zust`hcvZ(Hy)?<(5;mop$rqc0{JS%VPsv0X*KCvxaea+(UdN47?>{T`S`_81)NfVt z6!{6G-juFN^#OF{#uk@n|6%+-#nBSLwnQt<(bgONG^@7V*lqYztEW=gq0597y@LbJ zbpdp~^mMc7y3)d(h@ENe=7%`V@?q>nd7l18dh%(Xg3ct{U9=aI2X3fa-kY2K=+EfP zOSxmTwj+`~%+>buHO*YD8qN)fh1ngtIDi^MgRpK(hCd*B%9d?sdQqkeq(|AkUb`M^ z8q|icoeH*svgFmDrWf!B`jwy4HAjFOPB2cwO1H!f2iYw(@{I?rx46sR8FbR>qP1NN zaIdPXQ&u&=J)2EgoCltux;GMYWdN0-l`=o6l&p4s6^1*^J$n>AyoJFdu(o}gxCi9^ z3c7qht!Lvi-0;9kV^ZB}lfD63Nl0W0-QJIkM_z}%d#BiUp9TG}c6^Ud?|?$~BDFos zwIvxI(zIEP%-|KTA4M57#9+-0EooTVou9?;&s|hyz3p5tEPb<&XZ9g?X~})QJdXZ7 nCO3YXxx4u>haV<8L-j*NRuRxG97D0jO%=K%nBTNIH*)_0TvulK diff --git a/binaries/readme.txt b/binaries/readme.txt index cfc7dc3..6ae6124 100644 --- a/binaries/readme.txt +++ b/binaries/readme.txt @@ -1,5 +1,5 @@ This file "raspberry_casket.bin" can replace the original "player.bin" provided that you used the 16 KB + 16 KB allocation for player -variables as in the original player. +variables as in the original player (you need only about 2 + 12 KB). -It has been assembled from src/drop_in_replacement.asm (version V1.0). \ No newline at end of file +It has been assembled from src/drop_in_replacement.asm (version V1.1). \ No newline at end of file diff --git a/example/plastic_duff.exe b/example/plastic_duff.exe index 5e0e4690295a503d3a915359edc9093e1a859270..d3dd32c8b042026a6b6691b0001d5a17564786fc 100644 GIT binary patch delta 6192 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 OyfV1!-&1Cje;FZ%gcxf8 delta 6305 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 ; @@ -87,15 +87,22 @@ ; 18052 bytes down to 9023 bytes. ; ; Raspberry Casket, depending on the features compiled in, is about -; 6374 bytes and goes down to ~4410 bytes (in isolation). +; 6216 bytes and goes down to ~4348 bytes (in isolation). ; ; So this means that the optimization is not just "on the outside". ; ; Timing ; ~~~~~~ +; Sample generation is a bit faster (I guess around 10-15%), but most +; of the time is spent on muls operations, so this is the limiting +; factor. +; +; Raspberry Casket is about twice as fast as the old replayer for +; playback. +; ; Unfortunately, the replayer is still pretty slow and has high ; jitter compared to other standard music replayers. -; This means it may take up to 33 raster lines (14-19 on average) +; This means it may take up to 32 raster lines (13-18 on average) ; which is significant more than a standard Protracker replayer ; (the original one could take about 60 raster lines worst case and ; about 34 on average!). @@ -639,7 +646,7 @@ pre_FuncTable dc.l pre_PlayerInit-pre_FuncTable dc.l pre_PlayerTick-pre_FuncTable ENDC - ;dc.b '$VER: Raspberry Casket 1.0',0 + ;dc.b '$VER: Raspberry Casket 1.1',0 ;even IFNE PRETRACKER_COPPER_OUTPUT @@ -2906,29 +2913,66 @@ pre_PlayerTick: ; end of pattern loop ; ---------------------------------------- -; pattern advancing FIXME try to figure out all the cases +; Pattern advancing and pattern break and jump handling. Song looping and song-end detection. .pattern_advancing subq.b #1,pv_pat_line_ticks_b(a4) bne .no_pattern_advance ; clear note delay info - moveq.l #0,d1 + moveq.l #0,d0 REPT NUM_CHANNELS - move.b d1,pv_channeldata+pcd_note_delay_b+REPTN*pcd_SIZEOF(a4) + move.b d0,pv_channeldata+pcd_note_delay_b+REPTN*pcd_SIZEOF(a4) ENDR - move.b sv_num_steps_b(a6),d1 - subq.b #1,d1 - move.b pv_next_pat_row_b(a4),d0 - blt.s .no_pattern_break - cmp.b d0,d1 - bgt.s .has_legal_break_pos - move.b d1,d0 ; limit to last step -.has_legal_break_pos - move.b d0,pv_pat_curr_row_b(a4) + move.b sv_num_steps_b(a6),d1 ; number of steps in pattern - move.w sv_curr_pat_pos_w(a6),d3 ; go to next pattern pos - addq.w #1,d3 + move.b pv_pat_curr_row_b(a4),d0 + addq.b #1,d0 ; normal step increment + + move.w sv_curr_pat_pos_w(a6),d3 ; current song position + + move.b pv_next_pat_row_b(a4),d2 ; $ff means no pattern break + bmi.s .no_pattern_break + st pv_next_pat_row_b(a4) ; processed break, set to $ff + move.b d2,d0 + IFNE 0 ; PRETRACKER_BUGFIX_CODE ; currently disabled to keep old behaviour + moveq.l #0,d2 ; clear mask + ENDC + cmp.b d1,d0 + blo.s .has_legal_break_pos + move.b d1,d0 ; limit to last step + subq.b #1,d0 + bra.s .has_legal_break_pos + +.no_pattern_break + cmp.b d1,d0 + blo.s .pattern_end_not_reached + moveq.l #0,d0 + IFNE PRETRACKER_PARANOIA_MODE + move.b pv_loop_pattern_b(a4),d0 ; keep same pattern rolling? + bne.s .pattern_end_not_reached + ENDC +.has_legal_break_pos + addq.w #1,d3 ; pattern break will increment song pos -- if there is no new pattern position + +.pattern_end_not_reached + move.b pv_next_pat_pos_b(a4),d4 + bmi.s .no_new_position ; has a new pattern position + st pv_next_pat_pos_b(a4) + IFNE PRETRACKER_SONG_END_DETECTION + cmp.b d4,d3 + bgt.s .no_backjump + st pv_songend_detected_b(a4) ; detect jumping back +.no_backjump + ENDC + move.b d4,d3 ; load new position + IFNE 0 ; PRETRACKER_BUGFIX_CODE ; currently disabled to keep old behaviour + not.b d2 + and.b d2,d0 ; if we had NO pattern break, we will clear d0 + ELSE + moveq.l #0,d0 + ENDC +.no_new_position cmp.w sv_pat_pos_len_w(a6),d3 blt.s .no_restart_song @@ -2937,87 +2981,15 @@ pre_PlayerTick: st pv_songend_detected_b(a4) ENDC .no_restart_song - move.w d3,sv_curr_pat_pos_w(a6) - - st pv_next_pat_row_b(a4) ; processed break, set to $ff - - move.b pv_next_pat_pos_b(a4),d3 - bge.s .has_new_position ; has a new pattern position together with a break - move.b d0,d2 ; backup pv_pat_curr_row_b - cmp.b d0,d1 - ble.s .end_of_pattern_reached - bra.s .done_pat_advance - -.no_pattern_break - move.b pv_next_pat_pos_b(a4),d3 - bge.s .has_new_position - move.b pv_pat_curr_row_b(a4),d0 - move.b d0,d2 - cmp.b d1,d2 - blt.s .advancetonextpos - -.end_of_pattern_reached - clr.b pv_pat_curr_row_b(a4) - IFNE PRETRACKER_PARANOIA_MODE - move.b pv_loop_pattern_b(a4),d0 ; keep same pattern rolling? - bne .done_pat_advance - ENDC - bra.s .advance_song_pos - -.advancetonextpos - addq.b #1,d2 - move.b sv_num_steps_b(a6),d1 - addq.b #1,d0 - cmp.b d2,d1 - bgt.s .dont_go_to_top_row - moveq.l #0,d0 -.dont_go_to_top_row move.b d0,pv_pat_curr_row_b(a4) - bra.s .done_pat_advance - -.has_new_position - clr.b pv_pat_curr_row_b(a4) - IFNE PRETRACKER_PARANOIA_MODE - move.b pv_loop_pattern_b(a4),d0 - bne .no_restart_song_after_jump - ENDC - - cmp.w sv_pat_pos_len_w(a6),d3 - blt.s .set_song_pos2 - move.w sv_pat_restart_pos_w(a6),d3 - IFNE PRETRACKER_SONG_END_DETECTION - st pv_songend_detected_b(a4) - ENDC -.set_song_pos2 move.w d3,sv_curr_pat_pos_w(a6) - ; enters with d0 = 0 -.no_restart_song_after_jump - st pv_next_pat_pos_b(a4) ; processed jump, set to $ff - subq.b #1,d2 - bhi.s .done_pat_advance - clr.b pv_pat_curr_row_b(a4) - tst.b d0 - bne.s .done_pat_advance - -.advance_song_pos - move.w sv_curr_pat_pos_w(a6),d0 - addq.w #1,d0 - cmp.w sv_pat_pos_len_w(a6),d0 - blt.s .set_song_pos - move.w sv_pat_restart_pos_w(a6),d0 - IFNE PRETRACKER_SONG_END_DETECTION - st pv_songend_detected_b(a4) - ENDC -.set_song_pos - move.w d0,sv_curr_pat_pos_w(a6) -.done_pat_advance - move.b pv_pat_speed_even_b(a4),d0 - btst #0,pv_pat_curr_row_b(a4) - beq.s .set_speed_even - move.b pv_pat_speed_odd_b(a4),d0 + move.b pv_pat_speed_even_b(a4),d1 + lsr.b #1,d0 + bcc.s .set_speed_even + move.b pv_pat_speed_odd_b(a4),d1 .set_speed_even - move.b d0,pv_pat_line_ticks_b(a4) + move.b d1,pv_pat_line_ticks_b(a4) .no_pattern_advance ; ----------------------------------------