diff options
| -rw-r--r-- | LICENSE | 2 | ||||
| -rw-r--r-- | README | 12 | ||||
| -rw-r--r-- | built/old-builds/prog-z80-1.5.bin | bin | 0 -> 4864 bytes | |||
| -rw-r--r-- | built/prog-z80.bin | bin | 4864 -> 5120 bytes | |||
| -rw-r--r-- | c/echo.c | 19 | ||||
| -rw-r--r-- | c/echo.h | 5 | ||||
| -rw-r--r-- | c/echoblob.h | 524 | ||||
| -rw-r--r-- | doc/api-asm.68k | 24 | ||||
| -rw-r--r-- | doc/api-c.txt | 19 | ||||
| -rw-r--r-- | doc/eef.txt | 34 | ||||
| -rw-r--r-- | doc/esf.txt | 58 | ||||
| -rw-r--r-- | src-68k/echo.68k | 24 | ||||
| -rw-r--r-- | src-68k/esf.68k | 19 | ||||
| -rw-r--r-- | src-z80/core/bgm.z80 | 3 | ||||
| -rw-r--r-- | src-z80/core/main.z80 | 17 | ||||
| -rw-r--r-- | src-z80/core/sfx.z80 | 2 | ||||
| -rw-r--r-- | src-z80/core/vars.z80 | 3 | ||||
| -rw-r--r-- | src-z80/player/fm.z80 | 60 | ||||
| -rw-r--r-- | src-z80/player/freq.z80 | 6 | ||||
| -rw-r--r-- | src-z80/player/pcm (copia).z80 | 236 | ||||
| -rw-r--r-- | src-z80/player/psg.z80 | 130 |
21 files changed, 856 insertions, 341 deletions
@@ -1,4 +1,4 @@ -© 2010-2017 Javier Degirolmo +© 2010-2018 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 @@ -7,12 +7,12 @@ | | |_ |_ ___ | | | | | | | | | |_______ |_ |___| _| | | | | |_ |_____| _| |___________| |________| |___| |___| |_________| - ___ ___ _ _ ___ __ ___ ___ ___ _ ___ ___ _ ___ ___ - | _| | | | | \ | _| | _| | | _| | | | _|_ | - | |_| | | | | | | | | | |_| | | |_| | | | |_ _ _ ___ ___ | | | |_ _| | - |_ | | | | | | | | | | _| | | | | | | | _| | | | __| _ \ | | |_ | _| - _| | | | | | | | | | | |_| | | | | | | | |_ | | | __| /_ | |_ _| | |_ - |___|___|___|_|_|__/ |___|_|_|___|_|_|_|___| \_/|___|_|_\_| |_|_|___|___| + ___ ___ _ _ ___ __ ___ ___ ___ _ ___ ___ _ ___ + | _| | | | | \ | _| | _| | | _| | | | _| + | |_| | | | | | | | | | |_| | | |_| | | | |_ _ _ ___ ___ | | | |_ + |_ | | | | | | | | | | _| | | | | | | | _| | | | __| _ \ | | | | + _| | | | | | | | | | | |_| | | | | | | | |_ | | | __| /_ | |_| | | + |___|___|___|_|_|__/ |___|_|_|___|_|_|_|___| \_/|___|_|_\_| |_|_|___| ============================================================================= diff --git a/built/old-builds/prog-z80-1.5.bin b/built/old-builds/prog-z80-1.5.bin Binary files differnew file mode 100644 index 0000000..1658d7f --- /dev/null +++ b/built/old-builds/prog-z80-1.5.bin diff --git a/built/prog-z80.bin b/built/prog-z80.bin Binary files differindex 1658d7f..4f3cb3c 100644 --- a/built/prog-z80.bin +++ b/built/prog-z80.bin @@ -25,7 +25,7 @@ static volatile uint16_t* const z80_reset = (uint16_t *) 0xA11200; { volatile int16_t i; for (i = 0xFF; i >= 0; i--); } // Look-up tables for echo_set_volume -static const uint8_t fm_volumes[] = { +const uint8_t echo_fm_vol_table[0x40] = { 0x7F,0x7B,0x77,0x73,0x70,0x6C,0x68,0x65, 0x61,0x5E,0x5A,0x57,0x54,0x50,0x4D,0x4A, 0x47,0x44,0x41,0x3F,0x3C,0x39,0x36,0x34, @@ -35,7 +35,7 @@ static const uint8_t fm_volumes[] = { 0x08,0x07,0x06,0x05,0x04,0x04,0x03,0x02, 0x02,0x01,0x01,0x01,0x00,0x00,0x00,0x00 }; -static const uint8_t psg_volumes[] = { +const uint8_t echo_psg_vol_table[0x40] = { 0x0F,0x0F,0x0E,0x0E,0x0D,0x0D,0x0C,0x0C, 0x0B,0x0B,0x0B,0x0A,0x0A,0x0A,0x09,0x09, 0x08,0x08,0x08,0x07,0x07,0x07,0x06,0x06, @@ -306,7 +306,7 @@ void echo_set_volume(uint8_t vol) { Z80_REQUEST(); // Set FM volume values - uint8_t fm_vol = fm_volumes[vol >> 2]; + uint8_t fm_vol = echo_fm_vol_table[vol >> 2]; z80_ram[0x1FE0] = fm_vol; z80_ram[0x1FE1] = fm_vol; z80_ram[0x1FE2] = fm_vol; @@ -317,7 +317,7 @@ void echo_set_volume(uint8_t vol) { z80_ram[0x1FE7] = fm_vol; // Set PSG volume values - uint8_t psg_vol = psg_volumes[vol >> 2]; + uint8_t psg_vol = echo_psg_vol_table[vol >> 2]; z80_ram[0x1FE8] = psg_vol; z80_ram[0x1FE9] = psg_vol; z80_ram[0x1FEA] = psg_vol; @@ -368,6 +368,17 @@ void echo_set_pcm_rate(uint8_t rate) { } //*************************************************************************** +// echo_set_stereo +// Toggles stereo or mono. +//--------------------------------------------------------------------------- +// param enable: non-zero for stereo, zero for mono +//*************************************************************************** + +void echo_set_stereo(int enable) { + echo_send_command_byte(ECHO_CMD_SETSTEREO, !!enable); +} + +//*************************************************************************** // echo_get_status // Retrieves Echo's current status. //--------------------------------------------------------------------------- @@ -15,6 +15,7 @@ enum { ECHO_CMD_RESUMEBGM, /* 0x06 - Resume BGM playback */ ECHO_CMD_SETPCMRATE, /* 0x07 - Set PCM rate */ ECHO_CMD_PAUSEBGM, /* 0x08 - Pause BGM playback */ + ECHO_CMD_SETSTEREO, /* 0x09 - Toggle stereo */ }; /* Echo status flags */ @@ -47,4 +48,8 @@ void echo_send_command_byte(uint8_t cmd, uint8_t byte); static void (* const echo_send_command_ex)(uint8_t, const void *) = echo_send_command_addr; +/* Look-up tables */ +extern const uint8_t echo_fm_vol_table[0x40]; +extern const uint8_t echo_psg_vol_table[0x40]; + #endif diff --git a/c/echoblob.h b/c/echoblob.h index e4c8d4d..d570ecf 100644 --- a/c/echoblob.h +++ b/c/echoblob.h @@ -2,268 +2,284 @@ static uint8_t echo_blob[] = { 195,104, 1, 0, 0, 0, 0, 0,201,217,221, 54, 0, 39,221, 54, 1, 31,126, 60, 40, 12,221, 54, 0, 42,221,119, 1, 44, 40, 25, 217,201, 62,201, 50, 8, 0,221, 54, 0, 42,221, 54, 1,128,221, - 54, 0, 43,221, 54, 1, 0,217,201, 58,152, 18,185,202, 87, 0, - 121, 50,152, 18, 33, 0, 96,119, 15,119, 15,119, 15,119, 15,119, - 15,119, 15,119,116, 15,119, 33,240, 18, 26,119, 44, 28, 26,119, + 54, 0, 43,221, 54, 1, 0,217,201, 58,152, 19,185,202, 87, 0, + 121, 50,152, 19, 33, 0, 96,119, 15,119, 15,119, 15,119, 15,119, + 15,119, 15,119,116, 15,119, 33,240, 19, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28, 26,119, 44, 28,194,164, 0, 20,194,164, - 0, 22,128, 12, 46,240,195, 10, 0,205,193, 0,195,238, 5, 58, - 0, 64, 15,207, 58,142, 18,183,194,188, 4,205,193, 0,195, 7, - 4, 58,236, 31,183,200,205,234, 2,120,217, 38, 28,111, 86, 36, - 94, 36, 78, 33, 0, 96,121, 50,152, 18,119, 15,119, 15,119, 15, - 119, 15,119, 15,119, 15,119,116, 15,119, 38, 18,123,246,240,111, + 0, 22,128, 12, 46,240,195, 10, 0,205,193, 0,195, 0, 6, 58, + 0, 64, 15,207, 58,142, 19,183,194,205, 4,205,193, 0,195, 24, + 4, 58,236, 31,183,200,205,251, 2,120,217, 38, 28,111, 86, 36, + 94, 36, 78, 33, 0, 96,121, 50,152, 19,119, 15,119, 15,119, 15, + 119, 15,119, 15,119, 15,119,116, 15,119, 38, 19,123,246,240,111, 69, 26,119, 28, 44,194,241, 0,104,123,183,194, 5, 1, 20,194, 5, 1, 22,128, 12,217, 62,208, 50, 8, 0,221, 54, 0, 43,221, 54, 1,128,221, 54, 0, 42,221, 54, 1,128,201,205, 52, 1,195, - 238, 5, 58, 0, 64, 15,207, 58,142, 18,183,194, 7, 4,205, 52, - 1,195, 7, 4, 62,201, 50, 8, 0,221, 54, 0, 43,221, 54, 1, - 0,201, 62, 1, 50,142, 18,205, 52, 1,195,238, 5, 58,252, 31, + 0, 6, 58, 0, 64, 15,207, 58,142, 19,183,194, 24, 4,205, 52, + 1,195, 24, 4, 62,201, 50, 8, 0,221, 54, 0, 43,221, 54, 1, + 0,201, 62, 1, 50,142, 19,205, 52, 1,195, 0, 6, 58,252, 31, 47, 71, 33, 0, 64, 54, 36, 15, 15,246,192, 44,119,120, 45, 54, - 37,230, 3, 44,119,195, 81, 2,175, 50,240, 31, 50,251, 31, 49, + 37,230, 3, 44,119,195, 98, 2,175, 50,240, 31, 50,251, 31, 49, 224, 31, 33, 17,127, 54,159, 54,191, 54,223, 54,255,175, 50, 0, - 18, 50, 16, 18, 50, 32, 18, 50, 48, 18, 33, 0, 96,117,117,117, - 117,117,117,117,117,117,221, 33, 0, 64,253, 38, 64,217, 6, 0, - 217,221, 54, 0, 43,221, 54, 1, 0, 30,127, 62, 64, 6, 4,221, - 119, 0,221,115, 1,221,119, 2,221,115, 3, 60,221,119, 0,221, + 19, 50, 16, 19, 50, 32, 19, 50, 48, 19, 61, 50, 11, 19, 50, 27, + 19, 50, 43, 19, 50, 59, 19, 33, 0, 96,117,117,117,117,117,117, + 117,117,117,221, 33, 0, 64,253, 38, 64,217, 6, 0,217,221, 54, + 0, 43,221, 54, 1, 0, 30,127, 62, 64, 6, 4,221,119, 0,221, 115, 1,221,119, 2,221,115, 3, 60,221,119, 0,221,115, 1,221, - 119, 2,221,115, 3, 60, 60, 16,214,221, 54, 0,180,221, 54, 1, - 192,221, 54, 0,181,221, 54, 1,192,221, 54, 0,182,221, 54, 1, - 192,221, 54, 2,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,102, 2, 61,202,194, 2, - 61,202,137, 5, 61,202,164, 6, 61,202, 23, 3, 61,202,213, 4, - 61,202,181, 3, 61,202, 77, 1, 61,202, 93, 3, 58, 0, 64, 15, - 207, 42,248, 31, 34,252, 31, 42,250, 31, 34,254, 31,175, 50,251, - 31, 58, 0, 64, 15,207, 58,255, 31,183, 32,192, 58, 0, 64, 15, - 207, 58, 0, 64,203, 79, 32, 8,203, 71,196, 8, 0,195,102, 2, - 58, 0, 64, 15,207,221, 54, 0, 39,221, 54, 1, 47, 58, 0, 64, - 15,207, 58,241, 31,183,196, 71, 16,195,156, 2, 58, 0, 64, 15, - 207,205, 94, 7, 58, 0, 64, 15,207, 58,169, 18,183, 32, 3,195, - 178, 2, 58, 0, 64, 15,207,195,136, 12, 58, 0, 64, 15,207,195, - 102, 2, 42,253, 31, 58,252, 31, 79, 17, 0, 28,205,234, 2,120, - 183,202,231, 2, 18, 20,205,234, 2,120, 18, 20,205,234, 2,120, - 18, 21, 21, 28,195,204, 2,195, 81, 2, 58,152, 18,185,202, 10, - 3,121, 50,152, 18,229, 33, 0, 96,119, 15,119, 15,119, 15,119, - 15,119, 15,119, 15,119,116, 15,119,225, 70, 44,194, 22, 3, 36, - 194, 22, 3, 38,128, 12,201, 58, 0, 64, 15,207,205,251, 4, 58, - 0, 64, 15,207, 58,240, 31,246, 2, 50,240, 31, 58, 0, 64, 15, - 207, 33,252, 31, 78, 44, 94, 44, 86, 58, 0, 64, 15,207,175, 50, - 169, 18, 60, 33,153, 18,119, 44,119, 44,113, 44,115, 44,114, 58, - 0, 64, 15,207, 33,234, 3, 34,176, 2,195, 81, 2, 58,153, 18, - 183,202, 81, 2, 62, 1, 50,169, 18, 6,127, 14, 7, 33,143, 18, - 58, 0, 64, 15,207,126,183, 32, 4,121,205, 54, 10, 58, 0, 64, - 15,207, 45, 13,242,112, 3, 6, 4, 14, 15, 17,144, 18, 33, 0, - 18, 58, 0, 64, 15,207, 26,183, 32, 5,126,230,128,177,119, 58, - 0, 64, 15,207,125,198, 16,111, 28, 16,230, 58,142, 18,183,204, - 52, 1,195, 81, 2, 58,153, 18,183,202, 81, 2,175, 50,169, 18, - 6, 4, 17,147, 18, 33, 63, 18, 58, 0, 64, 15,207, 78,125,214, - 15,111, 26,183, 32, 5,126,230,128,177,119, 58, 0, 64, 15,207, - 45, 29, 16,228,205, 71, 16,195, 81, 2, 58, 0, 64, 15,207, 33, - 154, 18,126, 61,202,251, 3,119,195,178, 2, 58, 0, 64, 15,207, - 44, 78, 44, 94, 44, 86,235, 58, 0, 64, 15,207,205,234, 2, 58, - 0, 64, 15,207,120,254, 8,218,138, 7,254, 11,218, 52, 13,202, - 172, 13,254, 12,202,175, 0, 58, 0, 64, 15,207,120,254, 24,218, - 27, 8,254, 28,218,254, 13,202, 34, 1, 58, 0, 64, 15,207,120, - 254,254,202,208, 15,254,255,202,207, 4,254,252,202,107, 5,254, - 253,202,122, 5, 58, 0, 64, 15,207,120,254, 40,218,229, 9,254, - 44,218, 83, 14, 58, 0, 64, 15,207,120,254, 56,218, 71, 8,254, - 59,218, 73, 15,202,153, 15, 58, 0, 64, 15,207,120,254, 72,218, - 182, 8,254, 76,218,216, 14, 58, 0, 64, 15,207,120,254,224,218, - 224, 15,254,248,218, 47, 11,254,250,218,128, 11,202, 11, 16,254, - 251,202, 44, 16, 58, 0, 64, 15,207,195,207, 4, 58, 0, 64, 15, - 207, 44,194,188, 4, 36,194,188, 4, 38,128, 12, 58, 0, 64, 15, - 207, 44,194,204, 4, 36,194,204, 4, 38,128, 12,195, 7, 4,205, - 219, 4,195,178, 2,205,219, 4,195, 81, 2, 58,240, 31,230,253, - 50,240, 31, 58, 0, 64, 15,207,205,251, 4, 58, 0, 64, 15,207, - 175, 50,153, 18, 33,178, 2, 34,176, 2,201, 58,142, 18,183,204, - 52, 1, 6, 4, 17, 63, 18, 33,147, 18, 58, 0, 64, 15,207, 54, - 0,123,214, 15, 95,126,183, 32, 2,175, 18, 58, 0, 64, 15,207, - 29, 45, 16,230, 6, 8, 17, 79, 18, 58, 0, 64, 15,207, 62,127, - 18, 29, 58, 0, 64, 15,207,126,183,194, 88, 5, 5,120,205,216, - 11, 58, 0, 64, 15,207,120,230, 4,253,111,120,230, 3,198,180, - 253,119, 0,253, 54, 1,192, 4, 45, 16,206, 33, 80, 18, 62,192, - 6, 8,119, 44, 16,252,175, 50,242, 31,201, 58, 0, 64, 15,207, - 42,159, 18, 58,158, 18, 79,195, 7, 4, 58, 0, 64, 15,207,121, - 50,158, 18, 34,159, 18,195, 7, 4, 58, 0, 64, 15,207,205,212, - 6, 58, 0, 64, 15,207, 58,240, 31,246, 1, 50,240, 31, 58, 0, - 64, 15,207, 33,252, 31, 78, 44, 94, 44, 86, 58, 0, 64, 15,207, - 33,161, 18, 54, 1, 44, 54, 1, 44,113, 44,115, 44,114, 58, 0, - 64, 15,207, 33,209, 5, 34,154, 2, 58, 0, 64, 15,207,195, 81, - 2, 58, 0, 64, 15,207, 33,162, 18,126, 61,202,226, 5,119,195, - 156, 2, 58, 0, 64, 15,207, 44, 78, 44, 94, 44, 86,235, 58, 0, - 64, 15,207,205,234, 2, 58, 0, 64, 15,207,120,254, 8,218,132, - 7,254, 11,218, 46, 13,202,166, 13,254, 12,202,169, 0, 58, 0, - 64, 15,207,120,254, 24,218, 21, 8,254, 28,218,248, 13,202, 28, - 1, 58, 0, 64, 15,207,120,254,254,202,202, 15,254,255,202,158, - 6, 58, 0, 64, 15,207,120,254, 40,218,208, 9,254, 44,218, 49, - 14, 58, 0, 64, 15,207,120,254, 56,218, 65, 8,254, 59,218, 67, - 15,202,147, 15, 58, 0, 64, 15,207,120,254, 72,218,176, 8,254, - 76,218,154, 14, 58, 0, 64, 15,207,120,254,224,218,214, 15,254, - 232,218,170, 11,254,236,218,166, 15,202, 66, 1, 58, 0, 64, 15, - 207,120,254,248,218, 6, 11,254,250,218,122, 11,202, 5, 16,254, - 251,202, 38, 16,254,252,202, 64, 7,254,253,202, 79, 7,205,170, - 6,195,156, 2,205,170, 6,195, 81, 2, 58, 0, 64, 15,207, 58, - 240, 31,230,254, 50,240, 31, 58, 0, 64, 15,207,175, 50,161, 18, - 33,156, 2, 34,154, 2, 58, 0, 64, 15,207,205,212, 6, 58, 0, - 64, 15,207,201, 58,142, 18,183,196, 52, 1, 6, 4, 17,147, 18, - 58, 0, 64, 15,207, 26,183, 40, 56,175, 18, 58, 0, 64, 15,207, - 120, 15, 15, 15, 15, 61, 38, 18,111, 78,214, 15,111,113, 58, 0, - 64, 15,207,213,125,198, 8,111,198, 4, 95, 84, 58, 0, 64, 15, - 207, 26,119, 44, 28, 26,119, 44, 28, 26,119,209, 58, 0, 64, 15, - 207, 29, 16,188, 6, 8, 58, 0, 64, 15,207, 26,183,202, 60, 7, - 175, 18, 58, 0, 64, 15,207, 5,205, 85, 12, 4, 29, 16,231,201, - 58, 0, 64, 15,207, 42,167, 18, 58,166, 18, 79,195,238, 5, 58, - 0, 64, 15,207,121, 50,166, 18, 34,167, 18,195,238, 5, 58, 0, - 31, 60,200, 58, 0, 64, 15,207, 33,120, 7, 34, 72, 4, 33, 0, - 31, 58,152, 18, 79,195, 7, 4, 33,207, 4, 34, 72, 4, 62,255, - 50, 0, 31,201,205,166, 7,195,238, 5, 71, 58, 0, 64, 15,207, - 229,120,230, 7, 33,136, 18,133,111,126,225,183,194,188, 4,120, - 205,166, 7,195, 7, 4,230, 7,221, 54, 0, 40,221,119, 1, 71, - 8, 58, 0, 64, 15,207,120,230, 4, 15,253,111, 58, 0, 64, 15, - 207,205,234, 2, 58, 0, 64, 15,207, 8,213,229, 87,230, 3,198, - 164, 95, 58, 0, 64, 15,207, 38, 17,120,230, 31,198,144,111, 58, - 0, 64, 15,207,120,230,224, 15, 15, 71,126,176,253,115, 0,253, - 119, 1, 58, 0, 64, 15,207,123,214, 4, 95, 45,126,253,115, 0, - 253,119, 1, 58, 0, 64, 15,207,122,246,240,221, 54, 0, 40,221, - 119, 1,225,209,201,205, 55, 8,195,238, 5, 71, 58, 0, 64, 15, - 207,120,229,230, 7, 33,136, 18,133,111,126,225,183,194, 7, 4, - 120,205, 55, 8,195, 7, 4,230, 7,221, 54, 0, 40,221,119, 1, - 201,205, 99, 8,195,238, 5, 71, 58, 0, 64, 15,207,120,229,230, - 7, 33,136, 18,133,111,126,225,183,194,172, 4,120,205, 99, 8, - 195, 7, 4,245, 71, 58, 0, 64, 15,207,120,230, 4, 15,253,111, - 58, 0, 64, 15,207,205,234, 2, 58, 0, 64, 15,207,241,213,230, - 7, 87,230, 3,198,164, 95, 58, 0, 64, 15,207,253,115, 0,253, - 112, 1, 58, 0, 64, 15,207,205,234, 2, 58, 0, 64, 15,207,123, - 214, 4, 95,253,115, 0,253,112, 1, 58, 0, 64, 15,207,209,201, - 205, 12, 9,195,238, 5,230, 7, 71, 58, 0, 64, 15,207,213,197, - 120, 17, 64, 18,131, 95, 58, 0, 64, 15,207,205,234, 2, 58, 0, - 64, 15,207,120, 18,123,198, 8, 95,175, 18, 89,193, 75,209, 58, - 0, 64, 15,207,229,120, 38, 18,198,136,111,126,225,183,194, 7, - 4, 58, 0, 64, 15,207,120,229, 33, 64, 18,133,111, 70,225, 8, - 58, 0, 64, 15,207, 8,205, 29, 9,195, 7, 4,230, 7, 8, 58, - 0, 64, 15,207,205,234, 2, 58, 0, 64, 15,207, 8,245,230, 4, - 15,253,111, 58, 0, 64, 15,207,241,197,213,229, 38, 28,104, 86, - 36, 94, 36, 78,235,245, 58, 0, 64, 15,207, 6, 7, 17,176, 18, - 120, 8,205,234, 2,235,112,235, 28,205,234, 2,235,112,235, 28, - 205,234, 2,235,112,235, 28,205,234, 2,235,112,235, 28, 8, 71, - 16,222,205,234, 2,235,112,235, 58, 0, 64, 15,207,241, 71,205, - 216, 11,120, 17, 96, 18,230, 7,131, 95,245,230, 3,198,176, 33, - 176, 18, 8, 58, 0, 64, 15,207, 8,253,119, 0, 70, 44,253,112, - 1, 8,120, 18,123,198, 8, 95, 58, 0, 64, 15,207, 8,214,128, - 6, 28,253,119, 0, 78,253,113, 1,198, 4, 44, 16,244, 58, 0, - 64, 15,207,125,214, 24,111, 6, 4,126, 18,123,198, 8, 95, 44, - 16,247, 58, 0, 64, 15,207,241,225,209,193, 6, 0,195, 60, 10, - 245, 58, 0, 64, 15,207,205,234, 2, 58, 0, 64, 15,207,241,205, - 60, 10,195,238, 5,230, 7, 71, 58, 0, 64, 15,207,213,197,120, - 22, 18,198, 72, 95, 58, 0, 64, 15,207,205,234, 2, 58, 0, 64, - 15,207,235,112,235, 89,193, 75,209, 58, 0, 64, 15,207,229,120, - 33,136, 18,133,111,126,225,183,194, 7, 4, 58, 0, 64, 15,207, - 120,229, 33, 72, 18,133,111, 70,225,245, 58, 0, 64, 15,207,241, - 205, 60, 10,195, 7, 4,197,213,229,195, 73, 10,197,213,229,230, - 7,245, 38, 18,198, 88,111,112,241,245, 38, 18,198, 96,111, 8, - 58, 0, 64, 15,207, 8,230, 7,246,224, 22, 31, 95, 8, 26, 87, - 58, 0, 64, 15,207, 8,230, 4, 15,253,111, 58, 0, 64, 15,207, - 241,230, 3,198, 64, 79,126,230, 7, 95, 58, 0, 64, 15,207,125, - 198, 8,111,123,254, 7, 56, 17,253,113, 0,126,130,250,148, 10, - 128,242,150, 10, 62,127,253,119, 1,121,198, 4, 79, 58, 0, 64, - 15,207,125,198, 8,111,123,254, 5, 56, 17,253,113, 0,126,130, - 250,183, 10,128,242,185, 10, 62,127,253,119, 1,121,198, 4, 79, - 58, 0, 64, 15,207,125,198, 8,111,123,254, 4, 56, 17,253,113, - 0,126,130,250,218, 10,128,242,220, 10, 62,127,253,119, 1,121, - 198, 4, 79, 58, 0, 64, 15,207,125,198, 8,111,253,113, 0,126, - 130,250,248, 10,128,242,250, 10, 62,127,253,119, 1, 58, 0, 64, - 15,207,225,209,193,201, 71, 58, 0, 64, 15,207,120,230, 4, 15, - 253,111,120, 8, 58, 0, 64, 15,207,205,234, 2, 58, 0, 64, 15, - 207, 8,230, 3,198,180,253,119, 0,253,112, 1,195,238, 5, 71, + 119, 2,221,115, 3, 60,221,119, 0,221,115, 1,221,119, 2,221, + 115, 3, 60, 60, 16,214,221, 54, 0,180,221, 54, 1,192,221, 54, + 0,181,221, 54, 1,192,221, 54, 0,182,221, 54, 1,192,221, 54, + 2,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,119, 2, 61,202,211, 2, 61,202,155, + 5, 61,202,182, 6, 61,202, 40, 3, 61,202,230, 4, 61,202,198, + 3, 61,202, 77, 1, 61,202,110, 3, 61,202,217, 12, 58, 0, 64, + 15,207, 42,248, 31, 34,252, 31, 42,250, 31, 34,254, 31,175, 50, + 251, 31, 58, 0, 64, 15,207, 58,255, 31,183, 32,188, 58, 0, 64, + 15,207, 58, 0, 64,203, 79, 32, 8,203, 71,196, 8, 0,195,119, + 2, 58, 0, 64, 15,207,221, 54, 0, 39,221, 54, 1, 47, 58, 0, + 64, 15,207, 58,241, 31,183,196, 33, 17,195,173, 2, 58, 0, 64, + 15,207,205,116, 7, 58, 0, 64, 15,207, 58,169, 19,183, 32, 3, + 195,195, 2, 58, 0, 64, 15,207,195,226, 12, 58, 0, 64, 15,207, + 195,119, 2, 42,253, 31, 58,252, 31, 79, 17, 0, 28,205,251, 2, + 120,183,202,248, 2, 18, 20,205,251, 2,120, 18, 20,205,251, 2, + 120, 18, 21, 21, 28,195,221, 2,195, 98, 2, 58,152, 19,185,202, + 27, 3,121, 50,152, 19,229, 33, 0, 96,119, 15,119, 15,119, 15, + 119, 15,119, 15,119, 15,119,116, 15,119,225, 70, 44,194, 39, 3, + 36,194, 39, 3, 38,128, 12,201, 58, 0, 64, 15,207,205, 12, 5, + 58, 0, 64, 15,207, 58,240, 31,246, 2, 50,240, 31, 58, 0, 64, + 15,207, 33,252, 31, 78, 44, 94, 44, 86, 58, 0, 64, 15,207,175, + 50,169, 19, 60, 33,153, 19,119, 44,119, 44,113, 44,115, 44,114, + 58, 0, 64, 15,207, 33,251, 3, 34,193, 2,195, 98, 2, 58,153, + 19,183,202, 98, 2, 62, 1, 50,169, 19, 6,127, 14, 7, 33,143, + 19, 58, 0, 64, 15,207,126,183, 32, 4,121,205, 87, 10, 58, 0, + 64, 15,207, 45, 13,242,129, 3, 6, 4, 14, 15, 17,144, 19, 33, + 0, 19, 58, 0, 64, 15,207, 26,183, 32, 5,126,230,128,177,119, + 58, 0, 64, 15,207,125,198, 16,111, 28, 16,230, 58,142, 19,183, + 204, 52, 1,195, 98, 2, 58,153, 19,183,202, 98, 2,175, 50,169, + 19, 6, 4, 17,147, 19, 33, 63, 19, 58, 0, 64, 15,207, 78,125, + 214, 15,111, 26,183, 32, 5,126,230,128,177,119, 58, 0, 64, 15, + 207, 45, 29, 16,228,205, 33, 17,195, 98, 2, 58, 0, 64, 15,207, + 33,154, 19,126, 61,202, 12, 4,119,195,195, 2, 58, 0, 64, 15, + 207, 44, 78, 44, 94, 44, 86,235, 58, 0, 64, 15,207,205,251, 2, + 58, 0, 64, 15,207,120,254, 8,218,160, 7,254, 11,218,220, 13, + 202, 74, 14,254, 12,202,175, 0, 58, 0, 64, 15,207,120,254, 24, + 218, 49, 8,254, 28,218,156, 14,202, 34, 1, 58, 0, 64, 15,207, + 120,254,254,202,170, 16,254,255,202,224, 4,254,252,202,125, 5, + 254,253,202,140, 5, 58, 0, 64, 15,207,120,254, 40,218, 6, 10, + 254, 44,218,253, 14, 58, 0, 64, 15,207,120,254, 56,218, 93, 8, + 254, 59,218,243, 15,202,115, 16, 58, 0, 64, 15,207,120,254, 72, + 218,215, 8,254, 76,218,130, 15, 58, 0, 64, 15,207,120,254,224, + 218,186, 16,254,248,218, 95, 11,254,250,218,191, 11,202,229, 16, + 254,251,202, 6, 17, 58, 0, 64, 15,207,195,224, 4, 58, 0, 64, + 15,207, 44,194,205, 4, 36,194,205, 4, 38,128, 12, 58, 0, 64, + 15,207, 44,194,221, 4, 36,194,221, 4, 38,128, 12,195, 24, 4, + 205,236, 4,195,195, 2,205,236, 4,195, 98, 2, 58,240, 31,230, + 253, 50,240, 31, 58, 0, 64, 15,207,205, 12, 5, 58, 0, 64, 15, + 207,175, 50,153, 19, 33,195, 2, 34,193, 2,201, 58,142, 19,183, + 204, 52, 1, 6, 4, 17, 63, 19, 33,147, 19, 58, 0, 64, 15,207, + 54, 0,123,214, 15, 95,126,183, 32, 2,175, 18, 58, 0, 64, 15, + 207, 29, 45, 16,230, 6, 8, 17, 79, 19, 58, 0, 64, 15,207, 62, + 127, 18, 29, 58, 0, 64, 15,207,126,183,194,106, 5, 5,120,205, + 23, 12, 58, 0, 64, 15,207,120,230, 4, 15,253,111,120,230, 3, + 198,180,253,119, 0,253, 54, 1,192, 4, 45, 16,205, 33, 80, 19, + 62,192, 6, 8,119, 44, 16,252,175, 50,242, 31,201, 58, 0, 64, + 15,207, 42,159, 19, 58,158, 19, 79,195, 24, 4, 58, 0, 64, 15, + 207,121, 50,158, 19, 34,159, 19,195, 24, 4, 58, 0, 64, 15,207, + 205,230, 6, 58, 0, 64, 15,207, 58,240, 31,246, 1, 50,240, 31, + 58, 0, 64, 15,207, 33,252, 31, 78, 44, 94, 44, 86, 58, 0, 64, + 15,207, 33,161, 19, 54, 1, 44, 54, 1, 44,113, 44,115, 44,114, + 58, 0, 64, 15,207, 33,227, 5, 34,171, 2, 58, 0, 64, 15,207, + 195, 98, 2, 58, 0, 64, 15,207, 33,162, 19,126, 61,202,244, 5, + 119,195,173, 2, 58, 0, 64, 15,207, 44, 78, 44, 94, 44, 86,235, + 58, 0, 64, 15,207,205,251, 2, 58, 0, 64, 15,207,120,254, 8, + 218,154, 7,254, 11,218,214, 13,202, 68, 14,254, 12,202,169, 0, + 58, 0, 64, 15,207,120,254, 24,218, 43, 8,254, 28,218,150, 14, + 202, 28, 1, 58, 0, 64, 15,207,120,254,254,202,164, 16,254,255, + 202,176, 6, 58, 0, 64, 15,207,120,254, 40,218,241, 9,254, 44, + 218,219, 14, 58, 0, 64, 15,207,120,254, 56,218, 87, 8,254, 59, + 218,237, 15,202,109, 16, 58, 0, 64, 15,207,120,254, 72,218,209, + 8,254, 76,218, 68, 15, 58, 0, 64, 15,207,120,254,224,218,176, + 16,254,232,218,233, 11,254,236,218,128, 16,202, 66, 1, 58, 0, + 64, 15,207,120,254,248,218, 39, 11,254,250,218,185, 11,202,223, + 16,254,251,202, 0, 17,254,252,202, 86, 7,254,253,202,101, 7, + 205,188, 6,195,173, 2,205,188, 6,195, 98, 2, 58, 0, 64, 15, + 207, 58,240, 31,230,254, 50,240, 31, 58, 0, 64, 15,207,175, 50, + 161, 19, 33,173, 2, 34,171, 2, 58, 0, 64, 15,207,205,230, 6, + 58, 0, 64, 15,207,201, 58,142, 19,183,196, 52, 1, 6, 4, 17, + 147, 19, 58, 0, 64, 15,207, 26,183, 40, 56,175, 18, 58, 0, 64, + 15,207,120, 15, 15, 15, 15, 61, 38, 19,111, 78,214, 15,111,113, + 58, 0, 64, 15,207,213,125,198, 8,111,198, 4, 95, 84, 58, 0, + 64, 15,207, 26,119, 44, 28, 26,119, 44, 28, 26,119,209, 58, 0, + 64, 15,207, 29, 16,188, 6, 8, 58, 0, 64, 15,207, 26,183,202, + 82, 7,175, 18, 58, 0, 64, 15,207, 5,120,205, 23, 12,205,166, + 12, 4, 29, 16,227,201, 58, 0, 64, 15,207, 42,167, 19, 58,166, + 19, 79,195, 0, 6, 58, 0, 64, 15,207,121, 50,166, 19, 34,167, + 19,195, 0, 6, 58, 0, 31, 60,200, 58, 0, 64, 15,207, 33,142, + 7, 34, 89, 4, 33, 0, 31, 58,152, 19, 79,195, 24, 4, 33,224, + 4, 34, 89, 4, 62,255, 50, 0, 31,201,205,188, 7,195, 0, 6, + 71, 58, 0, 64, 15,207,229,120,230, 7, 33,136, 19,133,111,126, + 225,183,194,205, 4,120,205,188, 7,195, 24, 4,230, 7,221, 54, + 0, 40,221,119, 1, 71, 8, 58, 0, 64, 15,207,120,230, 4, 15, + 253,111, 58, 0, 64, 15,207,205,251, 2, 58, 0, 64, 15,207, 8, + 213,229, 87,230, 3,198,164, 95, 58, 0, 64, 15,207, 38, 18,120, + 230, 31,198,144,111, 58, 0, 64, 15,207,120,230,224, 15, 15, 71, + 126,176,253,115, 0,253,119, 1, 58, 0, 64, 15,207,123,214, 4, + 95, 45,126,253,115, 0,253,119, 1, 58, 0, 64, 15,207,122,246, + 240,221, 54, 0, 40,221,119, 1,225,209,201,205, 77, 8,195, 0, + 6, 71, 58, 0, 64, 15,207,120,229,230, 7, 33,136, 19,133,111, + 126,225,183,194, 24, 4,120,205, 77, 8,195, 24, 4,230, 7,221, + 54, 0, 40,221,119, 1,201,205,121, 8,195, 0, 6, 71, 58, 0, + 64, 15,207,120,229,230, 7, 33,136, 19,133,111,126,225,183,194, + 189, 4,120,205,121, 8,195, 24, 4, 71, 8, 58, 0, 64, 15,207, + 120,230, 4, 15,253,111, 58, 0, 64, 15,207,205,251, 2, 58, 0, + 64, 15,207,120,135,218,203, 8, 8,213,230, 7, 87,230, 3,198, + 164, 95, 58, 0, 64, 15,207,253,115, 0,253,112, 1, 58, 0, 64, + 15,207,205,251, 2, 58, 0, 64, 15,207,123,214, 4, 95,253,115, + 0,253,112, 1, 58, 0, 64, 15,207,209,201, 60, 71, 8,195,224, + 7,205, 45, 9,195, 0, 6,230, 7, 71, 58, 0, 64, 15,207,213, + 197,120, 17, 64, 19,131, 95, 58, 0, 64, 15,207,205,251, 2, 58, + 0, 64, 15,207,120, 18,123,198, 8, 95,175, 18, 89,193, 75,209, + 58, 0, 64, 15,207,229,120, 38, 19,198,136,111,126,225,183,194, + 24, 4, 58, 0, 64, 15,207,120,229, 33, 64, 19,133,111, 70,225, + 8, 58, 0, 64, 15,207, 8,205, 62, 9,195, 24, 4,230, 7, 8, + 58, 0, 64, 15,207,205,251, 2, 58, 0, 64, 15,207, 8,245,230, + 4, 15,253,111, 58, 0, 64, 15,207,241,197,213,229, 38, 28,104, + 86, 36, 94, 36, 78,235,245, 58, 0, 64, 15,207, 6, 7, 17,177, + 19,120, 8,205,251, 2,235,112,235, 28,205,251, 2,235,112,235, + 28,205,251, 2,235,112,235, 28,205,251, 2,235,112,235, 28, 8, + 71, 16,222,205,251, 2,235,112,235, 58, 0, 64, 15,207,241, 71, + 205, 23, 12,120, 17, 96, 19,230, 7,131, 95,245,230, 3,198,176, + 33,177, 19, 8, 58, 0, 64, 15,207, 8,253,119, 0, 70, 44,253, + 112, 1, 8,120, 18,123,198, 8, 95, 58, 0, 64, 15,207, 8,214, + 128, 6, 28,253,119, 0, 78,253,113, 1,198, 4, 44, 16,244, 58, + 0, 64, 15,207,125,214, 24,111, 6, 4,126, 18,123,198, 8, 95, + 44, 16,247, 58, 0, 64, 15,207,241,225,209,193, 6, 0,195, 93, + 10,245, 58, 0, 64, 15,207,205,251, 2, 58, 0, 64, 15,207,241, + 205, 93, 10,195, 0, 6,230, 7, 71, 58, 0, 64, 15,207,213,197, + 120, 22, 19,198, 72, 95, 58, 0, 64, 15,207,205,251, 2, 58, 0, + 64, 15,207,235,112,235, 89,193, 75,209, 58, 0, 64, 15,207,229, + 120, 33,136, 19,133,111,126,225,183,194, 24, 4, 58, 0, 64, 15, + 207,120,229, 33, 72, 19,133,111, 70,225,245, 58, 0, 64, 15,207, + 241,205, 93, 10,195, 24, 4,197,213,229,195,106, 10,197,213,229, + 230, 7,245, 38, 19,198, 88,111,112,241,245, 38, 19,198, 96,111, + 8, 58, 0, 64, 15,207, 8,230, 7,246,224, 22, 31, 95, 8, 26, + 87, 58, 0, 64, 15,207, 8,230, 4, 15,253,111, 58, 0, 64, 15, + 207,241,230, 3,198, 64, 79,126,230, 7, 95, 58, 0, 64, 15,207, + 125,198, 8,111,123,254, 7, 56, 17,253,113, 0,126,130,250,181, + 10,128,242,183, 10, 62,127,253,119, 1,121,198, 4, 79, 58, 0, + 64, 15,207,125,198, 8,111,123,254, 5, 56, 17,253,113, 0,126, + 130,250,216, 10,128,242,218, 10, 62,127,253,119, 1,121,198, 4, + 79, 58, 0, 64, 15,207,125,198, 8,111,123,254, 4, 56, 17,253, + 113, 0,126,130,250,251, 10,128,242,253, 10, 62,127,253,119, 1, + 121,198, 4, 79, 58, 0, 64, 15,207,125,198, 8,111,253,113, 0, + 126,130,250, 25, 11,128,242, 27, 11, 62,127,253,119, 1, 58, 0, + 64, 15,207,225,209,193,201, 71, 58, 0, 64, 15,207,120,230, 4, + 15,253,111,120, 8, 58, 0, 64, 15,207,205,251, 2, 58, 0, 64, + 15,207, 58,170, 19,183, 40, 9,120,246,192, 71, 58, 0, 64, 15, + 207, 8,230, 3,198,180,253,119, 0,253,112, 1,195, 0, 6, 71, 58, 0, 64, 15,207,120,230, 4, 15,253,111,120, 8, 58, 0, 64, - 15,207,205,234, 2, 58, 0, 64, 15,207, 8,229,230, 7, 38, 18, - 198, 80,111,112, 8, 58, 0, 64, 15,207, 8,230, 7,198,136,111, - 8,126,183,225,194, 7, 4, 58, 0, 64, 15,207, 8,230, 3,198, - 180,253,119, 0,253,112, 1,195, 7, 4,205,134, 11,195,238, 5, - 205,134, 11,195, 7, 4,230, 1,135,253,111, 58, 0, 64, 15,207, - 205,234, 2,197, 58, 0, 64, 15,207,205,234, 2, 58, 0, 64, 15, - 207,120,193,253,112, 0,253,119, 1,201,230, 7, 71, 58, 0, 64, - 15,207,229, 38, 18,120,198,136,111, 54, 1,225, 58, 0, 64, 15, - 207,120,230, 4, 15,253,111,120,230, 3,135,135,198,180,253,119, - 0,253, 54, 1,192,195,238, 5,230, 7,245,213,229, 79,230, 4, - 15,253,111,121,230, 3,198, 64, 14, 6, 33,181, 17, 8, 58, 0, - 64, 15,207, 8, 94,253,119, 0,253,115, 1,198, 4, 8, 58, 0, - 64, 15,207, 8,253,119, 0,253,115, 1,198, 4, 8, 58, 0, 64, + 15,207,205,251, 2, 58, 0, 64, 15,207, 58,170, 19,183, 40, 9, + 120,246,192, 71, 58, 0, 64, 15,207, 8,229,230, 7, 38, 19,198, + 80,111,112, 8, 58, 0, 64, 15,207, 8,230, 7,198,136,111, 8, + 126,183,225,194, 24, 4, 58, 0, 64, 15,207, 8,230, 3,198,180, + 253,119, 0,253,112, 1,195, 24, 4,205,197, 11,195, 0, 6,205, + 197, 11,195, 24, 4,230, 1,135,253,111, 58, 0, 64, 15,207,205, + 251, 2,197, 58, 0, 64, 15,207,205,251, 2, 58, 0, 64, 15,207, + 120,193,253,112, 0,253,119, 1,201,230, 7, 71, 58, 0, 64, 15, + 207,229, 38, 19,120,198,136,111, 54, 1,225, 58, 0, 64, 15,207, + 120,230, 4, 15,253,111,120,230, 3,135,135,198,180,253,119, 0, + 253, 54, 1,192,195, 0, 6,230, 7,245,213,229, 79,230, 4, 15, + 253,111,121,230, 3,198, 64, 14, 6, 33,183, 18, 8, 58, 0, 64, + 15,207, 8, 94,253,119, 0,253,115, 1,198, 4, 8, 58, 0, 64, 15,207, 8,253,119, 0,253,115, 1,198, 4, 8, 58, 0, 64, 15, - 207, 8,253,119, 0,253,115, 1,198, 4, 44, 13,194,237, 11,225, - 209, 58, 0, 64, 15,207,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,207,201,120, 38, 18,198, 64,111,197,120, 70,205, 29, - 9,193, 58, 0, 64, 15,207,197,125,198, 8,111,120, 70,205, 60, - 10,193,125,198, 8,111,120,230, 3,198,180,253,119, 0,126,253, - 119, 1, 58, 0, 64, 15,207,201, 33, 48, 18, 6, 3,197,126,183, - 250,153, 12, 6, 15, 44,195,229, 12,230,127, 71, 44,126,128, 71, - 58, 0, 64, 15,207,197, 44, 78, 44, 94, 44, 86,235, 58, 0, 64, - 15,207,205,234, 2, 58, 0, 64, 15,207,120,254,254,202, 8, 13, - 254,255,202, 27, 13,253,104, 58, 0, 64, 15,207,235,114, 45,115, - 45,113, 45,193, 58, 0, 64, 15,207,253,125,230, 15,128, 71,254, - 16, 56, 2, 6, 15, 58, 0, 64, 15,207,120, 7, 7, 7,193,176, - 15, 15, 15,246,144, 50, 17,127,125,214, 17,111, 58, 0, 64, 15, - 207, 5,242,141, 12,195,186, 2, 58, 0, 64, 15,207, 28,235,113, - 44,115, 44,114,235, 29, 29, 29,195,173, 12, 58, 0, 64, 15,207, - 28,235, 78, 44, 94, 44, 86,235, 29, 29, 29,195,173, 12,205, 80, - 13,195,238, 5, 71, 58, 0, 64, 15,207,120,229,230, 3, 33,144, - 18,133,111,126,225,183,194,188, 4,120,205, 80, 13,195, 7, 4, - 230, 3, 71, 8, 58, 0, 64, 15,207,229, 38, 18,120, 15, 15, 15, - 15,111,126,246,128,119, 58, 0, 64, 15,207,213, 44, 44, 84,125, - 198, 6, 95, 58, 0, 64, 15,207, 26,119, 44, 28, 26,119, 44, 28, - 26,119,209,225, 58, 0, 64, 15,207,205,234, 2, 58, 0, 64, 15, - 207, 8,229,213, 38, 17,104, 17, 17,127, 15, 15, 15, 70,176, 18, - 44,126, 18,209,225,201,205,185, 13,195,238, 5, 58,147, 18,183, - 194,188, 4,205,185, 13,195, 7, 4, 58, 0, 64, 15,207,229, 33, - 48, 18,126,246,128,119, 58, 0, 64, 15,207,213, 44, 44, 84,125, - 198, 6, 95, 58, 0, 64, 15,207, 26,119, 44, 28, 26,119, 44, 28, - 26,119,209,225, 58, 0, 64, 15,207,205,234, 2, 58, 0, 64, 15, - 207, 62,224,176, 50, 17,127,201,205, 26, 14,195,238, 5, 71, 58, - 0, 64, 15,207,120,229,230, 3, 33,144, 18,133,111,126,225,183, - 194, 7, 4,120,205, 26, 14,195, 7, 4,230, 3, 71, 58, 0, 64, - 15,207,229, 38, 18,120, 15, 15, 15, 15,111,126,230,127,119,225, - 201,230, 3, 8, 58, 0, 64, 15,207,205,234, 2, 58, 0, 64, 15, - 207, 8,229, 38, 18, 15, 15, 15, 15,111,126,230,128,176,119,225, - 195,238, 5,230, 3, 8, 58, 0, 64, 15,207,205,234, 2, 58, 0, - 64, 15,207, 8,213,229,245, 17,144, 18,131, 95, 26, 95, 58, 0, - 64, 15,207,241, 38, 18, 15, 15, 15, 15,198, 15,111,112, 58, 0, - 64, 15,207,123,183, 32, 14,125,214, 15,111,126,230,128,176,119, - 58, 0, 64, 15,207,225,209,195, 7, 4,230, 3, 8, 58, 0, 64, - 15,207,205,234, 2, 58, 0, 64, 15,207, 8,213,229, 22, 28, 88, - 38, 18, 15, 15, 15, 15,198, 10,111, 58, 0, 64, 15,207, 26,119, - 20, 45, 26,119, 20, 45, 26,119, 58, 0, 64, 15,207,125,214, 8, - 111, 54, 0,225,209,195,238, 5,230, 3, 8, 58, 0, 64, 15,207, - 205,234, 2, 58, 0, 64, 15,207, 8,213,229, 22, 28, 88, 33,144, - 18,245,133,111,241, 70, 38, 18, 15, 15, 15, 15,198, 15,111, 58, - 0, 64, 15,207,119, 45, 26,119, 20, 45, 26,119, 20, 45, 26,119, - 58, 0, 64, 15,207,120,183,202, 31, 15,225,209,195, 7, 4, 58, - 0, 64, 15,207, 84,125,214, 4, 95,126, 18, 44, 28,126, 18, 44, - 28,126, 18, 58, 0, 64, 15,207,125,214, 8,111, 54, 0,225,209, - 195, 7, 4,205,101, 15,195,238, 5, 71, 58, 0, 64, 15,207,120, - 229,230, 15, 38, 18,198,136,111,126,225,183,194,172, 4,120,205, - 101, 15,195, 7, 4,230, 3, 8, 58, 0, 64, 15,207,205,234, 2, - 58, 0, 64, 15,207, 8,213, 17, 17,127, 15, 15, 15,176,246,128, - 18, 58, 0, 64, 15,207,205,234, 2, 58, 0, 64, 15,207,235,112, - 235,209,201,205,228, 13,195,238, 5, 58,147, 18,183,194,188, 4, - 205,228, 13,195, 7, 4,230, 3, 71, 58, 0, 64, 15,207,229, 38, - 18,120,198,144,111, 54, 1, 58, 0, 64, 15,207,120, 15, 15, 15, - 15,111, 38, 18, 54, 0,225,195,238, 5,205,234, 15,195,156, 2, - 205,234, 15,195,178, 2,230, 15, 60, 71,205,247, 15,195,156, 2, - 230, 15, 60, 71,205,247, 15,195,178, 2, 58, 0, 64, 15,207,205, - 234, 2, 58, 0, 64, 15,207,235,114, 45,115, 45,113, 58, 0, 64, - 15,207, 45,112,201,205, 17, 16,195,238, 5,205, 17, 16,195, 7, - 4, 58, 0, 64, 15,207,205,234, 2, 58, 0, 64, 15,207, 58,242, - 31,176, 50,242, 31,201,205, 50, 16,195,238, 5,205, 50, 16,195, - 7, 4, 58, 0, 64, 15,207,205,234, 2, 58, 0, 64, 15,207, 58, - 242, 31,160, 50,242, 31,201, 33,240, 31, 17, 88, 18, 14, 8, 26, - 70,128,242, 87, 16, 62,127, 71,125,205, 60, 10, 44, 28, 13, 58, - 0, 64, 15,207, 32,233, 33,232, 31, 17, 1, 18, 1, 16, 4,126, - 18, 44,123,129, 95, 58, 0, 64, 15,207, 16,243,175, 50,241, 31, - 201,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 207, 8,253,119, 0,253,115, 1,198, 4, 8, 58, 0, 64, 15,207, + 8,253,119, 0,253,115, 1,198, 4, 44, 13,194, 44, 12, 30, 0, + 198, 4,253,119, 0,253,115, 1,214, 4,253,119, 0,253,115, 1, + 225,209, 58, 0, 64, 15,207,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,207,201,120, 38, 19,198, 64,111,197,120, 70,205, + 62, 9,193, 58, 0, 64, 15,207,197,125,198, 8,111,120, 70,205, + 93, 10,193,125,198, 8,111,120,230, 3,198,180,253,119, 0,126, + 253,119, 1, 58, 0, 64, 15,207,201, 58,252, 31, 50,170, 19,195, + 98, 2, 33, 48, 19, 6, 3,197,175,253,111,126,183,250,246, 12, + 6, 15, 44,195, 66, 13,230,127, 71, 44,126,128, 71, 58, 0, 64, + 15,207,197, 44, 78, 44, 94, 44, 86,235, 58, 0, 64, 15,207,205, + 251, 2, 58, 0, 64, 15,207,120,254,254,202,176, 13,254,255,202, + 195, 13,253,104, 58, 0, 64, 15,207,235,114, 45,115, 45,113, 45, + 193, 58, 0, 64, 15,207,253,125,230, 15,128, 71,254, 16, 56, 2, + 6, 15, 58, 0, 64, 15,207,120, 7, 7, 7,193,176, 15, 15, 15, + 246,144, 50, 17,127, 58, 0, 64, 15,207,197,125,198, 10,111, 70, + 214, 10,111,120, 60, 40, 56, 58, 0, 64, 15,207,253,125,230,240, + 15, 15, 15, 15,235, 38, 18,198,168,111, 78,235, 58, 0, 64, 15, + 207,120,129,235, 38, 18,111, 78, 44, 70, 58, 0, 64, 15,207,123, + 230, 48,135,177, 33, 17,127,119,112,235, 58, 0, 64, 15,207,193, + 125,214, 17,111, 58, 0, 64, 15,207, 5,242,231, 12,195,203, 2, + 58, 0, 64, 15,207, 28,235,113, 44,115, 44,114,235, 29, 29, 29, + 195, 10, 13, 58, 0, 64, 15,207, 28,235, 78, 44, 94, 44, 86,235, + 29, 29, 29,195, 10, 13,205,248, 13,195, 0, 6, 71, 58, 0, 64, + 15,207,120,229,230, 3, 33,144, 19,133,111,126,225,183,194,205, + 4,120,205,248, 13,195, 24, 4,230, 3, 71, 8, 58, 0, 64, 15, + 207,229, 38, 19,120, 15, 15, 15, 15,111,126,246,128,119, 58, 0, + 64, 15,207,213, 44, 44, 84,125,198, 6, 95, 58, 0, 64, 15,207, + 26,119, 44, 28, 26,119, 44, 28, 26,119,123,209,225, 8, 58, 0, + 64, 15,207,205,251, 2, 58, 0, 64, 15,207, 8,229, 60, 38, 19, + 111,112,225,201,205, 87, 14,195, 0, 6, 58,147, 19,183,194,205, + 4,205, 87, 14,195, 24, 4, 58, 0, 64, 15,207,229, 33, 48, 19, + 126,246,128,119, 58, 0, 64, 15,207,213, 44, 44, 84,125,198, 6, + 95, 58, 0, 64, 15,207, 26,119, 44, 28, 26,119, 44, 28, 26,119, + 209,225, 58, 0, 64, 15,207,205,251, 2, 58, 0, 64, 15,207, 62, + 224,176, 50, 17,127,201,205,184, 14,195, 0, 6, 71, 58, 0, 64, + 15,207,120,229,230, 3, 33,144, 19,133,111,126,225,183,194, 24, + 4,120,205,184, 14,195, 24, 4,230, 3, 71, 58, 0, 64, 15,207, + 229, 38, 19,120, 15, 15, 15, 15,111,126,230,127,119, 58, 0, 64, + 15,207,125,198, 11,111, 62,255,119,225,201,230, 3, 8, 58, 0, + 64, 15,207,205,251, 2, 58, 0, 64, 15,207, 8,229, 38, 19, 15, + 15, 15, 15,111,126,230,128,176,119,225,195, 0, 6,230, 3, 8, + 58, 0, 64, 15,207,205,251, 2, 58, 0, 64, 15,207, 8,213,229, + 245, 17,144, 19,131, 95, 26, 95, 58, 0, 64, 15,207,241, 38, 19, + 15, 15, 15, 15,198, 15,111,112, 58, 0, 64, 15,207,123,183, 32, + 14,125,214, 15,111,126,230,128,176,119, 58, 0, 64, 15,207,225, + 209,195, 24, 4,230, 3, 8, 58, 0, 64, 15,207,205,251, 2, 58, + 0, 64, 15,207, 8,213,229, 22, 28, 88, 38, 19, 15, 15, 15, 15, + 198, 10,111, 58, 0, 64, 15,207, 26,119, 20, 45, 26,119, 20, 45, + 26,119, 58, 0, 64, 15,207,125,214, 8,111, 54, 0,225,209,195, + 0, 6,230, 3, 8, 58, 0, 64, 15,207,205,251, 2, 58, 0, 64, + 15,207, 8,213,229, 22, 28, 88, 33,144, 19,245,133,111,241, 70, + 38, 19, 15, 15, 15, 15,198, 15,111, 58, 0, 64, 15,207,119, 45, + 26,119, 20, 45, 26,119, 20, 45, 26,119, 58, 0, 64, 15,207,120, + 183,202,201, 15,225,209,195, 24, 4, 58, 0, 64, 15,207, 84,125, + 214, 4, 95,126, 18, 44, 28,126, 18, 44, 28,126, 18, 58, 0, 64, + 15,207,125,214, 8,111, 54, 0,225,209,195, 24, 4,205, 15, 16, + 195, 0, 6, 71, 58, 0, 64, 15,207,120,229,230, 15, 38, 19,198, + 136,111,126,225,183,194,189, 4,120,205, 15, 16,195, 24, 4,230, + 3, 8, 58, 0, 64, 15,207,205,251, 2, 58, 0, 64, 15,207,120, + 135,218, 93, 16, 8,229,111, 8, 58, 0, 64, 15,207,125, 15, 15, + 15, 15,198, 11,111, 38, 19, 54,255,225, 58, 0, 64, 15,207, 8, + 213, 17, 17,127, 15, 15, 15,176,246,128, 18, 58, 0, 64, 15,207, + 205,251, 2, 58, 0, 64, 15,207,235,112,235,209,201, 71, 58, 0, + 64, 15,207, 8, 15, 15, 15, 15,198, 10,195, 60, 14,205,130, 14, + 195, 0, 6, 58,147, 19,183,194,205, 4,205,130, 14,195, 24, 4, + 230, 3, 71, 58, 0, 64, 15,207,229, 38, 19,120,198,144,111, 54, + 1, 58, 0, 64, 15,207,120, 15, 15, 15, 15,111, 38, 19, 54, 0, + 225,195, 0, 6,205,196, 16,195,173, 2,205,196, 16,195,195, 2, + 230, 15, 60, 71,205,209, 16,195,173, 2,230, 15, 60, 71,205,209, + 16,195,195, 2, 58, 0, 64, 15,207,205,251, 2, 58, 0, 64, 15, + 207,235,114, 45,115, 45,113, 58, 0, 64, 15,207, 45,112,201,205, + 235, 16,195, 0, 6,205,235, 16,195, 24, 4, 58, 0, 64, 15,207, + 205,251, 2, 58, 0, 64, 15,207, 58,242, 31,176, 50,242, 31,201, + 205, 12, 17,195, 0, 6,205, 12, 17,195, 24, 4, 58, 0, 64, 15, + 207,205,251, 2, 58, 0, 64, 15,207, 58,242, 31,160, 50,242, 31, + 201, 33,240, 31, 17, 88, 19, 14, 8, 26, 70,128,242, 49, 17, 62, + 127, 71,125,205, 93, 10, 44, 28, 13, 58, 0, 64, 15,207, 32,233, + 33,232, 31, 17, 1, 19, 1, 16, 4,126, 18, 44,123,129, 95, 58, + 0, 64, 15,207, 16,243,175, 50,241, 31,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, @@ -281,8 +297,8 @@ static uint8_t echo_blob[] = { 129, 2,143, 1,141, 1,140, 1,138, 1,137, 1,135, 1,134, 1, 133, 1,131, 1,130, 1,129, 1,128, 1,143, 0,142, 0,142, 0, 132, 2,169, 2,210, 2,253, 2, 42, 3, 90, 3,142, 3,196, 3, - 253, 3, 57, 4,122, 4,190, 4, 0, 2, 4, 6, 8, 10, 12,254, - 252,250,248,246,244,127, 0, 31, 31,255, 0,255,255,255,255,255, + 253, 3, 57, 4,122, 4,190, 4, 0, 2, 4, 6, 8, 12, 16, 24, + 254,252,250,248,244,240,232,127, 0, 31, 31,255, 0,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, @@ -297,10 +313,10 @@ static uint8_t echo_blob[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 0,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/doc/api-asm.68k b/doc/api-asm.68k index 3293b9e..8cbbdba 100644 --- a/doc/api-asm.68k +++ b/doc/api-asm.68k @@ -132,7 +132,9 @@ Echo_SetVolumeEx Sets the global volume for each channel separately. Register a0 points to a list of 16 bytes (one for each Echo channel). Values for FM and PSG channels are given in the same way as in events, that is: logarithmic - scale, 0..127 for FM, 0..15 for PSG, lower = louder. + scale, 0..127 for FM, 0..15 for PSG, lower = louder. You can use the + look-up tables described below (Echo_FMVolTable and Echo_PSGVolTable) to + convert from linear to . The last byte (the one belonging to the PCM channel) is used to toggle whether PCM plays, either 0 (disabled) or 1 (enabled). @@ -141,6 +143,17 @@ Echo_SetVolumeEx been changed for the sake of expansion. Currently the extra bytes are ignored, but consider adapting your code (just set them to zero). +Echo_FMVolTable +Echo_PSGVolTable + These two are not subroutines but rather look-up tables. They have 64 + byte-sized entries and they're used to convert a linear volume value into + a hardware volume value (e.g. for Echo_SetVolumeEx). + + To give an idea of how to use these: take what you'd pass in d0 to + Echo_SetVolume divided by 4 (shift right by 2), then use it as an offset + to these tables. The byte will be the volume as the hardware (or + Echo_SetVolumeEx) wants it. + ============================================================================= *** Settings *** @@ -167,6 +180,15 @@ Echo_SetPCMRate (which can hamper Echo's ability to process complex streams). Be careful if you increase the sample rate. +Echo_SetStereo + in d0 = $00 to use mono, otherwise to use stereo + + Toggles whether sound is forced to mono (d0 == $00) or if stereo panning + works (d0 != $00). Will take effect for all following panning events. Can + be used to implement a mono/stereo toggle in games. + + By default Echo is in stereo mode. + ============================================================================= *** Raw access *** diff --git a/doc/api-c.txt b/doc/api-c.txt index 8e5c61c..2c879ef 100644 --- a/doc/api-c.txt +++ b/doc/api-c.txt @@ -138,6 +138,17 @@ void echo_set_volume_ex(const uint8_t *ptr) been changed for the sake of expansion. Currently the extra bytes are ignored, but consider adapting your code (just set them to zero). +const uint8_t echo_fm_vol_table[] +const uint8_t echo_psg_vol_table[] + These two are not subroutines but rather look-up tables. They have 64 + byte-sized entries and they're used to convert a linear volume value into + a hardware volume value (e.g. for echo_set_volume_ex). + + To give an idea of how to use these: take what you'd pass as argument to + echo_set_volume divided by 4 (shift right by 2), then use it as an index + to these arrays. The byte will be the volume as the hardware (or + echo_set_volume_ex) wants it. + ============================================================================= *** Settings *** @@ -163,6 +174,14 @@ void echo_set_pcm_rate(uint8_t rate) (which can hamper Echo's ability to process complex streams). Be careful if you increase the sample rate. +void echo_set_stereo(int enable) + + Toggles whether sound is forced to mono (enable == 0) or if stereo panning + works (enable != 0). Will take effect for all following panning events. + Can be used to implement a mono/stereo toggle in games. + + By default Echo is in stereo mode. + ============================================================================= *** Raw access *** diff --git a/doc/eef.txt b/doc/eef.txt index c3ab92e..57eeb1d 100644 --- a/doc/eef.txt +++ b/doc/eef.txt @@ -7,13 +7,25 @@ OVERVIEW 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). + EEF instruments consist of a byte per tick (1/60th of a second). The + bottom nibble is the volume level (relative to the note's volume), + ranging from $x0 (loudest) to $xF (quietest). + + The upper nibble is a "semitone shift", which is added to the current + note's semitone. These can be useful for things like vibrato (e.g. for + whistles) and such. The amount the semitone is shifted is as follows: + + $0x ... 0 | $1x ... +1 | $8x ... -1 + | $2x ... +2 | $9x ... -2 + | $3x ... +3 | $Ax ... -3 + | $4x ... +4 | $Bx ... -4 + | $5x ... +6 | $Cx ... -6 + | $6x ... +8 | $Dx ... -8 + | $7x ... +12 | $Ex ... -12 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. + must be at least one tick byte between them or Echo will hang. To make a non-looping PSG instrument, just put the last volume value inside the loop. @@ -22,14 +34,14 @@ FORMAT 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): + 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 + + There's a flavor of the Set Frequency event that doesn't play nice with + semitone shifting (in which case it'll just act as if it was always $0x). + It will work again once a new note starts or the other flavor is used. ============================================================================= diff --git a/doc/esf.txt b/doc/esf.txt index 7fbe73e..ab74399 100644 --- a/doc/esf.txt +++ b/doc/esf.txt @@ -217,34 +217,56 @@ $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 +$30nn/$30nnnn: Set frequency FM channel #1 +$31nn/$31nnnn: Set frequency FM channel #2 +$32nn/$32nnnn: Set frequency FM channel #3 +$34nn/$34nnnn: Set frequency FM channel #4 +$35nn/$35nnnn: Set frequency FM channel #5 +$36nn/$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. - + triggering a new note. Meant for note slides. The format of this event + depends on whether the second byte has its MSB set or not. + + If the 2nd byte's MSB is set, the event is two bytes long. The 2nd byte + is the semitone in this format (where "octave" is from 0 to 7 and + "semitone" is from 0 to 11): + + octave * 16 + semitone + 128 + + If the 2nd byte's MSB is clear, the event is three bytes long. The 2nd + and 3rd bytes specify the new frequency in the same format as the YM2612 + expects. The 2nd byte is register $A4+, the 3rd 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 +$38nn/$38nnnn: Set frequency PSG channel #1 +$39nn/$39nnnn: Set frequency PSG channel #2 +$3Ann/$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). + without triggering a new note. Meant for note slides. The format of this + event depends on whether the second byte has its MSB set or not. + + If the 2nd byte's MSB is set, the event is two bytes long. The 2nd byte + is the semitone in this format (where "octave" is from 0 to 5 and + "semitone" is from 0 to 11): + + octave * 12 + semitone + 128 + + If the 2nd byte's MSB is clear, the event is three bytes long. The 2nd + and 3rd bytes specify the new frequency, the 2nd byte containing the + four least significant bits (LSB aligned), and the 3rd byte containing + the six most significant bits (LSB aligned too). + + IMPORTANT: using the 3-byte event prevents semitone shifting in PSG + instruments from working. It will start working again whenever a new note + or the 2-byte version of this event is used. Echo uses the following frequency values for each semitone: diff --git a/src-68k/echo.68k b/src-68k/echo.68k index 7abdbf8..e755d19 100644 --- a/src-68k/echo.68k +++ b/src-68k/echo.68k @@ -273,6 +273,22 @@ Echo_SetPCMRate: rts ; End of subroutine ;**************************************************************************** +; Echo_SetStereo +; Sets whether stereo is enabled or not +; +; input d0.b ... 0 to disable, otherwise to enable +;**************************************************************************** + +Echo_SetStereo: + movem.l d0-d1, -(sp) ; Save registers + tst.b d0 ; Check what we want to do + seq.b d1 ; Put parameter in place + move.b #$09, d0 ; Command $09 = set stereo + bsr Echo_SendCommandByte ; Send command to Echo + movem.l (sp)+, d0-d1 ; Restore registers + rts ; End of subroutine + +;**************************************************************************** ; Echo_SetVolume ; Changes the global volume for every channel. ; @@ -283,7 +299,7 @@ Echo_SetVolume: Echo_Z80Request ; We need the Z80 bus movem.l d0-d1/a0-a1, -(sp) ; Save registers - lea @FMTable(pc), a0 ; Determine FM volume + lea Echo_FMVolTable(pc), a0 ; Determine FM volume moveq #0, d1 move.b d0, d1 lsr.b #2, d1 @@ -299,7 +315,7 @@ Echo_SetVolume: move.b d1, (a1)+ ; FM channel 6 move.b d1, (a1)+ ; FM channel 7 - lea @PSGTable(pc), a0 ; Determine PSG volume + lea Echo_PSGVolTable(pc),a0 ; Determine PSG volume moveq #0, d1 move.b d0, d1 lsr.b #2, d1 @@ -324,13 +340,13 @@ Echo_SetVolume: ;---------------------------------------------------------------------------- -@FMTable: +Echo_FMVolTable: dc.b $7F,$7B,$77,$73,$70,$6C,$68,$65,$61,$5E,$5A,$57,$54,$50,$4D,$4A dc.b $47,$44,$41,$3F,$3C,$39,$36,$34,$31,$2F,$2D,$2A,$28,$26,$24,$22 dc.b $20,$1E,$1C,$1A,$18,$16,$15,$13,$12,$10,$0F,$0D,$0C,$0B,$0A,$09 dc.b $08,$07,$06,$05,$04,$04,$03,$02,$02,$01,$01,$01,$00,$00,$00,$00 -@PSGTable: +Echo_PSGVolTable: dc.b $0F,$0F,$0E,$0E,$0D,$0D,$0C,$0C,$0B,$0B,$0B,$0A,$0A,$0A,$09,$09 dc.b $08,$08,$08,$07,$07,$07,$06,$06,$06,$06,$05,$05,$05,$04,$04,$04 dc.b $04,$03,$03,$03,$03,$03,$02,$02,$02,$02,$02,$02,$01,$01,$01,$01 diff --git a/src-68k/esf.68k b/src-68k/esf.68k index fc8dacc..7f5aae5 100644 --- a/src-68k/esf.68k +++ b/src-68k/esf.68k @@ -220,12 +220,19 @@ ESF_SetFMReg macro ESF_Delay macro if (\1)>0 - if (\1)<=$10 - dc.b $D0-1+(\1) - else - dc.b $FE - dc.b (\1)&$FF - endc + if (\1)>=$100 + rept (\1)/$100 + dc.b $FE, $00 + endr + endc + if (\1)%$100 + if ((\1)%$100)<=$10 + dc.b $D0-1+((\1)%$100) + else + dc.b $FE + dc.b (\1)%$100 + endc + endc endc endm diff --git a/src-z80/core/bgm.z80 b/src-z80/core/bgm.z80 index b48d87a..c043616 100644 --- a/src-z80/core/bgm.z80 +++ b/src-z80/core/bgm.z80 @@ -376,10 +376,11 @@ ClearBGM: ld a, b ; Reset panning and $04 + rrca ld iyl, a ld a, b and $03 - add $B4 + add a, $B4 ld (iy+0), a ld (iy+1), $C0 diff --git a/src-z80/core/main.z80 b/src-z80/core/main.z80 index 387b879..1de8930 100644 --- a/src-z80/core/main.z80 +++ b/src-z80/core/main.z80 @@ -20,6 +20,11 @@ EntryPoint: ld (RAM_PSGData+16), a ld (RAM_PSGData+32), a ld (RAM_PSGData+48), a + dec a + ld (RAM_PSGData+11), a + ld (RAM_PSGData+11+16), a + ld (RAM_PSGData+11+32), a + ld (RAM_PSGData+11+48), a ld hl, $6000 ; Set default bank ld (hl), l @@ -114,6 +119,8 @@ RunCommand: jp z, SetPCMRate dec a ; Command $08: pause BGM jp z, PauseBGM + dec a ; Command $09: set stereo + jp z, SetStereo PollPCM @@ -207,17 +214,11 @@ DoTick_PSGSkip: ;**************************************************************************** ; LoadList [command $01] ; Loads the pointer list +;---------------------------------------------------------------------------- +; notes: doesn't return ;**************************************************************************** LoadList: -; ld hl, RAM_ComBank ; Get command parameters -; ld c, (hl) -; inc l -; ld e, (hl) -; inc l -; ld d, (hl) -; ex de, hl - ld hl, (RAM_ComAddr) ; Get command parameters ld a, (RAM_ComBank) ld c, a diff --git a/src-z80/core/sfx.z80 b/src-z80/core/sfx.z80 index 8c5e7dd..2430b74 100644 --- a/src-z80/core/sfx.z80 +++ b/src-z80/core/sfx.z80 @@ -281,6 +281,8 @@ ClearSFX: PollPCM dec b ; Restore FM channel + ld a, b + call KillFM call RestoreFM inc b diff --git a/src-z80/core/vars.z80 b/src-z80/core/vars.z80 index 79e4a1d..321d552 100644 --- a/src-z80/core/vars.z80 +++ b/src-z80/core/vars.z80 @@ -9,7 +9,7 @@ RAM_PSGData: ds 4*16 ; PSG envelope data ; ds 3 ... Current address ; ds 3 ... Looping address ; ds 3 ... Start address - ; ds 1 ... Padding + ; ds 1 ... Semitone ($FF if void) ; ds 3 ... BGM instrument address ; ds 1 ... BGM channel volume @@ -45,6 +45,7 @@ RAM_SFXAddress: ds 2 ; Current SFX address RAM_SFXLoopPoint: ds 3 ; SFX loop point RAM_Paused: ds 1 ; Set if BGM stream is paused +RAM_Mono: ds 1 ; Set if panning is disabled RAM_PCMBank1: db 1 ; (not implemented yet) RAM_PCMAddr1: dw 1 ; (not implemented yet) diff --git a/src-z80/player/fm.z80 b/src-z80/player/fm.z80 index d5d49ba..8afd0e7 100644 --- a/src-z80/player/fm.z80 +++ b/src-z80/player/fm.z80 @@ -49,8 +49,9 @@ NoteOnFM: PollPCM call GetParam ; Get note PollPCM - ex af, af' + +SetFMSemitone: push de push hl @@ -175,8 +176,8 @@ SetNoteFMBGM: jp ProcessBGMRun ; End of subroutine SetNoteFM: - push af ld b, a + ex af, af' PollPCM ld a, b ; Determine which port to write @@ -188,7 +189,11 @@ SetNoteFM: call GetParam ; Get high byte PollPCM - pop af + ld a, b ; Is it a semitone? + add a, a + jp c, .freqtone + + ex af, af' push de and $07 @@ -217,6 +222,14 @@ SetNoteFM: pop de ret ; End of subroutine +;---------------------------------------------------------------------------- + +.freqtone: + inc a + ld b, a + ex af, af' + jp SetFMSemitone + ;**************************************************************************** ; LoadFM* [events $40~$47] ; Loads a FM instrument @@ -678,6 +691,16 @@ SetFMParamSFX: PollPCM call GetParam ; Get parameters PollPCM + + ld a, (RAM_Mono) ; Is stereo disabled? (always turn on both + or a ; speakers in that case) + jr z, .sfxpanok + ld a, b + or $C0 + ld b, a + PollPCM +.sfxpanok: + ex af, af' and $03 ; Get channel ID @@ -701,6 +724,16 @@ SetFMParamBGM: PollPCM call GetParam ; Get parameters PollPCM + + ld a, (RAM_Mono) ; Is stereo disabled? (always turn on both + or a ; speakers in that case) + jr z, .bgmpanok + ld a, b + or $C0 + ld b, a + PollPCM +.bgmpanok: + ex af, af' push hl @@ -880,6 +913,14 @@ KillFM: dec c jp nz, .loaddummy + ld e, 0 ; Make the pitch so low it's unherable + add 4 ; because the above is STILL not enough + ld (iy+0), a ; sometimes. If you ever notice a very low + ld (iy+1), e ; pitch waveform... this is why + sub 4 + ld (iy+0), a + ld (iy+1), e + pop hl pop de PollPCM @@ -941,3 +982,16 @@ RestoreFM: PollPCM ret ; End of subroutine + +;**************************************************************************** +; SetStereo [command $09] +; Toggles whether stereo is enabled or not. +;---------------------------------------------------------------------------- +; notes: doesn't return +;**************************************************************************** + +SetStereo: + ld a, (RAM_ComBank) ; Just copy the argument as-is + ld (RAM_Mono), a + + jp EndOfCommand ; End of subroutine diff --git a/src-z80/player/freq.z80 b/src-z80/player/freq.z80 index 7f963e5..6aae77b 100644 --- a/src-z80/player/freq.z80 +++ b/src-z80/player/freq.z80 @@ -94,9 +94,9 @@ FMFreqTable: ;**************************************************************************** PSGShiftTable: - db 0 - db 2, 4, 6, 8, 10, 12 - db -2, -4, -6, -8, -10, -12 + db 0*2 ; $0x + db 1*2, 2*2, 3*2, 4*2, 6*2, 8*2, 12*2 ; $1x..$7x + db -1*2, -2*2, -3*2, -4*2, -6*2, -8*2, -12*2 ; $8x..$Ex ;**************************************************************************** ; DummyFMInstr diff --git a/src-z80/player/pcm (copia).z80 b/src-z80/player/pcm (copia).z80 new file mode 100644 index 0000000..ae7b34a --- /dev/null +++ b/src-z80/player/pcm (copia).z80 @@ -0,0 +1,236 @@ +;**************************************************************************** +; UpdatePCM +; Updates PCM output upon a timer event +;**************************************************************************** + +UpdatePCM: + ret ; $C9 = RET = no PCM playback + ; $D0 = RET NC = PCM playback + + exx ; Switch to PCM registers + +.doagain: + ld (ix+0), $27 ; Acknowledge timer + ld (ix+1), $1F + + ld a, (hl) ; Fetch next sample + inc a ; Check if it's the end of the waveform + jr z, .stop + ld (ix+0), $2A ; Nope, send sample to YM2612 + ld (ix+1), a + + inc l ; Update buffer position + jr z, .reload ; Need to buffer more? + +.nopcm: + exx ; Switch to normal registers + ret ; End of subroutine + +.stop: + ld a, $C9 ; Stop playback + ld (UpdatePCM), a + ld (ix+0), $2A ; Turn off DAC + ld (ix+1), $80 + ld (ix+0), $2B + ld (ix+1), $00 + exx ; Switch to normal registers + ret ; End of subroutine + +.reload: + ld a, (RAM_LastBank) ; Bank switch if needed + cp c + jp z, .noswitchu + ld a, c + ld (RAM_LastBank), a + ld hl, $6000 + BankSwitch +.noswitchu: + + ld hl, RAM_PCMBuffer ; Load samples into the buffer + ld a, c + ex de, hl + + ldi + ldi + ldi + ldi + + ldi + ldi + ldi + ldi + + ldi + ldi + ldi + ldi + + ldi + ldi + ldi + ldi + + ex de, hl + ld c, a + + ld a, e + or a + jp nz, .nobankchg ; Update high bytes of address if needed + inc d + jp nz, .nobankchg + ld d, $80 + inc c +.nobankchg: + + ld l, RAM_PCMBuffer&$FF ; Go back to the beginning of the buffer + jp .doagain ; We took so long we should play the next + ; sample already ._.' + +;**************************************************************************** +; PlayPCM* [event $0C] +; Plays a PCM sample +;---------------------------------------------------------------------------- +; input c .... current bank +; input hl ... current address +;---------------------------------------------------------------------------- +; breaks: af, b +;**************************************************************************** + +PlayPCMSFX: + call PlayPCM ; We're just a wrapper + jp ProcessSFXRun ; End of subroutine + +PlayPCMBGM: + PollPCM + + ld a, (RAM_Locked+6) ; Check if channel is free + or a + jp nz, ProcessBGMSkip1 ; Don't play sample if locked + + call PlayPCM ; We're just a wrapper + jp ProcessBGMRun ; End of subroutine + +PlayPCM: + ld a, (RAM_GlobalVol+$0C) ; Are we allowed to play PCM? + or a + ret z + + call GetParam ; Get sample ID + + ld a, b + exx ; We'll modify PCM data now + + ld h, RAM_PointerList>>8 ; Get offset in pointer list + ld l, a + + ld d, (hl) ; Get PCM address + inc h + ld e, (hl) + inc h + ld c, (hl) + + ld hl, $6000 ; Initial bank switch + ld a, c + ld (RAM_LastBank), a + BankSwitch + + ld h, RAM_PCMBuffer>>8 ; Set buffer where the sample starts + ld a, e + or $F0 + ld l, a + + ld b, l +.load1st: ; Copy initial samples into the buffer + ld a, (de) + ld (hl), a + inc e + inc l + jp nz, .load1st + ld l, b + + ld a, e ; Check if the sample should skip ahead + or a ; already + jp nz, .noskip1st + inc d + jp nz, .noskip1st + ld d, $80 + inc c +.noskip1st: + + exx ; Back to standard registers + ld a, $D0 ; Enable PCM playback + ld (UpdatePCM), a + + ld (ix+0), $2B ; Turn on DAC + ld (ix+1), $80 + ld (ix+0), $2A + ld (ix+1), $80 + + ret ; End of subroutine + +;**************************************************************************** +; StopPCM* +; Stops a PCM sample +;**************************************************************************** + +StopPCMSFX: + call StopPCM ; We're just a wrapper + jp ProcessSFXRun ; End of subroutine + +StopPCMBGM: + PollPCM + + ld a, (RAM_Locked+6) ; Check if channel is free + or a + jp nz, ProcessBGMRun ; Don't stop sample if locked + + call StopPCM ; We're just a wrapper + jp ProcessBGMRun ; End of subroutine + +StopPCM: + ld a, $C9 ; Stop PCM playback + ld (UpdatePCM), a + + ld (ix+0), $2B ; Disable DAC + ld (ix+1), $00 + + ret ; End of subroutine + +;**************************************************************************** +; LockChannelPCM [event $EC] +; Locks the PCM channel +;**************************************************************************** + +LockChannelPCM: + ld a, $01 ; Lock PCM channel + ld (RAM_Locked+6), a + + call StopPCM ; Stop PCM playback + jp ProcessSFXRun ; End of subroutine + +;**************************************************************************** +; SetPCMRate [command $07] +; Changes the sample rate of PCM +;**************************************************************************** + +SetPCMRate: + ld a, (RAM_ComBank) ; Get new rate + cpl + ld b, a + + xor a ; Parsed command already + ld (RAM_Command), a + + ld a, b ; Set high bits of timer + ld (ix+0), $24 + rrca + rrca + or $C0 + ld (ix+1), a + + ld a, b ; Set low bits of timer + ld (ix+0), $25 + and $03 + ld (ix+1), a + + jp IdleLoop ; End of subroutine diff --git a/src-z80/player/psg.z80 b/src-z80/player/psg.z80 index 6ddaae7..892931a 100644 --- a/src-z80/player/psg.z80 +++ b/src-z80/player/psg.z80 @@ -8,10 +8,10 @@ UpdatePSG: ld b, 3 ; Go through all channels .loop: push bc + xor a + ld iyl, a ld a, (hl) ; Get channel volume -; bit 7, a -; jr nz, .noskip or a jp m, .noskip ld b, $0F @@ -74,7 +74,7 @@ UpdatePSG: .skip: PollPCM - + ld a, b ; Set PSG channel volume rlca rlca @@ -86,6 +86,63 @@ UpdatePSG: rrca or $90 ld ($7F11), a + + PollPCM + push bc + + ld a, l ; Get current semitone + add 11-1 + ld l, a + ld b, (hl) + sub 11-1 + ld l, a + + ld a, b ; Oh, don't tocuh it? + inc a + jr z, .notone + + PollPCM + + db $FD,$7D ; ld a, iyl ; Get semitone shift + and $F0 + rrca + rrca + rrca + rrca + ex de, hl + ld h, PSGShiftTable>>8 + add PSGShiftTable&$FF + ld l, a + ld c, (hl) + ex de, hl + + PollPCM + + ld a, b ; Compute resulting semitone + add c + + ex de, hl ; Get corresponding frequency + ld h, PSGFreqTable>>8 + ld l, a + ld c, (hl) + inc l + ld b, (hl) + + PollPCM + + ld a, e ; Get PSG channel + and $30 + add a + or c + + ld hl, $7F11 ; Set new frequency + ld (hl), a + ld (hl), b + ex de, hl + + PollPCM +.notone: + pop bc ld a, l ; Go for next channel sub 16+1 @@ -200,31 +257,22 @@ NoteOnPSG: ld a, (de) ld (hl), a + ld a, e pop de pop hl + ex af, af' PollPCM call GetParam ; Get note PollPCM - - ;pop af ex af, af' - push hl - push de - ld h, PSGFreqTable>>8 ; Get address of frequency data - ld l, b - ld de, $7F11 - rrca ; Set new frequency - rrca - rrca - ld b, (hl) - or b - ld (de), a - inc l - ld a, (hl) - ld (de), a - pop de +SetSemitonePSG: + push hl ; Store new semitone + inc a + ld h, RAM_PSGData>>8 + ld l, a + ld (hl), b pop hl ret ; End of subroutine @@ -336,6 +384,14 @@ NoteOffPSG: ld a, (hl) and $7F ld (hl), a + + PollPCM + + ld a, l ; Don't waste time with semitone shifting + add 11 + ld l, a + ld a, $FF + ld (hl), a pop hl ret ; End of subroutine @@ -595,6 +651,27 @@ SetNotePSG: PollPCM call GetParam ; Get first byte PollPCM + + ld a, b ; Select by semitone? + add a, a + jp c, .freqtone + ex af, af' + + push hl ; Mark semitone as not valid + ld l, a + ex af, af' + PollPCM + ld a, l + rrca + rrca + rrca + rrca + add a, 11 + ld l, a + ld h, RAM_PSGData>>8 + ld (hl), $FF + pop hl + PollPCM ex af, af' push de ; PSG port address @@ -618,6 +695,19 @@ SetNotePSG: ret ; End of subroutine +;---------------------------------------------------------------------------- + +.freqtone: + ld b, a + PollPCM + ex af, af' + rrca + rrca + rrca + rrca + add 10 + jp SetSemitonePSG + ;**************************************************************************** ; SetNoteNoise* ; Sets the note of the noise PSG channel without "note on" |
