From 9d032c9a1c0eca663c6877f5421957f50cb1eb79 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Wed, 20 Jan 2016 23:46:17 -0500 Subject: rewrite sound code in asm, shed 186 bytes --- Makefile | 6 +-- soundasm.s | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++ sounds.c | 10 +++- sounds.h | 11 ---- titlecomp.pl | 20 ++++++++ titlecompression.txt | 45 ++++++++++++++++- 6 files changed, 215 insertions(+), 17 deletions(-) create mode 100644 soundasm.s diff --git a/Makefile b/Makefile index c3a46b4..6d14f27 100644 --- a/Makefile +++ b/Makefile @@ -88,8 +88,8 @@ XEX=taipan.xex # All the C and asm sources for taimain.xex: TAIMAIN_HDRS=sounds.h -TAIMAIN_C_SRC=taipan.c sounds.c -TAIMAIN_ASM_SRC=rand.s draw_lorcha.s timed_getch.s jsleep.s portstat.s clrtobot.s ultostr.s +TAIMAIN_C_SRC=taipan.c +TAIMAIN_ASM_SRC=rand.s draw_lorcha.s timed_getch.s jsleep.s portstat.s clrtobot.s ultostr.s soundasm.s # Comment these lines out to build without big number support. # This will stop being possible at some point. @@ -140,7 +140,7 @@ titledata.dat: newtitle.pl newtitle.png # compressed title, for faster loading. see titlecompression.txt # for gory details. comptitle.xex: titledata.dat titlecomp.pl comptitle.s.in - perl titlecomp.pl 151 < titledata.dat + perl titlecomp.pl 133 < titledata.dat cl65 -l comptitle.lst -o comptitle.xex -t none --asm-define destination=$(TITLE_DATA_ADDR) comptitle.s # Init segment that loads after the title screen data. It sets up diff --git a/soundasm.s b/soundasm.s new file mode 100644 index 0000000..512ec81 --- /dev/null +++ b/soundasm.s @@ -0,0 +1,140 @@ +; Sounds for Taipan! Atari 800 port. + +; Made by capturing the Apple II audio and taking wild guesses, +; then refining them. + +; I'm not shooting for Atari sounds that are identical to the +; Apple ones: (a) it's impossible anyway, and (b) the Apple +; sounds are a bit harsh to the ear. Hopefully these sound +; a little smoother while still being pretty close. + +; This is an asm rewrite of sounds.c. Sounds the same, but weighs +; in at 186 bytes less code + +; general form from sounds.c: +; for(j=0; j #include "sounds.h" -int sound_disabled = 0x06ff; +/* location we will look at, to see if sound is disabled. + 0 = enabled, 1 = disabled. If you change this here, + change it in newtitle.s also! */ +static int sound_disabled = 0x06ff; /* to build standalone xex that just plays the 3 sounds: cl65 -DTESTXEX -t atari -o sounds.xex sounds.c @@ -30,6 +36,7 @@ void jsleep(unsigned int j) { extern void __fastcall__ jsleep(unsigned int j); #endif +/* set volume 10, distortion 10 on audio channel 0 */ void init_sound(unsigned char audc1) { if(PEEK(sound_disabled)) return; @@ -39,6 +46,7 @@ void init_sound(unsigned char audc1) { POKEY_WRITE.audc1 = audc1; /* SOUND 0,x,audc1>>4,audc1&0x0f */ } +/* silence audio channel 0 */ void stop_sound(void) { POKEY_WRITE.audc1 = 0x00; /* SOUND 0,x,0,0 */ } diff --git a/sounds.h b/sounds.h index d121a70..d876aae 100644 --- a/sounds.h +++ b/sounds.h @@ -1,14 +1,3 @@ -/* location we will look at, to see if sound is disabled. - 0 = enabled, 1 = disabled. If you change this here, - change it in newtitle.s also! */ -extern int sound_disabled; - -/* set volume 10, distortion 10 on audio channel 0 */ -void init_sound(unsigned char audc1); - -/* silence audio channel 0 */ -void stop_sound(void); - /* played when something bad happens */ void bad_joss_sound(void); diff --git a/titlecomp.pl b/titlecomp.pl index 58ce0d3..a62b715 100644 --- a/titlecomp.pl +++ b/titlecomp.pl @@ -16,11 +16,31 @@ for(split //, $data) { } $firstcode = shift || 128; # must be >=128 +if($firstcode eq '-l') { + $list_codes = 1; + $firstcode = 128; + $tabsize = shift || 25; +} + for($firstcode..255) { push @available_codes, $_ unless $got{$_}; } print scalar keys %got, " unique byte values\n"; print scalar @available_codes . " available run codes >= $firstcode\n"; +if($list_codes) { + $lowest = 256; + $best = 0; +# print join("\t", @available_codes) . "\n"; + for($i = 0; $i < @available_codes - $tabsize - 1; $i++) { + $used = $available_codes[$i + $tabsize - 1] - $available_codes[$i] + 1; + if($used < $lowest) { + $lowest = $used, $best = $available_codes[$i]; + } + print $available_codes[$i] . " " . $used . "\n"; + } + print "== optimum firstcode value is $best\n"; + exit(0); +} sub allocate_code { if(!@available_codes) { diff --git a/titlecompression.txt b/titlecompression.txt index 9c30232..456ddf2 100644 --- a/titlecompression.txt +++ b/titlecompression.txt @@ -214,8 +214,49 @@ containing the table definition and the rest of the decoding code. If you look at titlecomp.pl, you'll see it takes an optional argument, forcing it to use a particular byte value as the first code value. This -number is determined by running the script repeatedly with different -arguments, to find the one with the smallest table size. +number is determined by: + +$ perl titlecomp.pl < titledata.dat +200 unique byte values +36 available run codes >= 128 +1st code 128, last 189, table size 62 +3437 bytes compressed data, 58.3% ratio +used 25 codes + +The table size worked out to 62 bytes. We can likely do better than that, +but the process isn't automated. The "used 25 codes" bit is important: +we call titlecomp.pl with that number as an argument to its -l option: + +$ perl titlecomp.pl -l 25 < titledata.dat +200 unique byte values +36 available run codes >= 128 +133 57 +147 57 +148 62 +149 65 +151 64 +154 62 +162 57 +163 67 +164 71 +166 70 +== optimum firstcode value is 133 + +So now we compress the file for real, using 133 as the first code: + +$ perl titlecomp.pl 133 < titledata.dat +200 unique byte values +36 available run codes >= 133 +1st code 133, last 189, table size 57 +3437 bytes compressed data, 58.3% ratio +used 25 codes + +Plug the number 133 into the Makefile (under the comptitle.xex target) and +we're done. Whew, that was a lot of work just to save 5 bytes... the good +news is that this procedure only needs to be repeated if newtitle.png is +edited. The other good news is, those 5 bytes wouldn't have hurt anything +anyway. Worst case scenario, they would have added 1 sector to the file +size (and made it take ever so slightly longer to load). Wait, what do I mean by smallest table size? Well, I said the table contains one entry for each byte value 0 to 255... This isn't really -- cgit v1.2.3