diff options
| author | Javier Degirolmo | 2012-08-27 07:58:24 -0300 |
|---|---|---|
| committer | Javier Degirolmo | 2012-08-27 07:58:24 -0300 |
| commit | 6266e3e5577bc7c11d300a873c150b6a7900376a (patch) | |
| tree | 82b14ee437f6f802cd5cd896dd66c58c29ea7ec0 | |
| parent | 2f83b4822b5825d58ab4a74e4e9e5f0be2cc78f2 (diff) | |
Fuck it, we're doing it live
| -rw-r--r-- | README | 166 | ||||
| -rw-r--r-- | built/old/echo-timer-version-a.bin (renamed from built/echo-timer-version-a.bin) | bin | 32768 -> 32768 bytes | |||
| -rw-r--r-- | built/old/echo-timer-version-b.bin (renamed from built/echo-timer-version-b.bin) | bin | 32768 -> 32768 bytes | |||
| -rw-r--r-- | built/old/echo-timer-version-c.bin (renamed from built/echo-timer-version-c.bin) | bin | 32768 -> 32768 bytes | |||
| -rw-r--r-- | built/old/echo-timer-version-d.bin (renamed from built/echo-timer-version-d.bin) | bin | 32768 -> 32768 bytes | |||
| -rw-r--r-- | c/LICENSE | 17 | ||||
| -rw-r--r-- | c/README | 100 | ||||
| -rw-r--r-- | c/echo.c | 6 | ||||
| -rw-r--r-- | c/echo.h | 9 | ||||
| -rw-r--r-- | c/echoblob.h | 482 | ||||
| -rw-r--r-- | doc/api-asm.68k | 104 | ||||
| -rw-r--r-- | doc/api-c.txt | 120 | ||||
| -rw-r--r-- | doc/eef.txt | 35 | ||||
| -rw-r--r-- | doc/eif.txt | 27 | ||||
| -rw-r--r-- | doc/esf.txt | 355 | ||||
| -rw-r--r-- | doc/ewf.txt | 15 | ||||
| -rw-r--r-- | src-68k/echo.68k | 102 | ||||
| -rw-r--r-- | src-z80/core/main.z80 | 78 |
18 files changed, 1058 insertions, 558 deletions
@@ -1,101 +1,97 @@ -***************************************************************************** -JUST TO MAKE IT CLEAR: THE TEXT BELOW IS NOT LEGAL BINDING, IT'S JUST A -WARNING THAT ECHO ISN'T STABLE, OK? THE PROPER LICENSE IS ZLIB'S AND THAT'S -WHAT YOU SHOULD CONSIDER. - -To see the license, check the LICENSE file. (to-do: add the notice to the -source files - license is still relevant!) -***************************************************************************** - _ _ _ _____ _____ _ _ _ _ _ _____ -| | | | | | | _ | | _ | | \ | | | | | \ | | | ___| -| | | | | | | |_| | | |_| | | \| | | | | \| | | | __ -| | | | | | | _ | | _| | | | | | | | || | -| |_| |_| | | | | | | |\ \ | |\ | | | | |\ | | |_| | -|____.____| |_| |_| |_| \_\ |_| \_| |_| |_| \_| |___._| - -This is NOT a final version. This version is quite stable right now, and -conversion tools will cope up with any shenanigans that can happen due to -currently undefined behavior, but don't get surprised if something ends up -being broken. - -tl;dr use Echo at your own risk :| - ------------------------------------------------------------------------------ - -If you want to use Echo from asm, take the blob from "bin/prog-z80.bin" and +============================================================================= + ___________ ________ ___ ___ _________ + | _______| _| ___ |_ | | | | _| _____ |_ + | | _| _| |___| | | | | | | | | + | |_____ | | | |_____| | | | | | + | _____| | | | _____ | | | | | + | | |_ |_ ___ | | | | | | | | + | |_______ |_ |___| _| | | | | |_ |_____| _| + |___________| |________| |___| |___| |_________| + ___ ___ _ _ ___ __ ___ ___ ___ _ ___ ___ _ ___ + | _| | | | | \ | _| | _| | | _| | | | | + | |_| | | | | | | | | | |_| | | |_| | | | |_ _ _ ___ ___ | | | | | + |_ | | | | | | | | | | _| | | | | | | | _| | | | __| _ \ | | | | | + _| | | | | | | | | | | |_| | | | | | | | |_ | | | __| /_ | |_| | | + |___|___|___|_|_|__/ |___|_|_|___|_|_|_|___| \_/|___|_|_\_| |_|_|___| + +============================================================================= + +Echo is available under the zlib license. Please see the LICENSE file for +details. All files here as-is are made available under that license unless +explicitly stated otherwise. + +Echo official "site" (currently redirects to the repo): +http://echo.mdscene.net/ + +mdtools repo (includes several tools for use with Echo): +http://tools.mdscene.net/ + +Some more tools from Oerg866 (XM to ESF converter and ESF optimizer): +https://github.com/oerg866/xm2esf + +============================================================================= + +*** How to use *** + +If you want to use Echo from asm, take the blob from "built/prog-z80.bin" and the "src-68k/echo.68k" asm file. Include the latter in your source code, then -go to the @Z80Program label and replace the string with the path to the blob. +go to the @Z80Program label (should be near the end of the file) and replace +the string with the path to the blob. If you want to use Echo from C, check the "c" subdirectory. You will find the required files. It should work with any Mega Drive C devkit that provides the stdint.h header (and you should ditch it if it doesn't!). ------------------------------------------------------------------------------ +The documentation for the asm API is in "doc/api-asm.txt", while the +documentation for the C API is in "doc/c-api.txt". -Echo official "site" (currently just redirects to the git repo): -http://echo.mdscene.net/ +============================================================================= -Echo tools are available as part of the mdtools set: -https://github.com/sikthehedgehog/mdtools +*** How to build *** -Also Oerg made a xm2esf tool, and an ESF optimization tool: -https://github.com/oerg866/xm2esf + * Make sure the root of this source code tree is the current directory + * Assemble src-z80/build.z80 to bin/prog-z80.bin + * Assemble tester/build.68k to bin/prog-68k.bin (optional) ------------------------------------------------------------------------------ +Sorry for not providing a build script but my current setup is a mess and +needs to be changed x_x; Currently using z80-asm to build the Z80 code and +asm68k to build the 68000 code, I need to find good replacements for both +(z80-asm for being crappy, asm68k for not being free). -Current version: 0.9 +Also no source for the data blobs yet, for similar reasons, although I have +more control over those tools at least so I may come up with some good +replacements (or even just rebuild the current tools, pretty sure one of them +(mdtiler) already has a replacement) :/ - And yes, I know the source code is a mess, I need to clean it up severely. - Also I know some stuff could be done better (e.g. buffering PCM instead of - reading each byte from ROM every time), but leaving that for after the - first official release, don't fix what isn't broken -_-' +The last step builds the Echo tester ROM, which is some generic ROM I use to +test the tools and some other stuff I make, and generally contains garbage +tunes in it you shouldn't pay attention to. You don't have to build it to +make use of Echo :P ------------------------------------------------------------------------------ +============================================================================= -How to build: +*** Making sound effects *** - * Make sure the root of this source code tree is the current directory - * Assemble src-z80/build.z80 to bin/prog-z80.bin - * Assemble tester/build.68k to bin/prog-68k.bin (optional) +If you are using assembly and don't feel like using the full-blown tools to +make sound effects, you can use the macros in the "src-68k/esf.68k" file to +create sound effects. For now there is not documentation for it :/ (check the +comments in the source file to see the syntax for each macro) + +An equivalent C API may be available in the future. + +============================================================================= + +CREDITS: + + Main programmer ........ Sik + Auxiliary programmer ... Oerg866 + +THANKS FOR TESTING: + + * TµEE (general hardware testing) + * Eke Eke (timer shenanigans IIRC?) + * MarkeyJester (*insert comment here*) + * John Springer (you heart his pizza) + * Flygon (sorry for your headphones :P) - Sorry for not providing a build script but my current setup is a mess and - needs to be changed x_x; Currently using z80-asm to build the Z80 code and - asm68k to build the 68000 code, I need to find good replacements for both - (z80-asm for being crappy, asm68k for not being free). - - Also no source for the data blobs yet, for similar reasons, although I - have more control over those tools at least so I may come up with good - replacements (or even just rebuild the current tools, pretty sure one of - them (mdtiler) already has a replacement) :/ - - The last step builds the Echo tester ROM, which is some generic ROM I use - to test the tools and some other stuff I make, and generally contains - garbage tunes in it you shouldn't pay attention to. You don't have to - build it to make use of Echo :P - ------------------------------------------------------------------------------ - -Available builds: - - built/prog-z80.bin - Current build of Echo. - - built/echo-timer-version-a.bin - Timer test. Both timers get reloaded each time they're fired. - built/echo-timer-version-b.bin - Timer test. Only timer B is reloaded when it fires, timer A is left to - loop on its own. - built/echo-timer-version-c.bin - Timer test. Both timers are left to loop on their own. Code for - initializing timer B is wrong so it doesn't work properly. - built/echo-timer-version-d.bin - What the previous ROM should have been, fixed timer B :| - ------------------------------------------------------------------------------ - -Credits: - - - Sik (main programmer) - - Oerg866 (bug hunter) - -Testing: TµEE, Eke Eke, MarkeyJester, John Springer, Flygon +============================================================================= diff --git a/built/echo-timer-version-a.bin b/built/old/echo-timer-version-a.bin Binary files differindex cf637f5..cf637f5 100644 --- a/built/echo-timer-version-a.bin +++ b/built/old/echo-timer-version-a.bin diff --git a/built/echo-timer-version-b.bin b/built/old/echo-timer-version-b.bin Binary files differindex 2c2df59..2c2df59 100644 --- a/built/echo-timer-version-b.bin +++ b/built/old/echo-timer-version-b.bin diff --git a/built/echo-timer-version-c.bin b/built/old/echo-timer-version-c.bin Binary files differindex 0459b30..0459b30 100644 --- a/built/echo-timer-version-c.bin +++ b/built/old/echo-timer-version-c.bin diff --git a/built/echo-timer-version-d.bin b/built/old/echo-timer-version-d.bin Binary files differindex bf92e9b..bf92e9b 100644 --- a/built/echo-timer-version-d.bin +++ b/built/old/echo-timer-version-d.bin diff --git a/c/LICENSE b/c/LICENSE deleted file mode 100644 index 05d9fdb..0000000 --- a/c/LICENSE +++ /dev/null @@ -1,17 +0,0 @@ -© 2010-2012 Javier Degirolmo - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. diff --git a/c/README b/c/README deleted file mode 100644 index 63a0c59..0000000 --- a/c/README +++ /dev/null @@ -1,100 +0,0 @@ -Quick readme that's going to be here until proper documentation is made. - -Echo is licensed under the zlib license. Feel free to use it as long as you -don't claim you made Echo (no credit needed though). If you modify it don't -claim it's vanilla Echo either :P - -THIS CODE HAS NOT BEEN TESTED YET. I CURRENTLY DON'T HAVE ANY C DEVKIT TO -VERIFY IT WORKS FINE. I HAVE DONE AS MANY CHECKS AS POSSIBLE (AND IT -DEFINITELY SHOULD BUILD) BUT I NEED REPORTS TO KNOW IF IT'S WORKING AS -EXPECTED. SORRY FOR THE INCONVENIENCE. - -============================================================================= - -To include Echo in your program, you need to include echo.c, echo.h and -echoblob.h in it (and yes, you can put echo.h as a system file if you want). -That's pretty much it. - -To access the Echo stuff, include echo.h in the source files that need to -make use of it. It contains all the function definitions and such, as well as -the macros needed to make the instrument list. - -echoblob.h is already included here, but if you want to use a different Z80 -blob from the included one, you can use the blob2c tool. It's a command line -tool and its usage is pretty simple: blob2c «input.bin» «output.c» - -============================================================================= - -Echo makes use of an instrument list. In the case of the C version of Echo, -you need to make a null-terminated pointer list, e.g. as follows: - -const void *list[] = { - instrument1, - instrument2, - instrument3, - instrument4, - instrument5, - NULL -}; - -Where 'list' is the name the list will have. This is the same name you have -to pass to echo_init(). 'instrument1' etc. are pointers to the data of each -instrument (EIF, EEF, EWF). - -If NULL isn't defined for whatever reason either include stddef.h or just use -0 instead (which is the same value). - -============================================================================= - -Quick overview of the functions. The functions map 1:1 to their asm -counterparts, by the way. - - echo_init(list) - - Initializes Echo. 'list' is a pointer to the instrument list (pass here - the name you passed to ECHO_LIST_START). Make sure to call this before - doing anything else with Echo. - - echo_play_bgm(stream) - - Plays background music. 'stream' is a pointer to the ESF data. - - echo_stop_bgm() - - Stops background music playback. - - echo_resume_bgm() - - Resumes background music playback (useful for unpausing). - - echo_play_sfx(stream) - - Plays a sound effect. 'stream' is a pointer to the ESF data. - - echo_stop_sfx() - - Stops sound effect playback. - - echo_get_status() - - Gets the current status of Echo. It returns a value which is an OR of - the following flags (as appropriate): - - ECHO_STAT_BGM .... Background music is playing - ECHO_STAT_SFX .... Sound effect is playing - ECHO_STAT_BUSY ... Echo is busy (can't parse commands yet) - - And just to make it clear: if you send a command to Echo while it's - busy, it won't fail, it'll just make the 68000 wait until Echo is - ready. No need to explicitly check for it. Check this only if you want - to prevent the 68000 waiting. - - echo_send_command(command) - - Lets you send a raw command to Echo. Use this for commands not taking - parameters. - - echo_send_command_ex(command, address) - - Lets you send a raw command to Echo. Use this for commands that take an - address as a parameter. @@ -77,7 +77,7 @@ void echo_init(const void **list) { // param cmd: command to send //*************************************************************************** -void echo_send_command(unsigned char cmd) { +void echo_send_command(uint8_t cmd) { // We need access to Z80 bus Z80_REQUEST(); @@ -104,7 +104,7 @@ void echo_send_command(unsigned char cmd) { // param addr: address parameter //*************************************************************************** -void echo_send_command_ex(unsigned char cmd, const void *addr) { +void echo_send_command_ex(uint8_t cmd, const void *addr) { // Since we need to split the address into multiple bytes we put it in an // integer. This is a bad practice in general, period, but since we don't // care about portability here we can afford to do it this time. @@ -190,7 +190,7 @@ void echo_stop_sfx(void) { // return: status flags (see ECHO_STAT_*) //*************************************************************************** -unsigned short echo_get_status(void) { +uint16_t echo_get_status(void) { // We need access to the Z80 Z80_REQUEST(); @@ -1,6 +1,9 @@ #ifndef ECHO_H #define ECHO_H +/* Required headers */ +#include <stdint.h> + /* Echo commands */ enum { ECHO_CMD_NONE, /* 0x00 - No command */ @@ -24,8 +27,8 @@ void echo_stop_bgm(void); void echo_resume_bgm(void); void echo_play_sfx(const void *); void echo_stop_sfx(void); -unsigned short echo_get_status(void); -void echo_send_command(unsigned char); -void echo_send_command_ex(unsigned char, const void *); +uint16_t echo_get_status(void); +void echo_send_command(uint8_t); +void echo_send_command_ex(uint8_t, const void *); #endif diff --git a/c/echoblob.h b/c/echoblob.h index 90871c2..0ac0d1b 100644 --- a/c/echoblob.h +++ b/c/echoblob.h @@ -11,247 +11,247 @@ static uint8_t echo_blob[] = { 180,221, 54, 3,192,221, 54, 2,181,221, 54, 3,192,221, 54, 2, 182,221, 54, 3,192,221, 54, 0, 36,221, 54, 1,254,221, 54, 0, 37,221, 54, 1, 3,221, 54, 0, 38,221, 54, 1,201,221, 54, 0, - 39,221, 54, 1, 63,195,242, 0, 61,202, 70, 1, 61,202, 19, 5, - 61,202, 56, 6, 61,202,197, 2, 61,202, 69, 4, 61,202, 22, 3, - 58, 0, 64, 15,220, 65, 2,175, 50,255, 31, 58, 0, 64, 15,220, - 65, 2, 58,255, 31,183, 32,208, 58, 0, 64, 15,220, 65, 2, 58, - 0, 64,203, 79, 32, 8,203, 71,196, 65, 2,195,242, 0,221,126, - 0,203, 71,196, 65, 2,221, 54, 0, 39,221, 54, 1, 47, 58, 0, - 64, 15,220, 65, 2,195, 40, 1, 58, 0, 64, 15,220, 65, 2,195, - 50, 1, 58, 0, 64, 15,220, 65, 2,195, 0, 12, 58, 0, 64, 15, - 220, 65, 2,195,242, 0, 33,252, 31, 78, 44, 94, 44, 86,235,175, - 50,255, 31,121, 17, 0, 96,235,119, 15,119, 15,119, 15,119, 15, - 119, 15,119, 15,119,117, 15,119,235, 17, 0, 28,126,183,202,210, - 1, 18, 20, 44, 32, 25, 36, 32, 22, 12,121, 38, 96,119, 15,119, - 15,119, 15,119, 15,119, 15,119, 15,119,117, 15,119, 38,128,126, - 18, 20, 44, 32, 25, 36, 32, 22, 12,121, 38, 96,119, 15,119, 15, - 119, 15,119, 15,119, 15,119, 15,119,117, 15,119, 38,128,126, 18, - 21, 21, 28, 44, 32, 25, 36, 32, 22, 12,121, 38, 96,119, 15,119, - 15,119, 15,119, 15,119, 15,119, 15,119,117, 15,119, 38,128,195, - 108, 1,121, 50,140, 17,195,242, 0, 58,140, 17,185,202,246, 1, - 121, 50,140, 17,217,119, 15,119, 15,119, 15,119, 15,119, 15,119, - 15,119,117, 15,119,217, 70, 44,194, 2, 2, 36,194, 2, 2, 38, - 128, 12,201,205, 29, 2,195,140, 5, 58, 0, 64, 15,220, 65, 2, - 58,134, 17,183,194, 42, 4,205, 29, 2,195,115, 3,205,217, 1, - 120,217, 6, 1, 38, 28,111, 86, 36, 94, 36, 78, 33, 0, 96,217, - 221, 54, 0, 43,221, 54, 1,128,221, 54, 0, 42,221, 54, 1,128, - 201,221, 54, 0, 39,221, 54, 1, 31,217,120,183, 40, 47, 58,140, - 17,185,202,105, 2,121, 50,140, 17,119, 15,119, 15,119, 15,119, - 15,119, 15,119, 15,119,117, 15,119, 26, 60, 40, 18,221, 54, 0, - 42,221,119, 1, 28, 32, 6, 20, 32, 3, 22,128, 12,217,201, 6, - 0,221, 54, 0, 42,221, 54, 1,128,221, 54, 0, 43,221, 54, 1, - 0,217,201,205,173, 2,195,140, 5, 58, 0, 64, 15,220, 65, 2, - 58,134, 17,183,194,115, 3,205,173, 2,195,115, 3,217, 6, 0, - 217,221, 54, 0, 43,221, 54, 1, 0,201, 62, 1, 50,134, 17,205, - 173, 2,195,140, 5, 58, 0, 64, 15,220, 65, 2,205,115, 4, 58, - 0, 64, 15,220, 65, 2, 58,240, 31,246, 2, 50,240, 31, 58, 0, - 64, 15,220, 65, 2, 33,252, 31, 78, 44, 94, 44, 86, 58, 0, 64, - 15,220, 65, 2,175, 50,255, 31, 33,141, 17, 54, 1, 44, 54, 1, - 44,113, 44,115, 44,114, 58, 0, 64, 15,220, 65, 2, 33, 82, 3, - 34, 48, 1,195,242, 0,175, 50,255, 31, 6, 8, 17,135, 17, 58, - 0, 64, 15,220, 65, 2, 26,183,194, 55, 3, 58, 0, 64, 15,220, - 65, 2, 5,205,201, 11, 4, 29, 5,194, 31, 3, 58,240, 31,246, - 2, 50,240, 31, 33,141, 17, 54, 1, 33, 82, 3, 34, 48, 1,195, - 242, 0, 58, 0, 64, 15,220, 65, 2, 33,142, 17,126, 61,202,101, - 3,119,195, 50, 1, 58, 0, 64, 15,220, 65, 2, 44, 78, 44, 94, - 44, 86,235, 58, 0, 64, 15,220, 65, 2,205,217, 1, 58, 0, 64, - 15,220, 65, 2,120,254, 8,218,246, 6,254, 11,218,188, 12,202, - 64, 13,254, 12,202, 9, 2, 58, 0, 64, 15,220, 65, 2,120,254, - 24,218,151, 7,254, 28,218,156, 13,202,153, 2, 58, 0, 64, 15, - 220, 65, 2,120,254,254,202,162, 15,254,255,202, 63, 4,254,252, - 202,233, 4,254,253,202,254, 4, 58, 0, 64, 15,220, 65, 2,120, - 254, 40,218,126, 9,254, 44,218,249, 13, 58, 0, 64, 15,220, 65, - 2,120,254, 56,218,197, 7,254, 59,218, 13, 15,202,103, 15, 58, - 0, 64, 15,220, 65, 2,120,254, 72,218, 68, 8,254, 76,218,144, - 14, 58, 0, 64, 15,220, 65, 2,120,254,248,218,209, 10, 58, 0, - 64, 15,220, 65, 2,195, 63, 4, 58, 0, 64, 15,220, 65, 2, 44, - 194, 42, 4, 36,194, 42, 4, 38,128, 12, 58, 0, 64, 15,220, 65, - 2, 44,194, 60, 4, 36,194, 60, 4, 38,128, 12,195,115, 3,205, - 79, 4,195, 50, 1,175, 50,255, 31,205, 79, 4,195,242, 0, 58, - 240, 31,230,253, 50,240, 31, 58, 0, 64, 15,220, 65, 2,205,115, - 4, 58, 0, 64, 15,220, 65, 2,175, 50,141, 17, 33, 50, 1, 34, - 48, 1,201, 58,134, 17,183,204,173, 2, 6, 4, 17, 63, 17, 33, - 139, 17, 58, 0, 64, 15,220, 65, 2, 54, 0,123,214, 15, 95,126, - 183, 32, 2,175, 18, 58, 0, 64, 15,220, 65, 2, 29, 45, 16,226, - 6, 8, 17, 79, 17, 58, 0, 64, 15,220, 65, 2, 62,127, 18, 29, - 58, 0, 64, 15,220, 65, 2,126,183,194,218, 4, 5,120,205, 88, - 11, 58, 0, 64, 15,220, 65, 2,120,230, 4,253,111,120,230, 3, - 198,180,253,119, 0,253, 54, 1,192, 4, 45, 16,200, 33, 80, 17, - 62,192, 6, 8,119, 44, 16,252,201, 58, 0, 64, 15,220, 65, 2, - 235, 44, 78, 44, 94, 44, 86, 45, 45, 45,235,195,115, 3, 58, 0, - 64, 15,220, 65, 2,235, 44,113, 44,115, 44,114, 45, 45, 45,235, - 195,115, 3, 58, 0, 64, 15,220, 65, 2,205,116, 6, 58, 0, 64, - 15,220, 65, 2, 58,240, 31,246, 1, 50,240, 31, 58, 0, 64, 15, - 220, 65, 2, 33,252, 31, 78, 44, 94, 44, 86, 58, 0, 64, 15,220, - 65, 2,175, 50,255, 31, 33,149, 17, 54, 1, 44, 54, 1, 44,113, - 44,115, 44,114, 58, 0, 64, 15,220, 65, 2, 33,107, 5, 34, 38, - 1, 58, 0, 64, 15,220, 65, 2,195,242, 0, 58, 0, 64, 15,220, - 65, 2, 33,150, 17,126, 61,202,126, 5,119,195, 40, 1, 58, 0, - 64, 15,220, 65, 2, 44, 78, 44, 94, 44, 86,235, 58, 0, 64, 15, - 220, 65, 2,205,217, 1, 58, 0, 64, 15,220, 65, 2,120,254, 8, - 218,240, 6,254, 11,218,182, 12,202, 58, 13,254, 12,202, 3, 2, - 58, 0, 64, 15,220, 65, 2,120,254, 24,218,145, 7,254, 28,218, - 150, 13,202,147, 2, 58, 0, 64, 15,220, 65, 2,120,254,254,202, - 156, 15,254,255,202, 50, 6, 58, 0, 64, 15,220, 65, 2,120,254, - 40,218,120, 9,254, 44,218,211, 13, 58, 0, 64, 15,220, 65, 2, - 120,254, 56,218,191, 7,254, 59,218, 7, 15,202, 97, 15, 58, 0, - 64, 15,220, 65, 2,120,254, 72,218, 62, 8,254, 76,218, 74, 14, - 58, 0, 64, 15,220, 65, 2,120,254,232,218, 38, 11,254,236,218, - 116, 15,202,186, 2, 58, 0, 64, 15,220, 65, 2,120,254,248,218, - 162, 10,205, 66, 6,195, 40, 1,175, 50,255, 31,205, 66, 6,195, - 242, 0, 58, 0, 64, 15,220, 65, 2, 58,240, 31,230,254, 50,240, - 31, 58, 0, 64, 15,220, 65, 2,175, 50,149, 17, 33, 40, 1, 34, - 38, 1, 58, 0, 64, 15,220, 65, 2,205,116, 6, 58, 0, 64, 15, - 220, 65, 2,201, 58,134, 17,183,196,173, 2, 6, 4, 17,139, 17, - 58, 0, 64, 15,220, 65, 2, 26,183, 40, 64,175, 18, 58, 0, 64, - 15,220, 65, 2,120, 15, 15, 15, 15, 61, 38, 17,111, 78,214, 15, - 111,113, 58, 0, 64, 15,220, 65, 2,213,125,198, 8,111,198, 4, - 95, 84, 58, 0, 64, 15,220, 65, 2, 26,119, 44, 28, 26,119, 44, - 28, 26,119,209, 58, 0, 64, 15,220, 65, 2, 29, 16,178, 6, 8, - 58, 0, 64, 15,220, 65, 2, 26,183,202,234, 6,175, 18, 58, 0, - 64, 15,220, 65, 2, 5,205,201, 11, 4, 29, 5,194,208, 6,201, - 205, 20, 7,195,140, 5, 71, 58, 0, 64, 15,220, 65, 2,229,120, - 230, 7, 33,128, 17,133,111,126,225,183,194, 42, 4,120,205, 20, - 7,195,115, 3,230, 7,221, 54, 0, 40,221,119, 1, 71, 8, 58, - 0, 64, 15,220, 65, 2,120,230, 4, 15,253,111, 58, 0, 64, 15, - 220, 65, 2,205,217, 1, 58, 0, 64, 15,220, 65, 2, 8,213,229, - 87,230, 3,198,164, 95, 58, 0, 64, 15,220, 65, 2, 38, 16,120, - 230, 31,198,144,111, 58, 0, 64, 15,220, 65, 2,120,230,224, 15, - 15, 71,126,176,253,115, 0,253,119, 1, 58, 0, 64, 15,220, 65, - 2,123,214, 4, 95, 45,126,253,115, 0,253,119, 1, 58, 0, 64, - 15,220, 65, 2,122,246,240,221, 54, 0, 40,221,119, 1,225,209, - 201,205,181, 7,195,140, 5, 71, 58, 0, 64, 15,220, 65, 2,120, - 229,230, 7, 33,128, 17,133,111,126,225,183,194,115, 3,120,205, - 181, 7,195,115, 3,230, 7,221, 54, 0, 40,221,119, 1,201,205, - 227, 7,195,140, 5, 71, 58, 0, 64, 15,220, 65, 2,120,229,230, - 7, 33,128, 17,133,111,126,225,183,194, 24, 4,120,205,227, 7, - 195,115, 3,245, 71, 58, 0, 64, 15,220, 65, 2,120,230, 4, 15, - 253,111, 58, 0, 64, 15,220, 65, 2,205,217, 1, 58, 0, 64, 15, - 220, 65, 2,241,213,230, 7, 87,230, 3,198,164, 95, 58, 0, 64, - 15,220, 65, 2,253,115, 0,253,112, 1, 58, 0, 64, 15,220, 65, - 2,205,217, 1, 58, 0, 64, 15,220, 65, 2,123,214, 4, 95,253, - 115, 0,253,112, 1, 58, 0, 64, 15,220, 65, 2,209,201,205,166, - 8,195,140, 5,230, 7, 71, 58, 0, 64, 15,220, 65, 2,213,197, - 120, 17, 64, 17,131, 95, 58, 0, 64, 15,220, 65, 2,205,217, 1, - 58, 0, 64, 15,220, 65, 2,120, 18,123,198, 8, 95,175, 18, 89, - 193, 75,209, 58, 0, 64, 15,220, 65, 2,229,120, 38, 17,198,128, - 111,126,225,183,194,115, 3, 58, 0, 64, 15,220, 65, 2,120,229, - 33, 64, 17,133,111, 70,225, 8, 58, 0, 64, 15,220, 65, 2, 8, - 205,187, 8,195,115, 3,230, 7, 8, 58, 0, 64, 15,220, 65, 2, - 205,217, 1, 58, 0, 64, 15,220, 65, 2, 8,245,230, 4, 15,253, - 111, 58, 0, 64, 15,220, 65, 2,241,197,213,229, 38, 28,104, 86, - 36, 94, 36, 78,235,245, 58, 0, 64, 15,220, 65, 2, 6, 7, 17, - 154, 17,120, 8,205,217, 1,235,112,235, 28,205,217, 1,235,112, - 235, 28,205,217, 1,235,112,235, 28,205,217, 1,235,112,235, 28, - 8, 71, 16,222,205,217, 1,235,112,235, 58, 0, 64, 15,220, 65, - 2,241, 71,205, 88, 11,120, 17, 88, 17,230, 7,131, 95,245,230, - 3,198,176, 33,154, 17, 8, 58, 0, 64, 15,220, 65, 2, 8,253, - 119, 0, 70, 44,253,112, 1, 8,120, 18,123,198, 8, 95, 58, 0, - 64, 15,220, 65, 2, 8,214,128, 6, 28,253,119, 0, 78,253,113, - 1,198, 4, 44, 16,244, 58, 0, 64, 15,220, 65, 2,125,214, 24, - 111, 6, 4,126, 18,123,198, 8, 95, 44, 16,247, 58, 0, 64, 15, - 220, 65, 2,241,225,209,193,201,205,219, 9,195,140, 5,230, 7, - 71, 58, 0, 64, 15,220, 65, 2,213,197,120, 22, 17,198, 72, 95, - 58, 0, 64, 15,220, 65, 2,205,217, 1, 58, 0, 64, 15,220, 65, - 2,235,112,235, 89,193, 75,209, 58, 0, 64, 15,220, 65, 2,229, - 120, 33,128, 17,133,111,126,225,183,194,115, 3, 58, 0, 64, 15, - 220, 65, 2,120,229, 33, 72, 17,133,111, 70,225,245, 58, 0, 64, - 15,220, 65, 2,241,205,238, 9,195,115, 3,245, 58, 0, 64, 15, - 220, 65, 2,205,217, 1, 58, 0, 64, 15,220, 65, 2,241,197,213, - 229,230, 7,245, 38, 17,198, 88,111, 8, 58, 0, 64, 15,220, 65, - 2, 8,230, 4, 15,253,111, 58, 0, 64, 15,220, 65, 2,241,230, - 3,198, 64, 79,126,230, 7, 95, 58, 0, 64, 15,220, 65, 2,125, - 198, 8,111,123,254, 7, 56, 14,253,113, 0,126,128,254,127, 56, - 2, 62,127,253,119, 1,121,198, 4, 79, 58, 0, 64, 15,220, 65, - 2,125,198, 8,111,123,254, 5, 56, 14,253,113, 0,126,128,254, - 127, 56, 2, 62,127,253,119, 1,121,198, 4, 79, 58, 0, 64, 15, - 220, 65, 2,125,198, 8,111,123,254, 4, 56, 14,253,113, 0,126, - 128,254,127, 56, 2, 62,127,253,119, 1,121,198, 4, 79, 58, 0, - 64, 15,220, 65, 2,125,198, 8,111,253,113, 0,126,128,254,127, - 56, 2, 62,127,253,119, 1, 58, 0, 64, 15,220, 65, 2,225,209, - 193,201, 71, 58, 0, 64, 15,220, 65, 2,120,230, 4, 15,253,111, - 120, 8, 58, 0, 64, 15,220, 65, 2,205,217, 1, 58, 0, 64, 15, - 220, 65, 2, 8,230, 3,198,180,253,119, 0,253,112, 1,195,140, - 5, 71, 58, 0, 64, 15,220, 65, 2,120,120,230, 4, 15,253,111, - 8, 58, 0, 64, 15,220, 65, 2,205,217, 1, 58, 0, 64, 15,220, - 65, 2, 8,229,230, 7, 38, 17,198, 80,108,112, 8, 58, 0, 64, - 15,220, 65, 2, 8,230, 7,198,128,111, 8,126,183,225,194,115, - 3, 58, 0, 64, 15,220, 65, 2, 8,230, 3,198,180,253,119, 0, - 253,112, 1,195,115, 3,230, 7, 71, 58, 0, 64, 15,220, 65, 2, - 229, 38, 17,120,198,128,111, 54, 1,225, 58, 0, 64, 15,220, 65, - 2,120,230, 4, 15,253,111,120,230, 3,135,135,198,180,253,119, - 0,253, 54, 1,192,195,140, 5,230, 7,245,213,229, 79,230, 4, - 15,253,111,121,230, 3,198, 64, 14, 6, 33,168, 16, 8, 58, 0, - 64, 15,220, 65, 2, 8, 94,253,119, 0,198, 4,253,115, 1, 0, - 253,119, 0,198, 4,253,115, 1, 0,253,119, 0,198, 4,253,115, - 1, 0,253,119, 0,198, 4,253,115, 1, 44, 13,194,109, 11,225, - 209, 58, 0, 64, 15,220, 65, 2,241, 79,246,240,221, 54, 0, 40, - 221,113, 1,221, 54, 0, 40,221,119, 1,221, 54, 0, 40,221,113, - 1, 58, 0, 64, 15,220, 65, 2,201,120, 38, 17,198, 64,111,197, - 120, 70,205,187, 8,193, 58, 0, 64, 15,220, 65, 2,197,125,198, - 8,111,120, 70,205,238, 9,193,125,198, 8,111,120,230, 3,198, - 180,253,119, 0,126,253,119, 1, 58, 0, 64, 15,220, 65, 2,201, - 33, 48, 17, 6, 3,197,126,203,127, 32, 6, 6, 15, 44,195,101, - 12,230,127, 71, 44,126,128, 71, 58, 0, 64, 15,220, 65, 2,197, - 44, 78, 44, 94, 44, 86,235, 58, 0, 64, 15,220, 65, 2,205,217, - 1, 58, 0, 64, 15,220, 65, 2,120,254,254,202,140, 12,254,255, - 202,161, 12,253,104, 58, 0, 64, 15,220, 65, 2,235,114, 45,115, - 45,113, 45,193, 58, 0, 64, 15,220, 65, 2,253,125,128, 71,254, - 16, 56, 2, 6, 15, 58, 0, 64, 15,220, 65, 2,120, 7, 7, 7, - 193,176, 15, 15, 15,246,144, 50, 17,127,125,214, 17,111, 58, 0, - 64, 15,220, 65, 2, 5,242, 5, 12,195, 60, 1, 58, 0, 64, 15, - 220, 65, 2, 28,235,113, 44,115, 44,114,235, 29, 29, 29,195, 39, - 12, 58, 0, 64, 15,220, 65, 2, 28,235, 78, 44, 94, 44, 86,235, - 29, 29, 29,195, 39, 12,205,218, 12,195,140, 5, 71, 58, 0, 64, - 15,220, 65, 2,120,229,230, 3, 33,136, 17,133,111,126,225,183, - 194, 42, 4,120,205,218, 12,195,115, 3,230, 3, 71, 8, 58, 0, - 64, 15,220, 65, 2,229, 38, 17,120, 15, 15, 15, 15,111,126,246, - 128,119, 58, 0, 64, 15,220, 65, 2,213, 44, 44, 84,125,198, 6, - 95, 58, 0, 64, 15,220, 65, 2, 26,119, 44, 28, 26,119, 44, 28, - 26,119,209,225, 58, 0, 64, 15,220, 65, 2,205,217, 1, 58, 0, - 64, 15,220, 65, 2, 8,229,213, 38, 16,104, 17, 17,127, 15, 15, - 15, 70,176, 18, 44,126, 18,209,225,201,205, 77, 13,195,140, 5, - 58,139, 17,183,194, 42, 4,205, 77, 13,195,115, 3, 58, 0, 64, - 15,220, 65, 2,229, 33, 48, 17,126,246,128,119, 58, 0, 64, 15, - 220, 65, 2,213, 44, 44, 84,125,198, 6, 95, 58, 0, 64, 15,220, - 65, 2, 26,119, 44, 28, 26,119, 44, 28, 26,119,209,225, 58, 0, - 64, 15,220, 65, 2,205,217, 1, 58, 0, 64, 15,220, 65, 2, 62, - 224,176, 50, 17,127,201,205,186, 13,195,140, 5, 71, 58, 0, 64, - 15,220, 65, 2,120,229,230, 3, 33,136, 17,133,111,126,225,183, - 194,115, 3,120,205,186, 13,195,115, 3,230, 3, 71, 58, 0, 64, - 15,220, 65, 2,229, 38, 17,120, 15, 15, 15, 15,111,126,230,127, - 119,225,201,230, 3, 8, 58, 0, 64, 15,220, 65, 2,205,217, 1, - 58, 0, 64, 15,220, 65, 2, 8,229, 38, 17, 15, 15, 15, 15,111, - 126,230,128,176,119,225,195,140, 5,230, 3, 8, 58, 0, 64, 15, - 220, 65, 2,205,217, 1, 58, 0, 64, 15,220, 65, 2, 8,213,229, - 245, 17,136, 17,131, 95, 26, 95, 58, 0, 64, 15,220, 65, 2,241, - 38, 17, 15, 15, 15, 15,198, 15,111,112, 58, 0, 64, 15,220, 65, - 2,123,183, 32, 16,125,214, 15,111,126,230,128,176,119, 58, 0, - 64, 15,220, 65, 2,225,209,195,115, 3,230, 3, 8, 58, 0, 64, - 15,220, 65, 2,205,217, 1, 58, 0, 64, 15,220, 65, 2, 8,213, - 229, 22, 28, 88, 38, 17, 15, 15, 15, 15,198, 10,111, 58, 0, 64, - 15,220, 65, 2, 26,119, 20, 45, 26,119, 20, 45, 26,119, 58, 0, - 64, 15,220, 65, 2,125,214, 8,111, 54, 0,225,209,195,140, 5, - 230, 3, 8, 58, 0, 64, 15,220, 65, 2,205,217, 1, 58, 0, 64, - 15,220, 65, 2, 8,213,229, 22, 28, 88, 33,136, 17,245,133,111, - 241, 70, 38, 17, 15, 15, 15, 15,198, 15,111, 58, 0, 64, 15,220, - 65, 2,119, 45, 26,119, 20, 45, 26,119, 20, 45, 26,119, 58, 0, - 64, 15,220, 65, 2,120,183,202,223, 14,225,209,195,115, 3, 58, - 0, 64, 15,220, 65, 2, 84,125,214, 4, 95,126, 18, 44, 28,126, - 18, 44, 28,126, 18, 58, 0, 64, 15,220, 65, 2,125,214, 8,111, - 54, 0,225,209,195,115, 3,205, 43, 15,195,140, 5, 71, 58, 0, - 64, 15,220, 65, 2,120,229,230, 15, 38, 17,198,128,111,126,225, - 183,194, 24, 4,120,205, 43, 15,195,115, 3,230, 3, 8, 58, 0, - 64, 15,220, 65, 2,205,217, 1, 58, 0, 64, 15,220, 65, 2, 8, - 213, 17, 17,127, 15, 15, 15,176,246,128, 18, 58, 0, 64, 15,220, - 65, 2,205,217, 1, 58, 0, 64, 15,220, 65, 2,235,112,235,209, - 201,205,126, 13,195,140, 5, 58,139, 17,183,194, 42, 4,205,126, - 13,195,115, 3,230, 3, 71, 58, 0, 64, 15,220, 65, 2,229, 38, - 17,120,198,136,111, 54, 1, 58, 0, 64, 15,220, 65, 2,120, 15, - 15, 15, 15,111, 38, 17, 54, 0,225,195,140, 5,205,168, 15,195, - 40, 1,205,168, 15,195, 50, 1, 58, 0, 64, 15,220, 65, 2,205, - 217, 1, 58, 0, 64, 15,220, 65, 2,235,114, 45,115, 45,113, 58, - 0, 64, 15,220, 65, 2, 45,112,201,255,255,255,255,255,255,255, + 39,221, 54, 1, 63,195,242, 0, 61,202, 70, 1, 61,202,174, 4, + 61,202,211, 5, 61,202, 96, 2, 61,202,224, 3, 61,202,177, 2, + 58, 0, 64, 15,220,220, 1,175, 50,255, 31, 58, 0, 64, 15,220, + 220, 1, 58,255, 31,183, 32,208, 58, 0, 64, 15,220,220, 1, 58, + 0, 64,203, 79, 32, 8,203, 71,196,220, 1,195,242, 0,221,126, + 0,203, 71,196,220, 1,221, 54, 0, 39,221, 54, 1, 47, 58, 0, + 64, 15,220,220, 1,195, 40, 1, 58, 0, 64, 15,220,220, 1,195, + 50, 1, 58, 0, 64, 15,220,220, 1,195,155, 11, 58, 0, 64, 15, + 220,220, 1,195,242, 0, 33,252, 31, 78, 44, 94, 44, 86,235,175, + 50,255, 31, 17, 0, 28,205,116, 1,120,183,202,113, 1, 18, 20, + 205,116, 1,120, 18, 20,205,116, 1,120, 18, 21, 21, 28,195, 86, + 1,195,242, 0, 58,140, 17,185,202,145, 1,121, 50,140, 17,217, + 119, 15,119, 15,119, 15,119, 15,119, 15,119, 15,119,117, 15,119, + 217, 70, 44,194,157, 1, 36,194,157, 1, 38,128, 12,201,205,184, + 1,195, 39, 5, 58, 0, 64, 15,220,220, 1, 58,134, 17,183,194, + 197, 3,205,184, 1,195, 14, 3,205,116, 1,120,217, 6, 1, 38, + 28,111, 86, 36, 94, 36, 78, 33, 0, 96,217,221, 54, 0, 43,221, + 54, 1,128,221, 54, 0, 42,221, 54, 1,128,201,221, 54, 0, 39, + 221, 54, 1, 31,217,120,183, 40, 47, 58,140, 17,185,202, 4, 2, + 121, 50,140, 17,119, 15,119, 15,119, 15,119, 15,119, 15,119, 15, + 119,117, 15,119, 26, 60, 40, 18,221, 54, 0, 42,221,119, 1, 28, + 32, 6, 20, 32, 3, 22,128, 12,217,201, 6, 0,221, 54, 0, 42, + 221, 54, 1,128,221, 54, 0, 43,221, 54, 1, 0,217,201,205, 72, + 2,195, 39, 5, 58, 0, 64, 15,220,220, 1, 58,134, 17,183,194, + 14, 3,205, 72, 2,195, 14, 3,217, 6, 0,217,221, 54, 0, 43, + 221, 54, 1, 0,201, 62, 1, 50,134, 17,205, 72, 2,195, 39, 5, + 58, 0, 64, 15,220,220, 1,205, 14, 4, 58, 0, 64, 15,220,220, + 1, 58,240, 31,246, 2, 50,240, 31, 58, 0, 64, 15,220,220, 1, + 33,252, 31, 78, 44, 94, 44, 86, 58, 0, 64, 15,220,220, 1,175, + 50,255, 31, 33,141, 17, 54, 1, 44, 54, 1, 44,113, 44,115, 44, + 114, 58, 0, 64, 15,220,220, 1, 33,237, 2, 34, 48, 1,195,242, + 0,175, 50,255, 31, 6, 8, 17,135, 17, 58, 0, 64, 15,220,220, + 1, 26,183,194,210, 2, 58, 0, 64, 15,220,220, 1, 5,205,100, + 11, 4, 29, 5,194,186, 2, 58,240, 31,246, 2, 50,240, 31, 33, + 141, 17, 54, 1, 33,237, 2, 34, 48, 1,195,242, 0, 58, 0, 64, + 15,220,220, 1, 33,142, 17,126, 61,202, 0, 3,119,195, 50, 1, + 58, 0, 64, 15,220,220, 1, 44, 78, 44, 94, 44, 86,235, 58, 0, + 64, 15,220,220, 1,205,116, 1, 58, 0, 64, 15,220,220, 1,120, + 254, 8,218,145, 6,254, 11,218, 87, 12,202,219, 12,254, 12,202, + 164, 1, 58, 0, 64, 15,220,220, 1,120,254, 24,218, 50, 7,254, + 28,218, 55, 13,202, 52, 2, 58, 0, 64, 15,220,220, 1,120,254, + 254,202, 61, 15,254,255,202,218, 3,254,252,202,132, 4,254,253, + 202,153, 4, 58, 0, 64, 15,220,220, 1,120,254, 40,218, 25, 9, + 254, 44,218,148, 13, 58, 0, 64, 15,220,220, 1,120,254, 56,218, + 96, 7,254, 59,218,168, 14,202, 2, 15, 58, 0, 64, 15,220,220, + 1,120,254, 72,218,223, 7,254, 76,218, 43, 14, 58, 0, 64, 15, + 220,220, 1,120,254,248,218,108, 10, 58, 0, 64, 15,220,220, 1, + 195,218, 3, 58, 0, 64, 15,220,220, 1, 44,194,197, 3, 36,194, + 197, 3, 38,128, 12, 58, 0, 64, 15,220,220, 1, 44,194,215, 3, + 36,194,215, 3, 38,128, 12,195, 14, 3,205,234, 3,195, 50, 1, + 175, 50,255, 31,205,234, 3,195,242, 0, 58,240, 31,230,253, 50, + 240, 31, 58, 0, 64, 15,220,220, 1,205, 14, 4, 58, 0, 64, 15, + 220,220, 1,175, 50,141, 17, 33, 50, 1, 34, 48, 1,201, 58,134, + 17,183,204, 72, 2, 6, 4, 17, 63, 17, 33,139, 17, 58, 0, 64, + 15,220,220, 1, 54, 0,123,214, 15, 95,126,183, 32, 2,175, 18, + 58, 0, 64, 15,220,220, 1, 29, 45, 16,226, 6, 8, 17, 79, 17, + 58, 0, 64, 15,220,220, 1, 62,127, 18, 29, 58, 0, 64, 15,220, + 220, 1,126,183,194,117, 4, 5,120,205,243, 10, 58, 0, 64, 15, + 220,220, 1,120,230, 4,253,111,120,230, 3,198,180,253,119, 0, + 253, 54, 1,192, 4, 45, 16,200, 33, 80, 17, 62,192, 6, 8,119, + 44, 16,252,201, 58, 0, 64, 15,220,220, 1,235, 44, 78, 44, 94, + 44, 86, 45, 45, 45,235,195, 14, 3, 58, 0, 64, 15,220,220, 1, + 235, 44,113, 44,115, 44,114, 45, 45, 45,235,195, 14, 3, 58, 0, + 64, 15,220,220, 1,205, 15, 6, 58, 0, 64, 15,220,220, 1, 58, + 240, 31,246, 1, 50,240, 31, 58, 0, 64, 15,220,220, 1, 33,252, + 31, 78, 44, 94, 44, 86, 58, 0, 64, 15,220,220, 1,175, 50,255, + 31, 33,149, 17, 54, 1, 44, 54, 1, 44,113, 44,115, 44,114, 58, + 0, 64, 15,220,220, 1, 33, 6, 5, 34, 38, 1, 58, 0, 64, 15, + 220,220, 1,195,242, 0, 58, 0, 64, 15,220,220, 1, 33,150, 17, + 126, 61,202, 25, 5,119,195, 40, 1, 58, 0, 64, 15,220,220, 1, + 44, 78, 44, 94, 44, 86,235, 58, 0, 64, 15,220,220, 1,205,116, + 1, 58, 0, 64, 15,220,220, 1,120,254, 8,218,139, 6,254, 11, + 218, 81, 12,202,213, 12,254, 12,202,158, 1, 58, 0, 64, 15,220, + 220, 1,120,254, 24,218, 44, 7,254, 28,218, 49, 13,202, 46, 2, + 58, 0, 64, 15,220,220, 1,120,254,254,202, 55, 15,254,255,202, + 205, 5, 58, 0, 64, 15,220,220, 1,120,254, 40,218, 19, 9,254, + 44,218,110, 13, 58, 0, 64, 15,220,220, 1,120,254, 56,218, 90, + 7,254, 59,218,162, 14,202,252, 14, 58, 0, 64, 15,220,220, 1, + 120,254, 72,218,217, 7,254, 76,218,229, 13, 58, 0, 64, 15,220, + 220, 1,120,254,232,218,193, 10,254,236,218, 15, 15,202, 85, 2, + 58, 0, 64, 15,220,220, 1,120,254,248,218, 61, 10,205,221, 5, + 195, 40, 1,175, 50,255, 31,205,221, 5,195,242, 0, 58, 0, 64, + 15,220,220, 1, 58,240, 31,230,254, 50,240, 31, 58, 0, 64, 15, + 220,220, 1,175, 50,149, 17, 33, 40, 1, 34, 38, 1, 58, 0, 64, + 15,220,220, 1,205, 15, 6, 58, 0, 64, 15,220,220, 1,201, 58, + 134, 17,183,196, 72, 2, 6, 4, 17,139, 17, 58, 0, 64, 15,220, + 220, 1, 26,183, 40, 64,175, 18, 58, 0, 64, 15,220,220, 1,120, + 15, 15, 15, 15, 61, 38, 17,111, 78,214, 15,111,113, 58, 0, 64, + 15,220,220, 1,213,125,198, 8,111,198, 4, 95, 84, 58, 0, 64, + 15,220,220, 1, 26,119, 44, 28, 26,119, 44, 28, 26,119,209, 58, + 0, 64, 15,220,220, 1, 29, 16,178, 6, 8, 58, 0, 64, 15,220, + 220, 1, 26,183,202,133, 6,175, 18, 58, 0, 64, 15,220,220, 1, + 5,205,100, 11, 4, 29, 5,194,107, 6,201,205,175, 6,195, 39, + 5, 71, 58, 0, 64, 15,220,220, 1,229,120,230, 7, 33,128, 17, + 133,111,126,225,183,194,197, 3,120,205,175, 6,195, 14, 3,230, + 7,221, 54, 0, 40,221,119, 1, 71, 8, 58, 0, 64, 15,220,220, + 1,120,230, 4, 15,253,111, 58, 0, 64, 15,220,220, 1,205,116, + 1, 58, 0, 64, 15,220,220, 1, 8,213,229, 87,230, 3,198,164, + 95, 58, 0, 64, 15,220,220, 1, 38, 16,120,230, 31,198,144,111, + 58, 0, 64, 15,220,220, 1,120,230,224, 15, 15, 71,126,176,253, + 115, 0,253,119, 1, 58, 0, 64, 15,220,220, 1,123,214, 4, 95, + 45,126,253,115, 0,253,119, 1, 58, 0, 64, 15,220,220, 1,122, + 246,240,221, 54, 0, 40,221,119, 1,225,209,201,205, 80, 7,195, + 39, 5, 71, 58, 0, 64, 15,220,220, 1,120,229,230, 7, 33,128, + 17,133,111,126,225,183,194, 14, 3,120,205, 80, 7,195, 14, 3, + 230, 7,221, 54, 0, 40,221,119, 1,201,205,126, 7,195, 39, 5, + 71, 58, 0, 64, 15,220,220, 1,120,229,230, 7, 33,128, 17,133, + 111,126,225,183,194,179, 3,120,205,126, 7,195, 14, 3,245, 71, + 58, 0, 64, 15,220,220, 1,120,230, 4, 15,253,111, 58, 0, 64, + 15,220,220, 1,205,116, 1, 58, 0, 64, 15,220,220, 1,241,213, + 230, 7, 87,230, 3,198,164, 95, 58, 0, 64, 15,220,220, 1,253, + 115, 0,253,112, 1, 58, 0, 64, 15,220,220, 1,205,116, 1, 58, + 0, 64, 15,220,220, 1,123,214, 4, 95,253,115, 0,253,112, 1, + 58, 0, 64, 15,220,220, 1,209,201,205, 65, 8,195, 39, 5,230, + 7, 71, 58, 0, 64, 15,220,220, 1,213,197,120, 17, 64, 17,131, + 95, 58, 0, 64, 15,220,220, 1,205,116, 1, 58, 0, 64, 15,220, + 220, 1,120, 18,123,198, 8, 95,175, 18, 89,193, 75,209, 58, 0, + 64, 15,220,220, 1,229,120, 38, 17,198,128,111,126,225,183,194, + 14, 3, 58, 0, 64, 15,220,220, 1,120,229, 33, 64, 17,133,111, + 70,225, 8, 58, 0, 64, 15,220,220, 1, 8,205, 86, 8,195, 14, + 3,230, 7, 8, 58, 0, 64, 15,220,220, 1,205,116, 1, 58, 0, + 64, 15,220,220, 1, 8,245,230, 4, 15,253,111, 58, 0, 64, 15, + 220,220, 1,241,197,213,229, 38, 28,104, 86, 36, 94, 36, 78,235, + 245, 58, 0, 64, 15,220,220, 1, 6, 7, 17,154, 17,120, 8,205, + 116, 1,235,112,235, 28,205,116, 1,235,112,235, 28,205,116, 1, + 235,112,235, 28,205,116, 1,235,112,235, 28, 8, 71, 16,222,205, + 116, 1,235,112,235, 58, 0, 64, 15,220,220, 1,241, 71,205,243, + 10,120, 17, 88, 17,230, 7,131, 95,245,230, 3,198,176, 33,154, + 17, 8, 58, 0, 64, 15,220,220, 1, 8,253,119, 0, 70, 44,253, + 112, 1, 8,120, 18,123,198, 8, 95, 58, 0, 64, 15,220,220, 1, + 8,214,128, 6, 28,253,119, 0, 78,253,113, 1,198, 4, 44, 16, + 244, 58, 0, 64, 15,220,220, 1,125,214, 24,111, 6, 4,126, 18, + 123,198, 8, 95, 44, 16,247, 58, 0, 64, 15,220,220, 1,241,225, + 209,193,201,205,118, 9,195, 39, 5,230, 7, 71, 58, 0, 64, 15, + 220,220, 1,213,197,120, 22, 17,198, 72, 95, 58, 0, 64, 15,220, + 220, 1,205,116, 1, 58, 0, 64, 15,220,220, 1,235,112,235, 89, + 193, 75,209, 58, 0, 64, 15,220,220, 1,229,120, 33,128, 17,133, + 111,126,225,183,194, 14, 3, 58, 0, 64, 15,220,220, 1,120,229, + 33, 72, 17,133,111, 70,225,245, 58, 0, 64, 15,220,220, 1,241, + 205,137, 9,195, 14, 3,245, 58, 0, 64, 15,220,220, 1,205,116, + 1, 58, 0, 64, 15,220,220, 1,241,197,213,229,230, 7,245, 38, + 17,198, 88,111, 8, 58, 0, 64, 15,220,220, 1, 8,230, 4, 15, + 253,111, 58, 0, 64, 15,220,220, 1,241,230, 3,198, 64, 79,126, + 230, 7, 95, 58, 0, 64, 15,220,220, 1,125,198, 8,111,123,254, + 7, 56, 14,253,113, 0,126,128,254,127, 56, 2, 62,127,253,119, + 1,121,198, 4, 79, 58, 0, 64, 15,220,220, 1,125,198, 8,111, + 123,254, 5, 56, 14,253,113, 0,126,128,254,127, 56, 2, 62,127, + 253,119, 1,121,198, 4, 79, 58, 0, 64, 15,220,220, 1,125,198, + 8,111,123,254, 4, 56, 14,253,113, 0,126,128,254,127, 56, 2, + 62,127,253,119, 1,121,198, 4, 79, 58, 0, 64, 15,220,220, 1, + 125,198, 8,111,253,113, 0,126,128,254,127, 56, 2, 62,127,253, + 119, 1, 58, 0, 64, 15,220,220, 1,225,209,193,201, 71, 58, 0, + 64, 15,220,220, 1,120,230, 4, 15,253,111,120, 8, 58, 0, 64, + 15,220,220, 1,205,116, 1, 58, 0, 64, 15,220,220, 1, 8,230, + 3,198,180,253,119, 0,253,112, 1,195, 39, 5, 71, 58, 0, 64, + 15,220,220, 1,120,120,230, 4, 15,253,111, 8, 58, 0, 64, 15, + 220,220, 1,205,116, 1, 58, 0, 64, 15,220,220, 1, 8,229,230, + 7, 38, 17,198, 80,108,112, 8, 58, 0, 64, 15,220,220, 1, 8, + 230, 7,198,128,111, 8,126,183,225,194, 14, 3, 58, 0, 64, 15, + 220,220, 1, 8,230, 3,198,180,253,119, 0,253,112, 1,195, 14, + 3,230, 7, 71, 58, 0, 64, 15,220,220, 1,229, 38, 17,120,198, + 128,111, 54, 1,225, 58, 0, 64, 15,220,220, 1,120,230, 4, 15, + 253,111,120,230, 3,135,135,198,180,253,119, 0,253, 54, 1,192, + 195, 39, 5,230, 7,245,213,229, 79,230, 4, 15,253,111,121,230, + 3,198, 64, 14, 6, 33,168, 16, 8, 58, 0, 64, 15,220,220, 1, + 8, 94,253,119, 0,198, 4,253,115, 1, 0,253,119, 0,198, 4, + 253,115, 1, 0,253,119, 0,198, 4,253,115, 1, 0,253,119, 0, + 198, 4,253,115, 1, 44, 13,194, 8, 11,225,209, 58, 0, 64, 15, + 220,220, 1,241, 79,246,240,221, 54, 0, 40,221,113, 1,221, 54, + 0, 40,221,119, 1,221, 54, 0, 40,221,113, 1, 58, 0, 64, 15, + 220,220, 1,201,120, 38, 17,198, 64,111,197,120, 70,205, 86, 8, + 193, 58, 0, 64, 15,220,220, 1,197,125,198, 8,111,120, 70,205, + 137, 9,193,125,198, 8,111,120,230, 3,198,180,253,119, 0,126, + 253,119, 1, 58, 0, 64, 15,220,220, 1,201, 33, 48, 17, 6, 3, + 197,126,203,127, 32, 6, 6, 15, 44,195, 0, 12,230,127, 71, 44, + 126,128, 71, 58, 0, 64, 15,220,220, 1,197, 44, 78, 44, 94, 44, + 86,235, 58, 0, 64, 15,220,220, 1,205,116, 1, 58, 0, 64, 15, + 220,220, 1,120,254,254,202, 39, 12,254,255,202, 60, 12,253,104, + 58, 0, 64, 15,220,220, 1,235,114, 45,115, 45,113, 45,193, 58, + 0, 64, 15,220,220, 1,253,125,128, 71,254, 16, 56, 2, 6, 15, + 58, 0, 64, 15,220,220, 1,120, 7, 7, 7,193,176, 15, 15, 15, + 246,144, 50, 17,127,125,214, 17,111, 58, 0, 64, 15,220,220, 1, + 5,242,160, 11,195, 60, 1, 58, 0, 64, 15,220,220, 1, 28,235, + 113, 44,115, 44,114,235, 29, 29, 29,195,194, 11, 58, 0, 64, 15, + 220,220, 1, 28,235, 78, 44, 94, 44, 86,235, 29, 29, 29,195,194, + 11,205,117, 12,195, 39, 5, 71, 58, 0, 64, 15,220,220, 1,120, + 229,230, 3, 33,136, 17,133,111,126,225,183,194,197, 3,120,205, + 117, 12,195, 14, 3,230, 3, 71, 8, 58, 0, 64, 15,220,220, 1, + 229, 38, 17,120, 15, 15, 15, 15,111,126,246,128,119, 58, 0, 64, + 15,220,220, 1,213, 44, 44, 84,125,198, 6, 95, 58, 0, 64, 15, + 220,220, 1, 26,119, 44, 28, 26,119, 44, 28, 26,119,209,225, 58, + 0, 64, 15,220,220, 1,205,116, 1, 58, 0, 64, 15,220,220, 1, + 8,229,213, 38, 16,104, 17, 17,127, 15, 15, 15, 70,176, 18, 44, + 126, 18,209,225,201,205,232, 12,195, 39, 5, 58,139, 17,183,194, + 197, 3,205,232, 12,195, 14, 3, 58, 0, 64, 15,220,220, 1,229, + 33, 48, 17,126,246,128,119, 58, 0, 64, 15,220,220, 1,213, 44, + 44, 84,125,198, 6, 95, 58, 0, 64, 15,220,220, 1, 26,119, 44, + 28, 26,119, 44, 28, 26,119,209,225, 58, 0, 64, 15,220,220, 1, + 205,116, 1, 58, 0, 64, 15,220,220, 1, 62,224,176, 50, 17,127, + 201,205, 85, 13,195, 39, 5, 71, 58, 0, 64, 15,220,220, 1,120, + 229,230, 3, 33,136, 17,133,111,126,225,183,194, 14, 3,120,205, + 85, 13,195, 14, 3,230, 3, 71, 58, 0, 64, 15,220,220, 1,229, + 38, 17,120, 15, 15, 15, 15,111,126,230,127,119,225,201,230, 3, + 8, 58, 0, 64, 15,220,220, 1,205,116, 1, 58, 0, 64, 15,220, + 220, 1, 8,229, 38, 17, 15, 15, 15, 15,111,126,230,128,176,119, + 225,195, 39, 5,230, 3, 8, 58, 0, 64, 15,220,220, 1,205,116, + 1, 58, 0, 64, 15,220,220, 1, 8,213,229,245, 17,136, 17,131, + 95, 26, 95, 58, 0, 64, 15,220,220, 1,241, 38, 17, 15, 15, 15, + 15,198, 15,111,112, 58, 0, 64, 15,220,220, 1,123,183, 32, 16, + 125,214, 15,111,126,230,128,176,119, 58, 0, 64, 15,220,220, 1, + 225,209,195, 14, 3,230, 3, 8, 58, 0, 64, 15,220,220, 1,205, + 116, 1, 58, 0, 64, 15,220,220, 1, 8,213,229, 22, 28, 88, 38, + 17, 15, 15, 15, 15,198, 10,111, 58, 0, 64, 15,220,220, 1, 26, + 119, 20, 45, 26,119, 20, 45, 26,119, 58, 0, 64, 15,220,220, 1, + 125,214, 8,111, 54, 0,225,209,195, 39, 5,230, 3, 8, 58, 0, + 64, 15,220,220, 1,205,116, 1, 58, 0, 64, 15,220,220, 1, 8, + 213,229, 22, 28, 88, 33,136, 17,245,133,111,241, 70, 38, 17, 15, + 15, 15, 15,198, 15,111, 58, 0, 64, 15,220,220, 1,119, 45, 26, + 119, 20, 45, 26,119, 20, 45, 26,119, 58, 0, 64, 15,220,220, 1, + 120,183,202,122, 14,225,209,195, 14, 3, 58, 0, 64, 15,220,220, + 1, 84,125,214, 4, 95,126, 18, 44, 28,126, 18, 44, 28,126, 18, + 58, 0, 64, 15,220,220, 1,125,214, 8,111, 54, 0,225,209,195, + 14, 3,205,198, 14,195, 39, 5, 71, 58, 0, 64, 15,220,220, 1, + 120,229,230, 15, 38, 17,198,128,111,126,225,183,194,179, 3,120, + 205,198, 14,195, 14, 3,230, 3, 8, 58, 0, 64, 15,220,220, 1, + 205,116, 1, 58, 0, 64, 15,220,220, 1, 8,213, 17, 17,127, 15, + 15, 15,176,246,128, 18, 58, 0, 64, 15,220,220, 1,205,116, 1, + 58, 0, 64, 15,220,220, 1,235,112,235,209,201,205, 25, 13,195, + 39, 5, 58,139, 17,183,194,197, 3,205, 25, 13,195, 14, 3,230, + 3, 71, 58, 0, 64, 15,220,220, 1,229, 38, 17,120,198,136,111, + 54, 1, 58, 0, 64, 15,220,220, 1,120, 15, 15, 15, 15,111, 38, + 17, 54, 0,225,195, 39, 5,205, 67, 15,195, 40, 1,205, 67, 15, + 195, 50, 1, 58, 0, 64, 15,220,220, 1,205,116, 1, 58, 0, 64, + 15,220,220, 1,235,114, 45,115, 45,113, 58, 0, 64, 15,220,220, + 1, 45,112,201,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, diff --git a/doc/api-asm.68k b/doc/api-asm.68k new file mode 100644 index 0000000..e6f466c --- /dev/null +++ b/doc/api-asm.68k @@ -0,0 +1,104 @@ +============================================================================= + +*** How to use *** + +You need to take "src-68k/echo.68k" and include it in your program. Then you +need to take "built/prog-z80.bin" (or if you built Echo from source, the +generated binary). Finally, go to the echo.68k file, look for @Z80Program +(should be near the end of the file) and change the filename to point where +the prog-z80.bin file is. + +Echo should now be inside your program. Now call Echo_Init (see below) to +initialize Echo and load the instrument list, and then you can proceed to use +Echo as needed (e.g. call Echo_PlayBGM to start playing music). + +Unless stated otherwise, calling the API subroutines will *not* modify the +68000 registers. + +============================================================================= + +*** Initialization *** + +Echo_Init + + Initializes Echo. Loads the instrument list, loads the Z80 engine and gets + it running. You need to call this before you can use Echo (usually when + the program is just starting). + + The address of the instrument list is given in register a0. The instrument + list can be built using the Echo_List* macros. An example of a short + instrument list is as follows: + + Echo_ListEntry instrument1 + Echo_ListEntry instrument2 + Echo_ListEntry instrument3 + Echo_ListEnd + + Where the parameter for Echo_ListEntry is the address (e.g. a label) to + the EIF/EEF/EWF data of the instrument. + +============================================================================= + +*** Background music *** + +Echo_PlayBGM + + Starts playback of the specified background music. The register a0 points + to the ESF data for the background music. + +Echo_StopBGM + + Stops playback of background music. Used both to stop and to pause music + (the latter can be undone with Echo_ResumeBGM, see below). + +Echo_ResumeBGM + + Resumes playback of whatever background music was playing last time before + Echo_StopBGM was called. Used when you want to unpause music. + +============================================================================= + +*** Sound effects *** + +Echo_PlaySFX + + Starts playback of the specified sound effect. The register a0 points to + the ESF data for the sound effect. + +Echo_StopSFX + + Stops playback of sound effects. + +============================================================================= + +*** Control *** + +Echo_GetStatus + + Gets the current status of Echo. The status is returned as a word in d0, + with the following bits set as relevant: + + Bit 0 .... Sound effect is playing + Bit 1 .... Background music is playing + Bit 15 ... Echo is busy (can't take commands) + + The API will automatically wait if you try to send a command while Echo is + busy, so the only reason to check for that is if you don't want to halt + the 68000 until Echo is ready to take more commands. + +============================================================================= + +*** Raw access *** + +Echo_SendCommand + + Sends an argument-less command to Echo. The command ID is given as a byte + in register d0. + +Echo_SendCommandEx + + Sends a command to Echo that takes an address as its argument. The command + ID is given as a byte in register d0, while the address argument is given + in register a0. + +============================================================================= diff --git a/doc/api-c.txt b/doc/api-c.txt new file mode 100644 index 0000000..fcfd07b --- /dev/null +++ b/doc/api-c.txt @@ -0,0 +1,120 @@ +============================================================================= + +*** How to use *** + +Add "echo.c" and "echoblob.h" in your program files. Then include the header +"echo.h" in whatever source files you need to access the Echo API, i.e. + + #include "echo.h" + +(these files are present in the "c" directory) + +Then use echo_init to initialize Echo and load the instrument list (see +below). After that you can use Echo as needed (e.g. call echo_play_bgm to +start playing music, etc.). + +The file "echoblob.h" is the Z80 binary turned into a C array. If you want to +change the blob, just use the included blob2c tool. It's invoked as follows: + + blob2c «input.bin» «output.h» + +============================================================================= + +*** Initialization *** + +void echo_init(const void **list) + + Initializes Echo. Loads the instrument list, loads the Z80 engine and gets + it running. You need to call this before you can use Echo (usually when + the program is just starting). + + The parameter 'list' is a pointer to an array of pointers, where each + entry points to the EIF/EEF/EWF data of each instrument. The list ends + with a NULL pointer. For example: + + const void* const list[] = { + instrument1, + instrument2, + instrument3, + NULL + }; + + (if NULL isn't defined for whatever reason just use 0 instead) + +============================================================================= + +*** Background music *** + +void echo_play_bgm(const void *esf) + + Starts playback of the specified background music. The parameter 'esf' + points to the ESF data for the background music. + +void echo_stop_bgm() + + Stops playback of background music. Used both to stop and to pause music + (the latter can be undone with echo_resume_bgm, see below). + +void echo_resume_bgm() + + Resumes playback of whatever background music was playing last time before + echo_stop_bgm was called. Used when you want to unpause music. + +============================================================================= + +*** Sound effects *** + +void echo_play_sfx(const void *esf) + + Starts playback of the specified sound effect. The parameter 'esf' points + to the ESF data for the sound effect. + +void echo_stop_sfx() + + Stops playback of sound effects. + +============================================================================= + +*** Control *** + +uint16_t echo_get_status() + + Gets the current status of Echo. Returns an OR of the following flags, + as relevant: + + ECHO_STAT_BGM .... Background music is playing + ECHO_STAT_SFX .... Sound effect is playing + ECHO_STAT_BUSY ... Echo is busy (can't take commands) + + The API will automatically wait if you try to send a command while Echo is + busy, so the only reason to check for that is if you don't want to halt + the 68000 until Echo is ready to take more commands. + +============================================================================= + +*** Raw access *** + +void echo_send_command(uint8_t command) + + Sends an argument-less command to Echo. The parameter 'command' is the + command to send, and may be one of the following: + + ECHO_CMD_STOPBGM ..... Stop background music playback + ECHO_CMD_RESUMEBGM ... Resume background music playback + ECHO_CMD_STOPSFX ..... Stop sound effect playback + +void echo_send_command_ex(uint8_t command, const void *address) + + Sends a command to Echo that takes an address as its argument. The + parameter 'command' is the command to send, while the parameter 'address' + is the address to use as argument. The command may be one of these: + + ECHO_CMD_PLAYBGM .... Start background music playback + ECHO_CMD_PLAYSFX .... Start sound effect playback + ECHO_CMD_LOADLIST ... Load instrument list (warning: see below) + + Do *NOT* use ECHO_CMD_LOADLIST unless you *REALLY* know you're doing, this + makes Echo load the instrument list by itself and it expects a different + format from the one used by the C API. + +============================================================================= diff --git a/doc/eef.txt b/doc/eef.txt new file mode 100644 index 0000000..c3ab92e --- /dev/null +++ b/doc/eef.txt @@ -0,0 +1,35 @@ +============================================================================= + +OVERVIEW + + EEF stands for "Echo Envelope Format" and it's the format in which PSG + instruments are stored. + +FORMAT + + EEF instruments consist of a list of volume levels. Each byte represents + a different volume level, and the value ranges from $00 (loudest) to $0F + (quietest). Each byte represents one tick (i.e. 1/60th of a second). + + Looping is possible. The start of the loop is marked by a byte with value + $FE, while the end of the loop is marked by a byte with value $FF. There + must be at least one volume byte between them or Echo will hang. + + To make a non-looping PSG instrument, just put the last volume value + inside the loop. + +============================================================================= + +NOTES + + Yes, this format was kind of an afterthought. Later I may improve it to + provide at least some kind of RLE-like compression, but for now you'll + have to stick with this :P + + Also, since PSG instruments are required to use PSG channels and I know + many of you don't want to mess with them at all, here's a flat PSG + instrument (i.e. no envelope): + + $FE,$00,$FF + +============================================================================= diff --git a/doc/eif.txt b/doc/eif.txt new file mode 100644 index 0000000..3d1f27d --- /dev/null +++ b/doc/eif.txt @@ -0,0 +1,27 @@ +============================================================================= + +OVERVIEW + + EIF stands for "Echo Instrument Format" and it's the format in which FM + instruments are stored. + +FORMAT + + EIF instruments are essentially raw dumps of the YM2612 registers. They + consist of 29 bytes, where each byte belongs to a different YM2612 + register. The registers are stored in the following order (assuming the + first FM channel): + + $B4 -- Algorithm and feedback + $30, $34, $38, $3C -- Multiplier and detune + $40, $44, $48, $4C -- Total level + $50, $54, $58, $5C -- Attack rate + $60, $64, $68, $6C -- Decay rate + $70, $74, $78, $7C -- Sustain rate + $80, $84, $88, $8C -- Release rate and sustain level + $90, $94, $98, $9C -- SSG-EG + + Some bits are unused and ignored by the YM2612. In an EIF instrument, + they *must* be 0, since Echo will rely on this for optimization purposes. + +============================================================================= diff --git a/doc/esf.txt b/doc/esf.txt new file mode 100644 index 0000000..a7b833e --- /dev/null +++ b/doc/esf.txt @@ -0,0 +1,355 @@ +============================================================================= + +OVERVIEW + + ESF stands for "Echo Stream Format". This is the format in which BGM and + SFX sequences are stored. Essentially this is the music arrangement data. + The format is mostly the same for both BGM and SFX, with just a few + exceptions. + +FORMAT + + ESF is a streamed format (think MIDI without the useless complexity). + It's stored as a sequence of events, where each event takes up between + one and three bytes. An event could be something like "note on", "set + volume", "stop", etc. + +CHANNEL LOCKING + + When both BGM and SFX are being played, it's likely that some channels + may get used by both. In this case, Echo will give the SFX privilege over + those channels. + + This is achieved by channel "locking". When the SFX starts, it first + locks the channels it needs to use. When the SFX ends, those channels get + unlocked. BGM won't play on the locked channels while the SFX is playing. + +============================================================================= + +EVENT LIST + + $00nn ..... Note on FM channel #1 + $01nn ..... Note on FM channel #2 + $02nn ..... Note on FM channel #3 + $04nn ..... Note on FM channel #4 + $05nn ..... Note on FM channel #5 + $06nn ..... Note on FM channel #6 + $08nn ..... Note on PSG channel #1 + $09nn ..... Note on PSG channel #2 + $0Ann ..... Note on PSG channel #3 + $0Bnn ..... Note on PSG channel #4 + $0Cnn ..... Note on PCM channel + + $10 ....... Note off FM channel #1 + $11 ....... Note off FM channel #2 + $12 ....... Note off FM channel #3 + $14 ....... Note off FM channel #4 + $15 ....... Note off FM channel #5 + $16 ....... Note off FM channel #6 + $18 ....... Note off PSG channel #1 + $19 ....... Note off PSG channel #2 + $1A ....... Note off PSG channel #3 + $1B ....... Note off PSG channel #4 + $1C ....... Note off PCM channel + + $20nn ..... Set volume FM channel #1 + $21nn ..... Set volume FM channel #2 + $22nn ..... Set volume FM channel #3 + $24nn ..... Set volume FM channel #4 + $25nn ..... Set volume FM channel #5 + $26nn ..... Set volume FM channel #6 + $28nn ..... Set volume PSG channel #1 + $29nn ..... Set volume PSG channel #2 + $2Ann ..... Set volume PSG channel #3 + $2Bnn ..... Set volume PSG channel #4 + + $30nnnn ... Set frequency FM channel #1 + $31nnnn ... Set frequency FM channel #2 + $32nnnn ... Set frequency FM channel #3 + $34nnnn ... Set frequency FM channel #4 + $35nnnn ... Set frequency FM channel #5 + $36nnnn ... Set frequency FM channel #6 + $38nnnn ... Set frequency PSG channel #1 + $39nnnn ... Set frequency PSG channel #2 + $3Annnn ... Set frequency PSG channel #3 + $3Bnn ..... Set noise type PSG channel #4 + + $40nn ..... Set instrument FM channel #1 + $41nn ..... Set instrument FM channel #2 + $42nn ..... Set instrument FM channel #3 + $44nn ..... Set instrument FM channel #4 + $45nn ..... Set instrument FM channel #5 + $46nn ..... Set instrument FM channel #6 + $48nn ..... Set instrument PSG channel #1 + $49nn ..... Set instrument PSG channel #2 + $4Ann ..... Set instrument PSG channel #3 + $4Bnn ..... Set instrument PSG channel #4 + + $E0 ....... [SFX] Lock FM channel #1 + $E1 ....... [SFX] Lock FM channel #2 + $E2 ....... [SFX] Lock FM channel #3 + $E4 ....... [SFX] Lock FM channel #4 + $E5 ....... [SFX] Lock FM channel #5 + $E6 ....... [SFX] Lock FM channel #6 + $E8 ....... [SFX] Lock PSG channel #1 + $E9 ....... [SFX] Lock PSG channel #2 + $EA ....... [SFX] Lock PSG channel #3 + $EB ....... [SFX] Lock PSG channel #4 + + $F0nn ..... Set parameters FM channel #1 + $F1nn ..... Set parameters FM channel #2 + $F2nn ..... Set parameters FM channel #3 + $F4nn ..... Set parameters FM channel #4 + $F5nn ..... Set parameters FM channel #5 + $F6nn ..... Set parameters FM channel #6 + + $FC ....... [BGM] Go to loop + $FD ....... [BGM] Set loop point + $FEnn ..... Delay ticks + $FF ....... Stop playback + +============================================================================= + +$00nn: Note on FM channel #1 +$01nn: Note on FM channel #2 +$02nn: Note on FM channel #3 +$04nn: Note on FM channel #4 +$05nn: Note on FM channel #5 +$06nn: Note on FM channel #6 + + These events do a "note on" at the specified FM channel. The event is + followed by a byte, which indicates which note to play. The value is as + follows, where "octave" ranges from 0 to 7 and "semitone" ranges from 0 + to 11: + + 32 * octave + 2 * semitone + 1 + +$08nn: Note on PSG channel #1 +$09nn: Note on PSG channel #2 +$0Ann: Note on PSG channel #3 + + These events do a "note on" at the specified square wave PSG channel. + The event is followed by a byte, which indicates which note to play. The + value is as follows, where "octave" ranges from 0 to 5 and "semitone" + ranges from 0 to 11: + + 24 * octave + 2 * semitone + +$0Bnn: Note on PSG channel #4 + + This event does a "note on" at the noise PSG channel. The event is + followed by a byte, which indicates what kind of noise to play. The + following values are valid: + + $00 ... Periodic noise, high pitch + $01 ... Periodic noise, medium pitch + $02 ... Periodic noise, low pitch + $03 ... Periodic noise, PSG3 frequency + $04 ... White noise, high pitch + $05 ... White noise, medium pitch + $06 ... White noise, low pitch + $07 ... White noise, PSG3 frequency + + When using values $03 and $07, the third square wave PSG channel controls + the noise frequency. You can change this frequency using the events to + change the frequency of that channel (usually you'd use event type $3A). + +$0Cnn: Note on PCM channel + + This event does a "note on" at the PCM channel. More specifically, it + starts playback of a PCM sample. This event is followed by a byte, that + specifies an index in the pointer list indicating where's the sample + data. Samples are stored as EWF (Echo Waveform Format). + + NOTE: FM channel #6 will be disabled. That channel will be re-enabled + when PCM playback is over (either because the waveform is over or because + the channel is stopped explicitly). + +============================================================================= + +$10: Note off FM channel #1 +$11: Note off FM channel #2 +$12: Note off FM channel #3 +$14: Note off FM channel #4 +$15: Note off FM channel #5 +$16: Note off FM channel #6 +$18: Note off PSG channel #1 +$19: Note off PSG channel #2 +$1A: Note off PSG channel #3 +$1B: Note off PSG channel #4 + + These events do a "note off" at the specified channel. + +$1C: Note off PCM channel + + This event does a "note off" at the PCM channel. This means that any PCM + playback is immediately stopped. FM channel #6 is immediately enabled as + well. + +============================================================================= + +$20nn: Set volume FM channel #1 +$21nn: Set volume FM channel #2 +$22nn: Set volume FM channel #3 +$24nn: Set volume FM channel #4 +$25nn: Set volume FM channel #5 +$26nn: Set volume FM channel #6 + + These events set the volume of a specific FM channel. The event is + followed by a byte, which indicates the new volume. A value of $00 is the + loudest, a value of $7F is the quietest. + +$28nn: Set volume PSG channel #1 +$29nn: Set volume PSG channel #2 +$2Ann: Set volume PSG channel #3 +$2Bnn: Set volume PSG channel #4 + + These events set the volume of a specific PSG channel. The event is + followed by a byte, which indicates the new volume. A value of $00 is the + loudest, a value of $0F is the quietest. + +============================================================================= + +$30nnnn: Set frequency FM channel #1 +$31nnnn: Set frequency FM channel #2 +$32nnnn: Set frequency FM channel #3 +$34nnnn: Set frequency FM channel #4 +$35nnnn: Set frequency FM channel #5 +$36nnnn: Set frequency FM channel #6 + + These events set the raw frequency of a specific FM channel, without + triggering a new note. Meant for note slides. The following two bytes + specify the new frequency in the same format as the YM2612 expects. The + first byte is register +$A4, the second byte is register +$A0. + + Echo uses the following frequency values for each semitone: + + C - 644 | E - 810 | G# - 1021 + C# - 681 | F - 858 | A - 1081 + D - 722 | F# - 910 | A# - 1146 + D# - 765 | G - 964 | B - 1214 + +$38nnnn: Set frequency PSG channel #1 +$39nnnn: Set frequency PSG channel #2 +$3Annnn: Set frequency PSG channel #3 + + These events set the raw frequency of a specific square wave PSG channel, + without triggering a new note. Meant for note slides. The following two + bytes specify the new frequency, the first byte containing the four least + significant bits (LSB aligned), and the next byte containing the six most + significant bits (LSB aligned too). + + Echo uses the following frequency values for each semitone: + + |Oct.0|Oct.1|Oct.2|Oct.3|Oct.4|Oct.5 + ---|-----|-----|-----|-----|-----|----- + C | 851 | 425 | 212 | 106 | 53 | 26 + C# | 803 | 401 | 200 | 100 | 50 | 25 + D | 758 | 379 | 189 | 94 | 47 | 23 + D# | 715 | 357 | 178 | 89 | 44 | 22 + E | 675 | 337 | 168 | 84 | 42 | 21 + F | 637 | 318 | 159 | 79 | 39 | 19 + F# | 601 | 300 | 150 | 75 | 37 | 18 + G | 568 | 284 | 142 | 71 | 35 | 17 + G# | 536 | 268 | 134 | 67 | 33 | 16 + A | 506 | 253 | 126 | 63 | 31 | 15 + A# | 477 | 238 | 119 | 59 | 29 | 14 + B | 450 | 225 | 112 | 56 | 28 | 14 + +$3Bnn: Set noise type PSG channel #4 + + This event works like event $0Bnn, but it doesn't trigger a note attack + (i.e. instrument envelope won't be reset, note won't start playing if it + wasn't already). + +============================================================================= + +$40nn: Set instrument FM channel #1 +$41nn: Set instrument FM channel #2 +$42nn: Set instrument FM channel #3 +$44nn: Set instrument FM channel #4 +$45nn: Set instrument FM channel #5 +$46nn: Set instrument FM channel #6 + + These events are used to set the instrument to be used by a specific FM + channel. The event is followed by a byte, which has an index in the + pointer list that indicates where's the FM instrument data. Instruments + are stored as EIF (Echo Instrument Format). + +$48nn: Set instrument PSG channel #1 +$49nn: Set instrument PSG channel #2 +$4Ann: Set instrument PSG channel #3 +$4Bnn: Set instrument PSG channel #4 + + These events are used to set the instrument to be used by a specific PSG + channel. The event is followed by a byte, which has an index in the + pointer list that indicates where's the PSG instrument data. Instruments + are stored as EEF (Echo Envelope Format). + +============================================================================= + +$E0: Lock FM channel #1 [SFX ONLY] +$E1: Lock FM channel #2 [SFX ONLY] +$E2: Lock FM channel #3 [SFX ONLY] +$E4: Lock FM channel #4 [SFX ONLY] +$E5: Lock FM channel #5 [SFX ONLY] +$E6: Lock FM channel #6 [SFX ONLY] +$E8: Lock PSG channel #1 [SFX ONLY] +$E9: Lock PSG channel #1 [SFX ONLY] +$EA: Lock PSG channel #1 [SFX ONLY] +$EB: Lock PSG channel #1 [SFX ONLY] + + These events are used to "lock" specific channels. When a channel is + locked, BGM can't mess up with it. All channels used by a SFX must be + locked before they're used. Channels get unlocked when the SFX stream is + over. + + To lock the PCM channel, you need to lock FM channel #6 (event $E6). Echo + will behave accordingly. + +============================================================================= + +$F0: Set parameters FM channel #1 +$F1: Set parameters FM channel #2 +$F2: Set parameters FM channel #3 +$F4: Set parameters FM channel #4 +$F5: Set parameters FM channel #5 +$F6: Set parameters FM channel #6 + + These events set up some miscellaneous parameters for the FM channels. + The event is followed by a byte, which speficies the new parameters to be + used. The format of this byte is as follows: + + Bit 7 ..... 1 to enable left speaker, 0 to mute it + Bit 6 ..... 1 to enable right speaker, 0 to mute it + Bit 5-0 ... Must be 0 + +============================================================================= + +$FC: Go to loop [BGM ONLY] +$FD: Set loop point [BGM ONLY] + + This event are used in BGM streams to loop music. Put event $FD where the + loop starts, and then end the stream using event $FC (don't use event + $FF). This will tell Echo to loop the song instead of stopping playback. + +$FEnn: Delay ticks + + This event is used for timing. It tells Echo to wait a specific amount of + ticks before continuing with the stream. A byte follows this event, it's + the amount of ticks to wait. If it's $00, then Echo waits 256 ticks + instead. + + If you need to wait more than 256 ticks, you can trigger this event + several times in a row. For example, to wait 320 ticks, use this event + twice: $FE00FE40 --> 256 ticks + 64 ticks = 320 ticks. + + One tick lasts 1/60th of a second. + +$FF: Stop playback + + This event indicates the end of the stream and tells Echo to stop + playback from this stream. If the stream was a SFX, then any locked + channels will be unlocked as well. + +============================================================================= diff --git a/doc/ewf.txt b/doc/ewf.txt new file mode 100644 index 0000000..e83dbbe --- /dev/null +++ b/doc/ewf.txt @@ -0,0 +1,15 @@ +============================================================================= + +OVERVIEW + + EWF stands for "Echo Waveform Format" and it's the format in which PCM + instruments are stored. + +FORMAT + + There isn't much to it. PCM data is stored as unsigned 8-bit, 10250 Hz, + mono. The bytes specifying the waveform data contain values ranging from + $00 to $FE. When a byte with value $FF is found, this is the end of the + waveform. + +============================================================================= diff --git a/src-68k/echo.68k b/src-68k/echo.68k index 1d02800..9b1341f 100644 --- a/src-68k/echo.68k +++ b/src-68k/echo.68k @@ -33,57 +33,6 @@ Echo_Z80Reset macro endm ; End of macro ;**************************************************************************** -; Echo_Init -; Initializes Echo -; -; input a0.l ... Address of pointer list -;**************************************************************************** - -Echo_Init: - movem.l d0/a0-a1, -(sp) ; Save registers - - Echo_Z80Reset ; May not work without this... - Echo_Z80Request ; We need the Z80 bus - - move.b #$01, ($A01FFF) ; Command: load pointer list - - move.l a0, d0 ; Easier to manipulate here - move.b d0, ($A01FFD) ; Store low address byte - lsr.l #7, d0 ; Get high address byte - lsr.b #1, d0 ; We skip one bit - bset.l #7, d0 ; Point into bank window - move.b d0, ($A01FFE) ; Store high address byte - lsr.w #8, d0 ; Get bank byte - move.w d0, d1 ; Parse 32X bit separately - lsr.w #1, d1 ; Put 32X bit in place - and.b #$7F, d0 ; Filter out unused bit from addresses - and.b #$80, d1 ; Filter out all but 32X bit - or.b d1, d0 ; Put everything together - move.b d0, ($A01FFC) ; Store bank byte - - lea @Z80Program(pc), a0 ; Where Z80 program starts - lea ($A00000), a1 ; Where Z80 RAM starts - move.w #@Z80ProgSize-1, d0 ; Size of Z80 program (DBF adjusted) -@LoadLoop: ; Go through all the program - move.b (a0)+, (a1)+ ; Copy byte into Z80 RAM - dbf d0, @LoadLoop ; Go for next byte - - Echo_Z80Reset ; Now reset for real - Echo_Z80Release ; Let the Z80 go! - - movem.l (sp)+, d0/a0-a1 ; Restore registers - rts ; End of subroutine - -;**************************************************************************** -; Echo Z80 program -; It should be located wherever Echo_ProgFile was defined -;**************************************************************************** - -@Z80Program: incbin "\Echo_ProgFile" -@Z80ProgSize equ *-@Z80Program - even - -;**************************************************************************** ; Echo_SendCommand ; Sends an Echo command (no address parameter) ; @@ -261,3 +210,54 @@ Echo_ListEnd macro dc.b $00 ; End of list mark even ; Just in case... endm + +;**************************************************************************** +; Echo_Init +; Initializes Echo +; +; input a0.l ... Address of pointer list +;**************************************************************************** + +Echo_Init: + movem.l d0/a0-a1, -(sp) ; Save registers + + Echo_Z80Reset ; May not work without this... + Echo_Z80Request ; We need the Z80 bus + + move.b #$01, ($A01FFF) ; Command: load pointer list + + move.l a0, d0 ; Easier to manipulate here + move.b d0, ($A01FFD) ; Store low address byte + lsr.l #7, d0 ; Get high address byte + lsr.b #1, d0 ; We skip one bit + bset.l #7, d0 ; Point into bank window + move.b d0, ($A01FFE) ; Store high address byte + lsr.w #8, d0 ; Get bank byte + move.w d0, d1 ; Parse 32X bit separately + lsr.w #1, d1 ; Put 32X bit in place + and.b #$7F, d0 ; Filter out unused bit from addresses + and.b #$80, d1 ; Filter out all but 32X bit + or.b d1, d0 ; Put everything together + move.b d0, ($A01FFC) ; Store bank byte + + lea @Z80Program(pc), a0 ; Where Z80 program starts + lea ($A00000), a1 ; Where Z80 RAM starts + move.w #@Z80ProgSize-1, d0 ; Size of Z80 program (DBF adjusted) +@LoadLoop: ; Go through all the program + move.b (a0)+, (a1)+ ; Copy byte into Z80 RAM + dbf d0, @LoadLoop ; Go for next byte + + Echo_Z80Reset ; Now reset for real + Echo_Z80Release ; Let the Z80 go! + + movem.l (sp)+, d0/a0-a1 ; Restore registers + rts ; End of subroutine + +;**************************************************************************** +; Echo Z80 program +; It should be located wherever Echo_ProgFile was defined +;**************************************************************************** + +@Z80Program: incbin "..." +@Z80ProgSize equ *-@Z80Program + even diff --git a/src-z80/core/main.z80 b/src-z80/core/main.z80 index 3a5a441..82c6bb0 100644 --- a/src-z80/core/main.z80 +++ b/src-z80/core/main.z80 @@ -225,69 +225,33 @@ LoadList: xor a ; Command parsed ld (RAM_Command), a - ld a, c ; Do initial bank switch - ld de, $6000 - ex de, hl - BankSwitch - ex de, hl - ld de, RAM_PointerList ; Where the pointer list starts .loop: - ld a, (hl) ; Get high address byte - or a ; Is it the end of the list? - jp z, .end ; If so, stop parsing list - ld (de), a ; Nope, store it in list - - inc d ; Get address for next byte - inc l - jr nz, .noswitch1 - inc h - jr nz, .noswitch1 - inc c - ld a, c - ld h, $60 - BankSwitch - ld h, $80 -.noswitch1: - - ld a, (hl) ; Get low address byte - ld (de), a ; Store it in pointer list - - inc d ; Get address for next byte - inc l - jr nz, .noswitch2 - inc h - jr nz, .noswitch2 - inc c - ld a, c - ld h, $60 - BankSwitch - ld h, $80 -.noswitch2: - - ld a, (hl) ; Get bank byte - ld (de), a ; Store it in pointer list - - dec d ; Get address for next byte + call GetParam ; Get high byte address + + ld a, b ; Is it the end of the list? + or a + jp z, .end + + ld (de), a ; Store high byte address + inc d + + call GetParam ; Get low address byte + ld a, b + ld (de), a + inc d + + call GetParam ; Get bank byte + ld a, b + ld (de), a + + dec d ; Go for next byte dec d inc e - inc l - jr nz, .noswitch3 - inc h - jr nz, .noswitch3 - inc c - ld a, c - ld h, $60 - BankSwitch - ld h, $80 -.noswitch3: - - jp .loop ; Go for next byte + jp .loop .end: - ld a, c ; Store current bank - ld (RAM_LastBank), a jp IdleLoop ; End of subroutine ;**************************************************************************** @@ -307,8 +271,6 @@ GetParam: .noswitchp: ld b, (hl) ; Get volume - ;PollPCM - inc l ; Get next address jp nz, .nonewbankp inc h |
