aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsik2017-07-23 03:20:35 -0300
committersik2017-07-23 03:20:35 -0300
commit3aacf3d2cedfdeca49ceb57533389870bfc688a9 (patch)
treea46d166fa9270700e8e159ca9ae455ac24472771
parenta679ba38190bfed6ae150a12e819ad7527c495d1 (diff)
Now with pausing and other niceties
-rw-r--r--README16
-rw-r--r--built/old-builds/prog-z80-1.4.binbin0 -> 5120 bytes
-rw-r--r--built/prog-z80.binbin5120 -> 4864 bytes
-rw-r--r--c/echo.c117
-rw-r--r--c/echo.h27
-rw-r--r--c/echoblob.h548
-rw-r--r--doc/api-asm.68k30
-rw-r--r--doc/api-c.txt18
-rw-r--r--doc/esf.txt21
-rw-r--r--src-68k/echo.68k165
-rw-r--r--src-z80/build.z808
-rw-r--r--src-z80/core/bgm.z80185
-rw-r--r--src-z80/core/macro.z8041
-rw-r--r--src-z80/core/main.z80113
-rw-r--r--src-z80/core/sfx.z8048
-rw-r--r--src-z80/core/vars.z8018
-rw-r--r--src-z80/player/fm.z8030
-rw-r--r--src-z80/player/misc.z8055
-rw-r--r--src-z80/player/pcm (copia).z80236
-rw-r--r--src-z80/player/pcm.z80197
-rw-r--r--src-z80/player/psg.z806
21 files changed, 1264 insertions, 615 deletions
diff --git a/README b/README
index e1b42b4..6f036e2 100644
--- a/README
+++ b/README
@@ -7,12 +7,18 @@
| | |_ |_ ___ | | | | | | | |
| |_______ |_ |___| _| | | | | |_ |_____| _|
|___________| |________| |___| |___| |_________|
- ___ ___ _ _ ___ __ ___ ___ ___ _ ___ ___ _ _ _
- | _| | | | | \ | _| | _| | | _| | | | | |
- | |_| | | | | | | | | | |_| | | |_| | | | |_ _ _ ___ ___ | | | | |
+ ___ ___ _ _ ___ __ ___ ___ ___ _ ___ ___ _ ___
+ | _| | | | | \ | _| | _| | | _| | | | _|
+ | |_| | | | | | | | | | |_| | | |_| | | | |_ _ _ ___ ___ | | | |_
|_ | | | | | | | | | | _| | | | | | | | _| | | | __| _ \ | | |_ |
- _| | | | | | | | | | | |_| | | | | | | | |_ | | | __| /_ | |_ | |
- |___|___|___|_|_|__/ |___|_|_|___|_|_|_|___| \_/|___|_|_\_| |_|_| |_|
+ _| | | | | | | | | | | |_| | | | | | | | |_ | | | __| /_ | |_ _| |
+ |___|___|___|_|_|__/ |___|_|_|___|_|_|_|___| \_/|___|_|_\_| |_|_|___|
+
+=============================================================================
+
+WARNING: if you used Echo_SetVolumeEx in Echo 1.4, beware that the ABI
+changed to require 16 bytes instead of 13. Currently the extra bytes are
+ignored, but consider adapting your code (just set them to zeroes).
=============================================================================
diff --git a/built/old-builds/prog-z80-1.4.bin b/built/old-builds/prog-z80-1.4.bin
new file mode 100644
index 0000000..bbb92e2
--- /dev/null
+++ b/built/old-builds/prog-z80-1.4.bin
Binary files differ
diff --git a/built/prog-z80.bin b/built/prog-z80.bin
index bbb92e2..1658d7f 100644
--- a/built/prog-z80.bin
+++ b/built/prog-z80.bin
Binary files differ
diff --git a/c/echo.c b/c/echo.c
index e488e33..23bd409 100644
--- a/c/echo.c
+++ b/c/echo.c
@@ -98,7 +98,7 @@ void echo_init(const void **list) {
// Set up global volume
int i;
- for (i = 0; i < 12; i++)
+ for (i = 0; i < 16; i++)
z80_ram[0x1FE0+i] = 0;
z80_ram[0x1FEC] = 1;
z80_ram[0x1FF1] = 1;
@@ -120,15 +120,19 @@ void echo_send_command(uint8_t cmd) {
Z80_REQUEST();
// Is Echo busy yet?
- while (z80_ram[0x1FFF] != 0x00) {
- Z80_RELEASE();
- DELAY();
- Z80_REQUEST();
+ volatile uint8_t *ptr = &z80_ram[0x1FFC]
+ if (ptr[3] != 0x00) {
+ ptr -= 4;
+ while (ptr[3] != 0x00) {
+ Z80_RELEASE();
+ DELAY();
+ Z80_REQUEST();
+ }
}
// Write the command
- z80_ram[0x1FFF] = cmd;
-
+ ptr[3] = cmd;
+
// Done with the Z80
Z80_RELEASE();
}
@@ -151,21 +155,25 @@ void echo_send_command_addr(uint8_t cmd, const void *addr) {
Z80_REQUEST();
// Is Echo busy yet?
- while (z80_ram[0x1FFF] != 0x00) {
- Z80_RELEASE();
- DELAY();
- Z80_REQUEST();
+ volatile uint8_t *ptr = &z80_ram[0x1FFC]
+ if (ptr[3] != 0x00) {
+ ptr -= 4;
+ while (ptr[3] != 0x00) {
+ Z80_RELEASE();
+ DELAY();
+ Z80_REQUEST();
+ }
}
// Write the command
- z80_ram[0x1FFF] = cmd;
- z80_ram[0x1FFD] = param;
+ ptr[3] = cmd;
+ ptr[1] = param;
param >>= 8;
- z80_ram[0x1FFE] = param | 0x80;
+ ptr[2] = param | 0x80;
param >>= 7;
param = (param & 0x7F) | (param >> 1 & 0x80);
- z80_ram[0x1FFC] = param;
-
+ ptr[0] = param;
+
// Done with the Z80
Z80_RELEASE();
}
@@ -183,17 +191,20 @@ void echo_send_command_byte(uint8_t cmd, uint8_t byte) {
Z80_REQUEST();
// Is Echo busy yet?
- while (z80_ram[0x1FFF] != 0x00) {
- Z80_RELEASE();
- int16_t i;
- for (i = 0x3FF; i >= 0; i--);
- Z80_REQUEST();
+ volatile uint8_t *ptr = &z80_ram[0x1FFC]
+ if (ptr[3] != 0x00) {
+ ptr -= 4;
+ while (ptr[3] != 0x00) {
+ Z80_RELEASE();
+ DELAY();
+ Z80_REQUEST();
+ }
}
// Write the command
- z80_ram[0x1FFF] = cmd;
- z80_ram[0x1FFC] = byte;
-
+ ptr[3] = cmd;
+ ptr[0] = byte;
+
// Done with the Z80
Z80_RELEASE();
}
@@ -219,15 +230,22 @@ void echo_stop_bgm(void) {
}
//***************************************************************************
+// echo_pause_bgm
+// Pauses background music playback.
+//***************************************************************************
+
+void echo_pause_bgm(void) {
+ echo_send_command(ECHO_CMD_PAUSEBGM);
+}
+
+//***************************************************************************
// echo_resume_bgm
// Resumes background music playback.
//***************************************************************************
-/*
void echo_resume_bgm(void) {
echo_send_command(ECHO_CMD_RESUMEBGM);
}
-*/
//***************************************************************************
// echo_play_sfx
@@ -328,7 +346,7 @@ void echo_set_volume_ex(const uint8_t *ptr) {
// Store the new volume values
int i;
- for (i = 0; i < 13; i++)
+ for (i = 0; i < 16; i++)
z80_ram[0x1FE0+i] = ptr[i];
// Tell Echo to update all the volumes
@@ -363,7 +381,7 @@ uint16_t echo_get_status(void) {
// Retrieve status from Z80 RAM
uint16_t status = 0;
status = z80_ram[0x1FF0];
- if (z80_ram[0x1FFF] != 0)
+ if (z80_ram[0x1FFB] != 0)
status |= ECHO_STAT_BUSY;
if (z80_ram[0x1F00] != 0xFF)
status |= ECHO_STAT_DIRBUSY;
@@ -374,3 +392,46 @@ uint16_t echo_get_status(void) {
// Return status
return status;
}
+
+//***************************************************************************
+// echo_get_flags
+// Gets the current values of the flags.
+//---------------------------------------------------------------------------
+// return: bitmask with flags
+//***************************************************************************
+
+uint8_t echo_get_flags(void)
+{
+ Z80_REQUEST();
+ uint8_t flags = z80_ram[0x1FF2];
+ Z88_RELEASE();
+ return flags;
+}
+
+//***************************************************************************
+// echo_set_flags
+// Sets flags from the 68000.
+//---------------------------------------------------------------------------
+// param flags: bitmask of flags to be set (1 = set, 0 = intact)
+//***************************************************************************
+
+void echo_set_flags(uint8_t flags)
+{
+ Z80_REQUEST();
+ z80_ram[0x1FF2] |= flags;
+ Z80_RELEASE();
+}
+
+//***************************************************************************
+// echo_clear_flags
+// Clears flags from the 68000.
+//---------------------------------------------------------------------------
+// param flags: bitmask of flags to be cleared (1 = clear, 0 = intact)
+//***************************************************************************
+
+void echo_clear_flags(uint8_t flags)
+{
+ Z80_REQUEST();
+ z80_ram[0x1FF2] &= ~flags;
+ Z80_RELEASE();
+}
diff --git a/c/echo.h b/c/echo.h
index 56088b6..c1d6062 100644
--- a/c/echo.h
+++ b/c/echo.h
@@ -14,6 +14,7 @@ enum {
ECHO_CMD_STOPBGM, /* 0x05 - Stop BGM playback */
ECHO_CMD_RESUMEBGM, /* 0x06 - Resume BGM playback */
ECHO_CMD_SETPCMRATE, /* 0x07 - Set PCM rate */
+ ECHO_CMD_PAUSEBGM, /* 0x08 - Pause BGM playback */
};
/* Echo status flags */
@@ -23,20 +24,24 @@ enum {
#define ECHO_STAT_BUSY 0x8000 /* Echo still didn't parse command */
/* Function prototypes */
-void echo_init(const void **);
-void echo_play_bgm(const void *);
+void echo_init(const void **list);
+void echo_play_bgm(const void *esf);
void echo_stop_bgm(void);
-/*void echo_resume_bgm(void);*/
-void echo_play_sfx(const void *);
+void echo_pause_bgm(void);
+void echo_resume_bgm(void);
+void echo_play_sfx(const void *esf);
void echo_stop_sfx(void);
-void echo_play_direct(const void *);
-void echo_set_volume(uint8_t);
-void echo_set_volume_ex(const uint8_t *);
-void echo_set_pcm_rate(uint8_t);
+void echo_play_direct(const void *esf);
+void echo_set_volume(uint8_t vol);
+void echo_set_volume_ex(const uint8_t *vol_list);
+void echo_set_pcm_rate(uint8_t rate);
uint16_t echo_get_status(void);
-void echo_send_command(uint8_t);
-void echo_send_command_addr(uint8_t, const void *);
-void echo_send_command_byte(uint8_t, uint8_t);
+uint8_t echo_get_flags(void);
+void echo_set_flags(uint8_t flags);
+void echo_clear_flags(uint8_t flags);
+void echo_send_command(uint8_t cmd);
+void echo_send_command_addr(uint8_t cmd, const void *addr);
+void echo_send_command_byte(uint8_t cmd, uint8_t byte);
/* Deprecated functions */
static void (* const echo_send_command_ex)(uint8_t, const void *) =
diff --git a/c/echoblob.h b/c/echoblob.h
index 827cc5b..e4c8d4d 100644
--- a/c/echoblob.h
+++ b/c/echoblob.h
@@ -1,285 +1,269 @@
static uint8_t echo_blob[] = {
- 49,224, 31,175, 50,240, 31, 33, 17,127, 54,159, 54,191, 54,223,
- 54,255,175, 50, 0, 19, 50, 16, 19, 50, 32, 19, 50, 48, 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,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,239,
- 0, 61,202, 83, 1, 61,202,109, 5, 61,202,156, 6, 61,202, 21,
- 3, 61,202,159, 4, 61,202,102, 3, 61,202,243, 2, 58, 0, 64,
- 15,220, 34, 2,175, 50,255, 31, 58, 0, 64, 15,220, 34, 2, 58,
- 255, 31,183, 32,204, 58, 0, 64, 15,220, 34, 2, 58, 0, 64,203,
- 79, 32, 8,203, 71,196, 34, 2,195,239, 0, 58, 0, 64, 15,220,
- 34, 2,221, 54, 0, 39,221, 54, 1, 47, 58, 0, 64, 15,220, 34,
- 2, 58,241, 31,183,196,227, 16,195, 43, 1, 58, 0, 64, 15,220,
- 34, 2,205, 84, 7, 58, 0, 64, 15,220, 34, 2,195, 63, 1, 58,
- 0, 64, 15,220, 34, 2,195, 4, 13, 58, 0, 64, 15,220, 34, 2,
- 195,239, 0, 33,252, 31, 78, 44, 94, 44, 86,235,175, 50,255, 31,
- 17, 0, 28,205,129, 1,120,183,202,126, 1, 18, 20,205,129, 1,
- 120, 18, 20,205,129, 1,120, 18, 21, 21, 28,195, 99, 1,195,239,
- 0, 58,152, 19,185,202,161, 1,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,173, 1, 36,194,173, 1, 38,128, 12,201,205,200,
- 1,195,230, 5, 58, 0, 64, 15,220, 34, 2, 58,142, 19,183,194,
- 132, 4,205,200, 1,195,195, 3, 58,236, 31,183,200,205,129, 1,
- 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,248, 1,104,
- 123,183,194, 12, 2, 20,194, 12, 2, 22,128, 12,217,175, 50, 34,
- 2,221, 54, 0, 43,221, 54, 1,128,221, 54, 0, 42,221, 54, 1,
- 128,201,201,217,221, 54, 0, 39,221, 54, 1, 31,126, 60, 40, 12,
- 221, 54, 0, 42,221,119, 1, 44, 40, 22,217,201, 6, 0,221, 54,
- 0, 42,221, 54, 1,128,221, 54, 0, 43,221, 54, 1, 0,217,201,
- 58,152, 19,185,202,110, 2,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,187, 2, 20,194,187, 2, 22,128, 12, 46,240,195, 36, 2,
- 205,218, 2,195,230, 5, 58, 0, 64, 15,220, 34, 2, 58,142, 19,
- 183,194,195, 3,205,218, 2,195,195, 3, 62,201, 50, 34, 2,221,
- 54, 0, 43,221, 54, 1, 0,201, 62, 1, 50,142, 19,205,218, 2,
- 195,230, 5, 58,252, 31, 47, 71,175, 50,255, 31,120,221, 54, 0,
- 36, 15, 15,246,192,221,119, 1,120,221, 54, 0, 37,230, 3,221,
- 119, 1,195,239, 0, 58, 0, 64, 15,220, 34, 2,205,205, 4, 58,
- 0, 64, 15,220, 34, 2, 58,240, 31,246, 2, 50,240, 31, 58, 0,
- 64, 15,220, 34, 2, 33,252, 31, 78, 44, 94, 44, 86, 58, 0, 64,
- 15,220, 34, 2,175, 50,255, 31, 33,153, 19, 54, 1, 44, 54, 1,
- 44,113, 44,115, 44,114, 58, 0, 64, 15,220, 34, 2, 33,162, 3,
- 34, 61, 1,195,239, 0,175, 50,255, 31, 6, 8, 17,143, 19, 58,
- 0, 64, 15,220, 34, 2, 26,183,194,135, 3, 58, 0, 64, 15,220,
- 34, 2, 5,205,205, 12, 4, 29, 5,194,111, 3, 58,240, 31,246,
- 2, 50,240, 31, 33,153, 19, 54, 1, 33,162, 3, 34, 61, 1,195,
- 239, 0, 58, 0, 64, 15,220, 34, 2, 33,154, 19,126, 61,202,181,
- 3,119,195, 63, 1, 58, 0, 64, 15,220, 34, 2, 44, 78, 44, 94,
- 44, 86,235, 58, 0, 64, 15,220, 34, 2,205,129, 1, 58, 0, 64,
- 15,220, 34, 2,120,254, 8,218,130, 7,254, 11,218,194, 13,202,
- 70, 14,254, 12,202,180, 1, 58, 0, 64, 15,220, 34, 2,120,254,
- 24,218, 35, 8,254, 28,218,162, 14,202,198, 2, 58, 0, 64, 15,
- 220, 34, 2,120,254,254,202,168, 16,254,255,202,153, 4,254,252,
- 202, 67, 5,254,253,202, 88, 5, 58, 0, 64, 15,220, 34, 2,120,
- 254, 40,218, 14, 10,254, 44,218,255, 14, 58, 0, 64, 15,220, 34,
- 2,120,254, 56,218, 81, 8,254, 59,218, 19, 16,202,109, 16, 58,
- 0, 64, 15,220, 34, 2,120,254, 72,218,208, 8,254, 76,218,150,
- 15, 58, 0, 64, 15,220, 34, 2,120,254,224,218,184, 16,254,248,
- 218,135, 11,254,250,218,226, 11, 58, 0, 64, 15,220, 34, 2,195,
- 153, 4, 58, 0, 64, 15,220, 34, 2, 44,194,132, 4, 36,194,132,
- 4, 38,128, 12, 58, 0, 64, 15,220, 34, 2, 44,194,150, 4, 36,
- 194,150, 4, 38,128, 12,195,195, 3,205,169, 4,195, 63, 1,175,
- 50,255, 31,205,169, 4,195,239, 0, 58,240, 31,230,253, 50,240,
- 31, 58, 0, 64, 15,220, 34, 2,205,205, 4, 58, 0, 64, 15,220,
- 34, 2,175, 50,153, 19, 33, 63, 1, 34, 61, 1,201, 58,142, 19,
- 183,204,218, 2, 6, 4, 17, 63, 19, 33,147, 19, 58, 0, 64, 15,
- 220, 34, 2, 54, 0,123,214, 15, 95,126,183, 32, 2,175, 18, 58,
- 0, 64, 15,220, 34, 2, 29, 45, 16,226, 6, 8, 17, 79, 19, 58,
- 0, 64, 15,220, 34, 2, 62,127, 18, 29, 58, 0, 64, 15,220, 34,
- 2,126,183,194, 52, 5, 5,120,205, 68, 12, 58, 0, 64, 15,220,
- 34, 2,120,230, 4,253,111,120,230, 3,198,180,253,119, 0,253,
- 54, 1,192, 4, 45, 16,200, 33, 80, 19, 62,192, 6, 8,119, 44,
- 16,252,201, 58, 0, 64, 15,220, 34, 2,235, 44, 78, 44, 94, 44,
- 86, 45, 45, 45,235,195,195, 3, 58, 0, 64, 15,220, 34, 2,235,
- 44,113, 44,115, 44,114, 45, 45, 45,235,195,195, 3, 58, 0, 64,
- 15,220, 34, 2,205,216, 6, 58, 0, 64, 15,220, 34, 2, 58,240,
- 31,246, 1, 50,240, 31, 58, 0, 64, 15,220, 34, 2, 33,252, 31,
- 78, 44, 94, 44, 86, 58, 0, 64, 15,220, 34, 2,175, 50,255, 31,
- 33,161, 19, 54, 1, 44, 54, 1, 44,113, 44,115, 44,114, 58, 0,
- 64, 15,220, 34, 2, 33,197, 5, 34, 41, 1, 58, 0, 64, 15,220,
- 34, 2,195,239, 0, 58, 0, 64, 15,220, 34, 2, 33,162, 19,126,
- 61,202,216, 5,119,195, 43, 1, 58, 0, 64, 15,220, 34, 2, 44,
- 78, 44, 94, 44, 86,235, 58, 0, 64, 15,220, 34, 2,205,129, 1,
- 58, 0, 64, 15,220, 34, 2,120,254, 8,218,124, 7,254, 11,218,
- 188, 13,202, 64, 14,254, 12,202,174, 1, 58, 0, 64, 15,220, 34,
- 2,120,254, 24,218, 29, 8,254, 28,218,156, 14,202,192, 2, 58,
- 0, 64, 15,220, 34, 2,120,254,254,202,162, 16,254,255,202,150,
- 6, 58, 0, 64, 15,220, 34, 2,120,254, 40,218, 8, 10,254, 44,
- 218,217, 14, 58, 0, 64, 15,220, 34, 2,120,254, 56,218, 75, 8,
- 254, 59,218, 13, 16,202,103, 16, 58, 0, 64, 15,220, 34, 2,120,
- 254, 72,218,202, 8,254, 76,218, 80, 15, 58, 0, 64, 15,220, 34,
- 2,120,254,224,218,174, 16,254,232,218, 18, 12,254,236,218,122,
- 16,202,232, 2, 58, 0, 64, 15,220, 34, 2,120,254,248,218, 88,
- 11,254,250,218,220, 11,205,166, 6,195, 43, 1,175, 50,255, 31,
- 205,166, 6,195,239, 0, 58, 0, 64, 15,220, 34, 2, 58,240, 31,
- 230,254, 50,240, 31, 58, 0, 64, 15,220, 34, 2,175, 50,161, 19,
- 33, 43, 1, 34, 41, 1, 58, 0, 64, 15,220, 34, 2,205,216, 6,
- 58, 0, 64, 15,220, 34, 2,201, 58,142, 19,183,196,218, 2, 6,
- 4, 17,147, 19, 58, 0, 64, 15,220, 34, 2, 26,183, 40, 64,175,
- 18, 58, 0, 64, 15,220, 34, 2,120, 15, 15, 15, 15, 61, 38, 19,
- 111, 78,214, 15,111,113, 58, 0, 64, 15,220, 34, 2,213,125,198,
- 8,111,198, 4, 95, 84, 58, 0, 64, 15,220, 34, 2, 26,119, 44,
- 28, 26,119, 44, 28, 26,119,209, 58, 0, 64, 15,220, 34, 2, 29,
- 16,178, 6, 8, 58, 0, 64, 15,220, 34, 2, 26,183,202, 78, 7,
- 175, 18, 58, 0, 64, 15,220, 34, 2, 5,205,205, 12, 4, 29, 5,
- 194, 52, 7,201, 58, 0, 31, 60,200, 58, 0, 64, 15,220, 34, 2,
- 33,112, 7, 34, 12, 4, 33, 0, 31, 58,152, 19, 79,195,195, 3,
- 33,153, 4, 34, 12, 4, 62,255, 50, 0, 31,201,205,160, 7,195,
- 230, 5, 71, 58, 0, 64, 15,220, 34, 2,229,120,230, 7, 33,136,
- 19,133,111,126,225,183,194,132, 4,120,205,160, 7,195,195, 3,
- 230, 7,221, 54, 0, 40,221,119, 1, 71, 8, 58, 0, 64, 15,220,
- 34, 2,120,230, 4, 15,253,111, 58, 0, 64, 15,220, 34, 2,205,
- 129, 1, 58, 0, 64, 15,220, 34, 2, 8,213,229, 87,230, 3,198,
- 164, 95, 58, 0, 64, 15,220, 34, 2, 38, 18,120,230, 31,198,144,
- 111, 58, 0, 64, 15,220, 34, 2,120,230,224, 15, 15, 71,126,176,
- 253,115, 0,253,119, 1, 58, 0, 64, 15,220, 34, 2,123,214, 4,
- 95, 45,126,253,115, 0,253,119, 1, 58, 0, 64, 15,220, 34, 2,
- 122,246,240,221, 54, 0, 40,221,119, 1,225,209,201,205, 65, 8,
- 195,230, 5, 71, 58, 0, 64, 15,220, 34, 2,120,229,230, 7, 33,
- 136, 19,133,111,126,225,183,194,195, 3,120,205, 65, 8,195,195,
- 3,230, 7,221, 54, 0, 40,221,119, 1,201,205,111, 8,195,230,
- 5, 71, 58, 0, 64, 15,220, 34, 2,120,229,230, 7, 33,136, 19,
- 133,111,126,225,183,194,114, 4,120,205,111, 8,195,195, 3,245,
- 71, 58, 0, 64, 15,220, 34, 2,120,230, 4, 15,253,111, 58, 0,
- 64, 15,220, 34, 2,205,129, 1, 58, 0, 64, 15,220, 34, 2,241,
- 213,230, 7, 87,230, 3,198,164, 95, 58, 0, 64, 15,220, 34, 2,
- 253,115, 0,253,112, 1, 58, 0, 64, 15,220, 34, 2,205,129, 1,
- 58, 0, 64, 15,220, 34, 2,123,214, 4, 95,253,115, 0,253,112,
- 1, 58, 0, 64, 15,220, 34, 2,209,201,205, 50, 9,195,230, 5,
- 230, 7, 71, 58, 0, 64, 15,220, 34, 2,213,197,120, 17, 64, 19,
- 131, 95, 58, 0, 64, 15,220, 34, 2,205,129, 1, 58, 0, 64, 15,
- 220, 34, 2,120, 18,123,198, 8, 95,175, 18, 89,193, 75,209, 58,
- 0, 64, 15,220, 34, 2,229,120, 38, 19,198,136,111,126,225,183,
- 194,195, 3, 58, 0, 64, 15,220, 34, 2,120,229, 33, 64, 19,133,
- 111, 70,225, 8, 58, 0, 64, 15,220, 34, 2, 8,205, 71, 9,195,
- 195, 3,230, 7, 8, 58, 0, 64, 15,220, 34, 2,205,129, 1, 58,
- 0, 64, 15,220, 34, 2, 8,245,230, 4, 15,253,111, 58, 0, 64,
- 15,220, 34, 2,241,197,213,229, 38, 28,104, 86, 36, 94, 36, 78,
- 235,245, 58, 0, 64, 15,220, 34, 2, 6, 7, 17,166, 19,120, 8,
- 205,129, 1,235,112,235, 28,205,129, 1,235,112,235, 28,205,129,
- 1,235,112,235, 28,205,129, 1,235,112,235, 28, 8, 71, 16,222,
- 205,129, 1,235,112,235, 58, 0, 64, 15,220, 34, 2,241, 71,205,
- 68, 12,120, 17, 96, 19,230, 7,131, 95,245,230, 3,198,176, 33,
- 166, 19, 8, 58, 0, 64, 15,220, 34, 2, 8,253,119, 0, 70, 44,
- 253,112, 1, 8,120, 18,123,198, 8, 95, 58, 0, 64, 15,220, 34,
- 2, 8,214,128, 6, 28,253,119, 0, 78,253,113, 1,198, 4, 44,
- 16,244, 58, 0, 64, 15,220, 34, 2,125,214, 24,111, 6, 4,126,
- 18,123,198, 8, 95, 44, 16,247, 58, 0, 64, 15,220, 34, 2,241,
- 225,209,193, 6, 0,195,126, 10,205,107, 10,195,230, 5,230, 7,
- 71, 58, 0, 64, 15,220, 34, 2,213,197,120, 22, 19,198, 72, 95,
- 58, 0, 64, 15,220, 34, 2,205,129, 1, 58, 0, 64, 15,220, 34,
- 2,235,112,235, 89,193, 75,209, 58, 0, 64, 15,220, 34, 2,229,
- 120, 33,136, 19,133,111,126,225,183,194,195, 3, 58, 0, 64, 15,
- 220, 34, 2,120,229, 33, 72, 19,133,111, 70,225,245, 58, 0, 64,
- 15,220, 34, 2,241,205,126, 10,195,195, 3,245, 58, 0, 64, 15,
- 220, 34, 2,205,129, 1, 58, 0, 64, 15,220, 34, 2,241,197,213,
- 229,230, 7,245, 38, 19,198, 88,111,112,241,245, 38, 19,198, 96,
- 111, 8, 58, 0, 64, 15,220, 34, 2, 8,230, 7,246,224, 22, 31,
- 95, 8, 26, 87, 58, 0, 64, 15,220, 34, 2, 8,230, 4, 15,253,
- 111, 58, 0, 64, 15,220, 34, 2,241,230, 3,198, 64, 79,126,230,
- 7, 95, 58, 0, 64, 15,220, 34, 2,125,198, 8,111,123,254, 7,
- 56, 17,253,113, 0,126,130,250,222, 10,128,242,224, 10, 62,127,
- 253,119, 1,121,198, 4, 79, 58, 0, 64, 15,220, 34, 2,125,198,
- 8,111,123,254, 5, 56, 17,253,113, 0,126,130,250, 3, 11,128,
- 242, 5, 11, 62,127,253,119, 1,121,198, 4, 79, 58, 0, 64, 15,
- 220, 34, 2,125,198, 8,111,123,254, 4, 56, 17,253,113, 0,126,
- 130,250, 40, 11,128,242, 42, 11, 62,127,253,119, 1,121,198, 4,
- 79, 58, 0, 64, 15,220, 34, 2,125,198, 8,111,253,113, 0,126,
- 130,250, 72, 11,128,242, 74, 11, 62,127,253,119, 1, 58, 0, 64,
- 15,220, 34, 2,225,209,193,201, 71, 58, 0, 64, 15,220, 34, 2,
- 120,230, 4, 15,253,111,120, 8, 58, 0, 64, 15,220, 34, 2,205,
- 129, 1, 58, 0, 64, 15,220, 34, 2, 8,230, 3,198,180,253,119,
- 0,253,112, 1,195,230, 5, 71, 58, 0, 64, 15,220, 34, 2,120,
- 230, 4, 15,253,111,120, 8, 58, 0, 64, 15,220, 34, 2,205,129,
- 1, 58, 0, 64, 15,220, 34, 2, 8,229,230, 7, 38, 19,198, 80,
- 111,112, 8, 58, 0, 64, 15,220, 34, 2, 8,230, 7,198,136,111,
- 8,126,183,225,194,195, 3, 58, 0, 64, 15,220, 34, 2, 8,230,
- 3,198,180,253,119, 0,253,112, 1,195,195, 3,205,232, 11,195,
- 230, 5,205,232, 11,195,195, 3,230, 1,135,253,111, 58, 0, 64,
- 15,220, 34, 2,205,129, 1,197, 58, 0, 64, 15,220, 34, 2,205,
- 129, 1, 58, 0, 64, 15,220, 34, 2,120,193,253,112, 0,253,119,
- 1,201,230, 7, 71, 58, 0, 64, 15,220, 34, 2,229, 38, 19,120,
- 198,136,111, 54, 1,225, 58, 0, 64, 15,220, 34, 2,120,230, 4,
- 15,253,111,120,230, 3,135,135,198,180,253,119, 0,253, 54, 1,
- 192,195,230, 5,230, 7,245,213,229, 79,230, 4, 15,253,111,121,
- 230, 3,198, 64, 14, 6, 33,181, 18, 8, 58, 0, 64, 15,220, 34,
- 2, 8, 94,253,119, 0,253,115, 1,198, 4, 8, 58, 0, 64, 15,
- 220, 34, 2, 8,253,119, 0,253,115, 1,198, 4, 8, 58, 0, 64,
- 15,220, 34, 2, 8,253,119, 0,253,115, 1,198, 4, 8, 58, 0,
- 64, 15,220, 34, 2, 8,253,119, 0,253,115, 1,198, 4, 44, 13,
- 194, 89, 12,225,209, 58, 0, 64, 15,220, 34, 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, 34, 2,201,120, 38, 19,
- 198, 64,111,197,120, 70,205, 71, 9,193, 58, 0, 64, 15,220, 34,
- 2,197,125,198, 8,111,120, 70,205,126, 10,193,125,198, 8,111,
- 120,230, 3,198,180,253,119, 0,126,253,119, 1, 58, 0, 64, 15,
- 220, 34, 2,201, 33, 48, 19, 6, 3,197,126,203,127, 32, 6, 6,
- 15, 44,195,107, 13,230,127, 71, 44,126,128, 71, 58, 0, 64, 15,
- 220, 34, 2,197, 44, 78, 44, 94, 44, 86,235, 58, 0, 64, 15,220,
- 34, 2,205,129, 1, 58, 0, 64, 15,220, 34, 2,120,254,254,202,
- 146, 13,254,255,202,167, 13,253,104, 58, 0, 64, 15,220, 34, 2,
- 235,114, 45,115, 45,113, 45,193, 58, 0, 64, 15,220, 34, 2,253,
- 125,230, 15,128, 71,254, 16, 56, 2, 6, 15, 58, 0, 64, 15,220,
- 34, 2,120, 7, 7, 7,193,176, 15, 15, 15,246,144, 50, 17,127,
- 125,214, 17,111, 58, 0, 64, 15,220, 34, 2, 5,242, 9, 13,195,
- 73, 1, 58, 0, 64, 15,220, 34, 2, 28,235,113, 44,115, 44,114,
- 235, 29, 29, 29,195, 43, 13, 58, 0, 64, 15,220, 34, 2, 28,235,
- 78, 44, 94, 44, 86,235, 29, 29, 29,195, 43, 13,205,224, 13,195,
- 230, 5, 71, 58, 0, 64, 15,220, 34, 2,120,229,230, 3, 33,144,
- 19,133,111,126,225,183,194,132, 4,120,205,224, 13,195,195, 3,
- 230, 3, 71, 8, 58, 0, 64, 15,220, 34, 2,229, 38, 19,120, 15,
- 15, 15, 15,111,126,246,128,119, 58, 0, 64, 15,220, 34, 2,213,
- 44, 44, 84,125,198, 6, 95, 58, 0, 64, 15,220, 34, 2, 26,119,
- 44, 28, 26,119, 44, 28, 26,119,209,225, 58, 0, 64, 15,220, 34,
- 2,205,129, 1, 58, 0, 64, 15,220, 34, 2, 8,229,213, 38, 18,
- 104, 17, 17,127, 15, 15, 15, 70,176, 18, 44,126, 18,209,225,201,
- 205, 83, 14,195,230, 5, 58,147, 19,183,194,132, 4,205, 83, 14,
- 195,195, 3, 58, 0, 64, 15,220, 34, 2,229, 33, 48, 19,126,246,
- 128,119, 58, 0, 64, 15,220, 34, 2,213, 44, 44, 84,125,198, 6,
- 95, 58, 0, 64, 15,220, 34, 2, 26,119, 44, 28, 26,119, 44, 28,
- 26,119,209,225, 58, 0, 64, 15,220, 34, 2,205,129, 1, 58, 0,
- 64, 15,220, 34, 2, 62,224,176, 50, 17,127,201,205,192, 14,195,
- 230, 5, 71, 58, 0, 64, 15,220, 34, 2,120,229,230, 3, 33,144,
- 19,133,111,126,225,183,194,195, 3,120,205,192, 14,195,195, 3,
- 230, 3, 71, 58, 0, 64, 15,220, 34, 2,229, 38, 19,120, 15, 15,
- 15, 15,111,126,230,127,119,225,201,230, 3, 8, 58, 0, 64, 15,
- 220, 34, 2,205,129, 1, 58, 0, 64, 15,220, 34, 2, 8,229, 38,
- 19, 15, 15, 15, 15,111,126,230,128,176,119,225,195,230, 5,230,
- 3, 8, 58, 0, 64, 15,220, 34, 2,205,129, 1, 58, 0, 64, 15,
- 220, 34, 2, 8,213,229,245, 17,144, 19,131, 95, 26, 95, 58, 0,
- 64, 15,220, 34, 2,241, 38, 19, 15, 15, 15, 15,198, 15,111,112,
- 58, 0, 64, 15,220, 34, 2,123,183, 32, 16,125,214, 15,111,126,
- 230,128,176,119, 58, 0, 64, 15,220, 34, 2,225,209,195,195, 3,
- 230, 3, 8, 58, 0, 64, 15,220, 34, 2,205,129, 1, 58, 0, 64,
- 15,220, 34, 2, 8,213,229, 22, 28, 88, 38, 19, 15, 15, 15, 15,
- 198, 10,111, 58, 0, 64, 15,220, 34, 2, 26,119, 20, 45, 26,119,
- 20, 45, 26,119, 58, 0, 64, 15,220, 34, 2,125,214, 8,111, 54,
- 0,225,209,195,230, 5,230, 3, 8, 58, 0, 64, 15,220, 34, 2,
- 205,129, 1, 58, 0, 64, 15,220, 34, 2, 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,220, 34, 2,119, 45, 26,119, 20, 45, 26,119,
- 20, 45, 26,119, 58, 0, 64, 15,220, 34, 2,120,183,202,229, 15,
- 225,209,195,195, 3, 58, 0, 64, 15,220, 34, 2, 84,125,214, 4,
- 95,126, 18, 44, 28,126, 18, 44, 28,126, 18, 58, 0, 64, 15,220,
- 34, 2,125,214, 8,111, 54, 0,225,209,195,195, 3,205, 49, 16,
- 195,230, 5, 71, 58, 0, 64, 15,220, 34, 2,120,229,230, 15, 38,
- 19,198,136,111,126,225,183,194,114, 4,120,205, 49, 16,195,195,
- 3,230, 3, 8, 58, 0, 64, 15,220, 34, 2,205,129, 1, 58, 0,
- 64, 15,220, 34, 2, 8,213, 17, 17,127, 15, 15, 15,176,246,128,
- 18, 58, 0, 64, 15,220, 34, 2,205,129, 1, 58, 0, 64, 15,220,
- 34, 2,235,112,235,209,201,205,132, 14,195,230, 5, 58,147, 19,
- 183,194,132, 4,205,132, 14,195,195, 3,230, 3, 71, 58, 0, 64,
- 15,220, 34, 2,229, 38, 19,120,198,144,111, 54, 1, 58, 0, 64,
- 15,220, 34, 2,120, 15, 15, 15, 15,111, 38, 19, 54, 0,225,195,
- 230, 5,205,194, 16,195, 43, 1,205,194, 16,195, 63, 1,230, 15,
- 60, 71,205,211, 16,195, 43, 1,230, 15, 60, 71,205,211, 16,195,
- 63, 1, 58, 0, 64, 15,220, 34, 2,205,129, 1, 58, 0, 64, 15,
- 220, 34, 2,235,114, 45,115, 45,113, 58, 0, 64, 15,220, 34, 2,
- 45,112,201, 33,240, 31, 17, 88, 19, 14, 8, 26, 70,128,242,243,
- 16, 62,127, 71,125,205,126, 10, 44, 28, 13, 32,238, 33,232, 31,
- 17, 1, 19, 1, 16, 4,126, 18, 44,123,129, 95, 58, 0, 64, 15,
- 220, 34, 2, 16,241,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,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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, 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,
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,
@@ -313,9 +297,9 @@ 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, 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,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 8c0995c..3293b9e 100644
--- a/doc/api-asm.68k
+++ b/doc/api-asm.68k
@@ -20,6 +20,7 @@ Unless stated otherwise, calling the API subroutines will *not* modify the
*** Initialization ***
Echo_Init
+ in a0 = pointer to instrument 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
@@ -42,20 +43,29 @@ Echo_Init
*** Background music ***
Echo_PlayBGM
+ in a0 = pointer to ESF data to play
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).
+ Stops playback of background music. Used both to stop and to pause music.
+
+Echo_PauseBGM
+
+ Pauses BGM playback (SFXs should be unaffected).
+
+Echo_ResumeBGM
+
+ Resumes BGM playback after it has been paused with Echo_PauseBGM.
=============================================================================
*** Sound effects ***
Echo_PlaySFX
+ in a0 = pointer to ESF data to play
Starts playback of the specified sound effect. The register a0 points to
the ESF data for the sound effect.
@@ -69,6 +79,7 @@ Echo_StopSFX
*** Direct events ***
Echo_PlayDirect
+ in a0 = pointer to ESF data to inject
Injects events to be played as part of the BGM the next tick. The register
a0 points to the ESF data to be injected.
@@ -91,6 +102,7 @@ Echo_PlayDirect
*** Control ***
Echo_GetStatus
+ out d0 = status (see below)
Gets the current status of Echo. The status is returned as a word in d0,
with the following bits set as relevant:
@@ -105,6 +117,7 @@ Echo_GetStatus
the 68000 until Echo is ready to take more commands.
Echo_SetVolume
+ in d0 = new volume ($00 = quietest, $FF = loudest)
Sets the global volume. Register d0 is a byte value ranging from 0
(quietest) to 255 (loudest), and every channel is affected immediately.
@@ -114,20 +127,26 @@ Echo_SetVolume
on the volume value (the cut off point is at 25%).
Echo_SetVolumeEx
+ in a0 = pointer to volume data (see below)
Sets the global volume for each channel separately. Register a0 points to
- a list of 13 bytes (one for each Echo channel). Values for FM and PSG
+ 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.
The last byte (the one belonging to the PCM channel) is used to toggle
whether PCM plays, either 0 (disabled) or 1 (enabled).
+
+ NOTE: the Echo 1.4 docs requested for 13 bytes instead of 16. This has
+ been changed for the sake of expansion. Currently the extra bytes are
+ ignored, but consider adapting your code (just set them to zero).
=============================================================================
*** Settings ***
Echo_SetPCMRate
+ in d0 = new PCM rate (see below)
Changes the sample rate of PCM. Note this is a global parameter as it
affects both BGM and SFX. The value is what one would write in timer A of
@@ -153,17 +172,22 @@ Echo_SetPCMRate
*** Raw access ***
Echo_SendCommand
+ in d0 = command
Sends an argument-less command to Echo. The command ID is given as a byte
in register d0.
Echo_SendCommandAddr
+ in d0 = command
+ in a0 = address
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.
Echo_SendCommandByte
+ in d0 = command
+ in d1 = argument
Sends a command to Echo that takes a byte as its argument. The command ID
is given as a byte in register d0, while the byte argument is given in
diff --git a/doc/api-c.txt b/doc/api-c.txt
index 24c6312..541a895 100644
--- a/doc/api-c.txt
+++ b/doc/api-c.txt
@@ -52,8 +52,15 @@ void echo_play_bgm(const void *esf)
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).
+ Stops playback of background music. Used both to stop and to pause music.
+
+void echo_pause_bgm()
+
+ Pauses BGM playback (SFXs should be unaffected).
+
+void echo_resume_bgm()
+
+ Resumes BGM playback after it has been paused with echo_pause_bgm.
=============================================================================
@@ -120,12 +127,16 @@ void echo_set_volume(uint8_t vol)
void echo_set_volume_ex(const uint8_t *ptr)
Sets the global volume for each channel separately. The parameter 'ptr'
- points to a list of 13 bytes (one for each Echo channel). Values for FM
+ 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.
The last byte (the one belonging to the PCM channel) is used to toggle
whether PCM plays, either 0 (disabled) or 1 (enabled).
+
+ NOTE: the Echo 1.4 docs requested for 13 bytes instead of 16. This has
+ been changed for the sake of expansion. Currently the extra bytes are
+ ignored, but consider adapting your code (just set them to zero).
=============================================================================
@@ -162,6 +173,7 @@ void echo_send_command(uint8_t command)
command to send, and may be one of the following:
ECHO_CMD_STOPBGM ..... Stop background music playback
+ ECHO_CMD_PAUSEBGM .... Pause background music playback
ECHO_CMD_RESUMEBGM ... Resume background music playback
ECHO_CMD_STOPSFX ..... Stop sound effect playback
diff --git a/doc/esf.txt b/doc/esf.txt
index a96e35d..eb04474 100644
--- a/doc/esf.txt
+++ b/doc/esf.txt
@@ -367,12 +367,27 @@ $F9rrnn: Set FM register in bank 1
=============================================================================
-$FC: Go to loop [BGM ONLY]
-$FD: Set loop point [BGM ONLY]
+$FAnn: Set flags
- This event are used in BGM streams to loop music. Put event $FD where the
+ This event will set some of the flags. The value nn is a bitmask that is
+ OR'd with the current flags.
+
+$FBnn: Clear flags
+
+ This event will clear some of the flags. The value nn is a bitmask that
+ is AND'd with the current flags.
+
+=============================================================================
+
+$FC: Go to loop
+$FD: Set loop point
+
+ This event are used in 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.
+
+ SFX support for this event was added in 1.5, if you loop a sound effect
+ you'll have to either stop it manually or play another SFX.
$FEnn: Delay ticks
diff --git a/src-68k/echo.68k b/src-68k/echo.68k
index f10695a..e6682bd 100644
--- a/src-68k/echo.68k
+++ b/src-68k/echo.68k
@@ -40,12 +40,16 @@ Echo_Z80Reset macro
;****************************************************************************
Echo_SendCommand:
- move.w d1, -(sp) ; Save register
-
+ movem.l d1/a1, -(sp) ; Save registers
Echo_Z80Request ; We need the Z80 bus
+ lea ($A01FFF), a1 ; First try the 1st slot
+ tst.b (a1) ; Is 1st slot available?
+ beq.s @Ready ; If so, move on
+ subq.l #4, a1 ; Try 2nd slot otherwise
+
@Try:
- tst.b ($A01FFF) ; Check if Echo is ready
+ tst.b (a1) ; Check if 2nd slot is ready
beq.s @Ready ; Too busy?
Echo_Z80Release ; Let Echo continue
move.w #$FF, d1 ; Give it some time
@@ -54,10 +58,10 @@ Echo_SendCommand:
bra.s @Try ; Try again
@Ready:
- move.b d0, ($A01FFF) ; Write command ID
+ move.b d0, (a1) ; Write command ID
Echo_Z80Release ; We're done with the Z80 bus
- move.w (sp)+, d1 ; Restore register
+ movem.l (sp)+, d1/a1 ; Restore registers
rts ; End of subroutine
;****************************************************************************
@@ -70,12 +74,16 @@ Echo_SendCommand:
Echo_SendCommandAddr:
Echo_SendCommandEx:
- movem.l d0-d1, -(sp) ; Save register
-
+ movem.l d0-d1/a1, -(sp) ; Save registers
Echo_Z80Request ; We need the Z80 bus
+ lea ($A01FFF), a1 ; First try the 1st slot
+ tst.b (a1) ; Is 1st slot available?
+ beq.s @Ready ; If so, move on
+ subq.l #4, a1 ; Try 2nd slot otherwise
+
@Try:
- tst.b ($A01FFF) ; Check if Echo is ready
+ tst.b (a1) ; Check if 2nd slot is ready
beq.s @Ready ; Too busy?
Echo_Z80Release ; Let Echo continue
move.w #$FF, d1 ; Give it some time
@@ -84,14 +92,14 @@ Echo_SendCommandEx:
bra.s @Try ; Try again
@Ready:
- move.b d0, ($A01FFF) ; Write command ID
+ move.b d0, (a1) ; Write command ID
move.l a0, d0 ; Easier to manipulate here
- move.b d0, ($A01FFD) ; Store low address byte
+ move.b d0, -2(a1) ; 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
+ move.b d0, -1(a1) ; Store high address byte
lsr.w #8, d0 ; Get bank byte
move.w d0, d1 ; Parse 32X bit separately
@@ -99,11 +107,11 @@ Echo_SendCommandEx:
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
+ move.b d0, -3(a1) ; Store bank byte
Echo_Z80Release ; We're done with the Z80 bus
- movem.l (sp)+, d0-d1 ; Restore register
+ movem.l (sp)+, d0-d1/a1 ; Restore registers
rts ; End of subroutine
;****************************************************************************
@@ -115,11 +123,16 @@ Echo_SendCommandEx:
;****************************************************************************
Echo_SendCommandByte:
+ movem.l d1/a1, -(sp) ; Save registers
Echo_Z80Request ; We need the Z80 bus
- move.w d1, -(sp) ; Save register
+ lea ($A01FFF), a1 ; First try the 1st slot
+ tst.b (a1) ; Is 1st slot available?
+ beq.s @Ready ; If so, move on
+ subq.l #4, a1 ; Try 2nd slot otherwise
+
@Try:
- tst.b ($A01FFF) ; Check if Echo is ready
+ tst.b (a1) ; Check if 2nd slot is ready
beq.s @Ready ; Too busy?
Echo_Z80Release ; Let Echo continue
move.w #$FF, d1 ; Give it some time
@@ -128,11 +141,11 @@ Echo_SendCommandByte:
bra.s @Try ; Try again
@Ready:
- move.w (sp)+, d1 ; Restore register
- move.b d0, ($A01FFF) ; Write command ID
- move.b d1, ($A01FFC) ; Write parameter
+ move.b d0, (a1) ; Write command ID
+ move.b d1, -3(a1) ; Write parameter
Echo_Z80Release ; We're done with the Z80 bus
+ movem.l (sp)+, d1/a1 ; Restore registers
rts ; End of subroutine
;****************************************************************************
@@ -147,6 +160,11 @@ Echo_PlaySFX:
move.b #$02, d0 ; Command $02 = play SFX
bsr Echo_SendCommandAddr ; Send command to Echo
move.w (sp)+, d0 ; Restore register
+
+ Echo_Z80Request ; We need Z80 RAM access...
+ ori.b #$01, ($A01FF0) ; Force SFX flag to be on
+ Echo_Z80Release ; OK done with it for real
+
rts ; End of subroutine
;****************************************************************************
@@ -159,6 +177,11 @@ Echo_StopSFX:
move.b #$03, d0 ; Command $03 = stop SFX
bsr Echo_SendCommand ; Send command to Echo
move.w (sp)+, d0 ; Restore register
+
+ Echo_Z80Request ; We need Z80 RAM access...
+ andi.b #$FE, ($A01FF0) ; Force SFX flag to be off
+ Echo_Z80Release ; OK done with it for real
+
rts ; End of subroutine
;****************************************************************************
@@ -173,6 +196,11 @@ Echo_PlayBGM:
move.b #$04, d0 ; Command $04 = play BGM
bsr Echo_SendCommandAddr ; Send command to Echo
move.w (sp)+, d0 ; Restore register
+
+ Echo_Z80Request ; We need Z80 RAM access...
+ ori.b #$02, ($A01FF0) ; Force BGM flag to be on
+ Echo_Z80Release ; OK done with it for real
+
rts ; End of subroutine
;****************************************************************************
@@ -185,6 +213,23 @@ Echo_StopBGM:
move.b #$05, d0 ; Command $05 = stop BGM
bsr Echo_SendCommand ; Send command to Echo
move.w (sp)+, d0 ; Restore register
+
+ Echo_Z80Request ; We need Z80 RAM access...
+ andi.b #$FD, ($A01FF0) ; Force BGM flag to be off
+ Echo_Z80Release ; OK done with it for real
+
+ rts ; End of subroutine
+
+;****************************************************************************
+; Echo_PauseBGM
+; Pauses BGM playback
+;****************************************************************************
+
+Echo_PauseBGM:
+ move.w d0, -(sp) ; Save register
+ move.b #$08, d0 ; Command $08 = pause BGM
+ bsr Echo_SendCommand ; Send command to Echo
+ move.w (sp)+, d0 ; Restore register
rts ; End of subroutine
;****************************************************************************
@@ -192,12 +237,12 @@ Echo_StopBGM:
; Resumes BGM playback
;****************************************************************************
-;Echo_ResumeBGM:
-; move.w d0, -(sp) ; Save register
-; move.b #$06, d0 ; Command $06 = resume BGM
-; bsr Echo_SendCommand ; Send command to Echo
-; move.w (sp)+, d0 ; Restore register
-; rts ; End of subroutine
+Echo_ResumeBGM:
+ move.w d0, -(sp) ; Save register
+ move.b #$06, d0 ; Command $06 = resume BGM
+ bsr Echo_SendCommand ; Send command to Echo
+ move.w (sp)+, d0 ; Restore register
+ rts ; End of subroutine
;****************************************************************************
; Echo_PlayDirect
@@ -311,10 +356,11 @@ Echo_SetVolume:
; Echo_SetVolumeEx
; Changes the global volume for each individual channel.
;
-; input a0.l ... Pointer to 13 bytes
+; input a0.l ... Pointer to 16 bytes
; 8 bytes with FM volumes (0..127)
; 4 bytes with PSG volumes (0..15)
; 1 byte with PCM toggle (0/1)
+; 3 reserved (unused for now)
;****************************************************************************
Echo_SetVolumeEx:
@@ -335,6 +381,9 @@ Echo_SetVolumeEx:
move.b (a0)+, (a1)+ ; PSG channel 2
move.b (a0)+, (a1)+ ; PSG channel 3
move.b (a0)+, (a1)+ ; PCM channel toggle
+ move.b (a0)+, (a1)+ ; (reserved)
+ move.b (a0)+, (a1)+ ; (reserved)
+ move.b (a0)+, (a1)+ ; (reserved)
move.b #1, ($A01FF1) ; Tell Echo to update the volume levels
@@ -358,9 +407,9 @@ Echo_GetStatus:
Echo_Z80Request ; We need the Z80 bus
move.b ($A01FF0), d0 ; Get the status flags
- tst.b ($A01FFF) ; Check if command still has to be parsed
- beq.s @NotBusy ; Any commands left to be parsed?
- bset.l #15, d0 ; If so, set the relevant flag
+ tst.b ($A01FFB) ; Check if any commands can be sent
+ beq.s @NotBusy ; Any room left for new commands?
+ bset.l #15, d0 ; If not, set the relevant flag
@NotBusy:
cmpi.b #$FF, ($A01F00) ; Check if the direct buffer is empty
@@ -372,6 +421,63 @@ Echo_GetStatus:
rts ; End of subroutine
;****************************************************************************
+; Echo_GetFlags
+; Gets the current values of the flags.
+;
+; output d0.b ... Bitmask with flags
+;****************************************************************************
+
+Echo_GetFlags:
+ Echo_Z80Request ; Request Z80 bus
+ move.b ($A01FF2), d0 ; Get the flags
+ Echo_Z80Release ; Done with Z80 RAM
+ rts ; End of subroutine
+
+;****************************************************************************
+; Echo_SetFlags
+; Sets flags from the 68000.
+;
+; input d0.b ... Bitmask of flags to be set (1 = set, 0 = intact)
+;****************************************************************************
+
+Echo_SetFlags:
+ subq.w #4, sp ; Buffer for the events
+ move.b #$FA, (sp) ; Set flags
+ move.b d0, 1(sp) ; <bitmask>
+ move.b #$FF, 2(sp) ; End of stream
+
+ move.l a0, -(sp) ; Issue the events
+ lea 4(sp), a0
+ bsr Echo_PlayDirect
+ move.l (sp)+, a0
+
+ addq.w #4, sp ; Done with the buffer
+ rts ; End of subroutine
+
+;****************************************************************************
+; Echo_ClearFlags
+; Clear flags from the 68000.
+;
+; input d0.b ... Bitmask of flags to be cleared (1 = clear, 0 = intact)
+;****************************************************************************
+
+Echo_ClearFlags:
+ not.b d0 ; Bitmask is inverted
+ subq.w #4, sp ; Buffer for the events
+ move.b #$FB, (sp) ; Set flags
+ move.b d0, 1(sp) ; <bitmask>
+ move.b #$FF, 2(sp) ; End of stream
+ not.b d0 ; Restore register
+
+ move.l a0, -(sp) ; Issue the events
+ lea 4(sp), a0
+ bsr Echo_PlayDirect
+ move.l (sp)+, a0
+
+ addq.w #4, sp ; Done with the buffer
+ rts ; End of subroutine
+
+;****************************************************************************
; Echo_ListEntry
; Defines an entry in a pointer list
;****************************************************************************
@@ -443,6 +549,9 @@ Echo_Init:
move.b d0, (a0)+
move.b d0, (a0)+
move.b #1, (a0)+
+ move.b d0, (a0)+
+ move.b d0, (a0)+
+ move.b d0, (a0)+
move.b d0, ($A01FF1)
move.b #$FF, ($A01F00) ; No direct events to execute
diff --git a/src-z80/build.z80 b/src-z80/build.z80
index 1aaa709..2f7fd5f 100644
--- a/src-z80/build.z80
+++ b/src-z80/build.z80
@@ -1,11 +1,15 @@
- include "src-z80/core/main.z80"
+ jp EntryPoint ; Jump to the entry point
+ db 0,0,0,0,0 ; Padding to 0008h
+
+ include "src-z80/core/macro.z80"
include "src-z80/player/pcm.z80"
+ include "src-z80/core/main.z80"
include "src-z80/core/bgm.z80"
include "src-z80/core/sfx.z80"
include "src-z80/core/direct.z80"
include "src-z80/player/fm.z80"
include "src-z80/player/psg.z80"
include "src-z80/player/misc.z80"
-
+
include "src-z80/player/freq.z80"
include "src-z80/core/vars.z80"
diff --git a/src-z80/core/bgm.z80 b/src-z80/core/bgm.z80
index 338a7a6..b48d87a 100644
--- a/src-z80/core/bgm.z80
+++ b/src-z80/core/bgm.z80
@@ -25,13 +25,14 @@ PlayBGM:
PollPCM
- xor a ; Command parsed
- ld (RAM_Command), a
+ xor a ; Playing a BGM immediately unpauses playback
+ ld (RAM_Paused), a
+ inc a
ld hl, RAM_BGMData ; Set BGM as playing
- ld (hl), $01
+ ld (hl), a
inc l ; No delays!
- ld (hl), $01
+ ld (hl), a
inc l ; Store BGM start bank
ld (hl), c
inc l ; Store BGM start address (low)
@@ -44,55 +45,111 @@ PlayBGM:
ld hl, ProcessBGM ; Tell Echo to process BGM
ld (DoTick_BGM+1), hl
- jp IdleLoop ; End of subroutine
+ jp EndOfCommand ; End of subroutine
;****************************************************************************
-; ResumeBGM [command $06]
-; Resumes a stopped BGM
+; PauseBGM [command $08]
+; Pauses a playing BGM
;----------------------------------------------------------------------------
; breaks: all
;****************************************************************************
-ResumeBGM:
- xor a ; Command parsed
- ld (RAM_Command), a
+PauseBGM:
+ ld a, (RAM_BGMPlaying) ; Is BGM even playing?
+ or a
+ jp z, EndOfCommand
+
+ ld a, 1 ; Halt BGM playback
+ ld (RAM_Paused), a
;----------------------------------------------------------------------------
-
- ld b, 8 ; Restore all FM channels
- ld de, RAM_Locked+7
-.restorefm:
+ ld b, $7F ; Mute all FM channels
+ ld c, 7
+ ld hl, RAM_Locked+7
+.mutefm:
PollPCM
-
- ld a, (de) ; Check if this channel is locked
+ ld a, (hl)
or a
- jp nz, .fmlocked
-
+ jr nz, .nofmmute
+ ld a, c
+ call SetFMVolTempLoad
+.nofmmute:
PollPCM
+ dec l
+ dec c
+ jp p, .mutefm
- dec b ; Restore FM channel
- call RestoreFM
- inc b
-
-.fmlocked:
- dec e ; Go for next channel to restore
- dec b
- jp nz, .restorefm
+ ld b, 4 ; Mute all PSG channels
+ ld c, $0F
+ ld de, RAM_Locked+8
+ ld hl, RAM_PSGData
+.mutepsg:
+ PollPCM
+ ld a, (de)
+ or a
+ jr nz, .nopsgmute
+ ld a, (hl)
+ and $80
+ or c,
+ ld (hl), a
+.nopsgmute:
+ PollPCM
+ ld a, l
+ add 16
+ ld l, a
+ inc e
+ djnz .mutepsg
;----------------------------------------------------------------------------
- ld a, (RAM_Status) ; Show BGM playback in Echo's status
- or $02
- ld (RAM_Status), a
+ ld a, (RAM_Locked+6) ; Mute PCM channel
+ or a
+ call z, StopPCM
- ld hl, RAM_BGMData ; Set BGM as playing
- ld (hl), $01
+;----------------------------------------------------------------------------
+
+ jp EndOfCommand ; End of subroutine
+
+;****************************************************************************
+; ResumeBGM [command $06]
+; Resumes a stopped BGM
+;----------------------------------------------------------------------------
+; breaks: all
+;****************************************************************************
+
+ResumeBGM:
+ ld a, (RAM_BGMPlaying) ; Was BGM even playing?
+ or a
+ jp z, EndOfCommand
- ld hl, ProcessBGM ; Tell Echo to process BGM
- ld (DoTick_BGM+1), hl
+ xor a
+ ld (RAM_Paused), a ; Resume BGM playback
- jp IdleLoop ; End of subroutine
+ ld b, 4 ; Restore PSG channels
+ ld de, RAM_Locked+11
+ ld hl, RAM_PSGData+63
+.resumepsg:
+ PollPCM
+ ld c, (hl)
+ ld a, l
+ sub 15
+ ld l, a
+ ld a, (de)
+ or a
+ jr nz, .nopsgresume
+ ld a, (hl)
+ and $80
+ or c
+ ld (hl), a
+.nopsgresume:
+ PollPCM
+ dec l
+ dec e
+ djnz .resumepsg
+
+ call RefreshVolume ; Restore remaining channels
+ jp EndOfCommand ; End of subroutine
;****************************************************************************
; ProcessBGM
@@ -197,6 +254,9 @@ ProcessBGMEventFF:
jp c, SetFMParamBGM
cp $FA ; Events $F8-$F9: set FM register
jp c, SetFMRegBGM
+ jp z, SetFlagsBGM ; Events $FA-$FB: set/clear flags
+ cp $FB
+ jp z, ClearFlagsBGM
PollPCM ; FFFFFFFFF bad event >:(
ProcessBGMEnd:
@@ -234,10 +294,8 @@ StopBGMEvent:
jp DoTick_BGMSkip ; End of subroutine
StopBGMCmd:
- xor a ; Command parsed
- ld (RAM_Command), a
call StopBGM ; We're just a wrapper
- jp IdleLoop ; End of subroutine
+ jp EndOfCommand ; End of subroutine
StopBGM:
ld a, (RAM_Status) ; Hide BGM playback in Echo's status
@@ -271,7 +329,7 @@ ClearBGM:
ld b, 4 ; Reset all PSG channels
ld de, RAM_PSGData+48+15
ld hl, RAM_Locked+11
-.mutepsg:
+.killpsg:
PollPCM
ld (hl), $00 ; Reset BGM volume
@@ -282,22 +340,22 @@ ClearBGM:
ld a, (hl) ; Mute PSG channel if it isn't locked
or a
- jr nz, .nopsgmute
+ jr nz, .nopsgkill
xor a
ld (de), a
-.nopsgmute:
+.nopsgkill:
PollPCM
dec e
dec l
- djnz .mutepsg
+ djnz .killpsg
;----------------------------------------------------------------------------
ld b, 8 ; Reset all FM channels
ld de, RAM_BGMFMVol+7
-.resetfm:
+.killfm:
PollPCM
ld a, $7F ; Reset BGM volume
@@ -328,10 +386,10 @@ ClearBGM:
inc b
.nofmkill:
dec l
- djnz .resetfm
+ djnz .killfm
;----------------------------------------------------------------------------
-
+
ld hl, RAM_BGMFMPan ; Reset panning status (for restoring)
ld a, $C0
ld b, 8
@@ -339,6 +397,9 @@ ClearBGM:
ld (hl), a
inc l
djnz .initpanstat
+
+ xor a ; Reset flags
+ ld (RAM_Flags), a
ret ; End of subroutine
@@ -349,19 +410,11 @@ ClearBGM:
LoopBGM:
PollPCM
-
- ex de, hl ; Get looping address
- inc l
- ld c, (hl)
- inc l
- ld e, (hl)
- inc l
- ld d, (hl)
- dec l
- dec l
- dec l
- ex de, hl
-
+
+ ld hl, (RAM_BGMLoopPoint+1) ; Get looping address
+ ld a, (RAM_BGMLoopPoint)
+ ld c, a
+
jp ProcessBGMRun ; End of subroutine
;****************************************************************************
@@ -371,17 +424,9 @@ LoopBGM:
SetLoopBGM:
PollPCM
-
- ex de, hl
- inc l ; Store loop point address
- ld (hl), c
- inc l
- ld (hl), e
- inc l
- ld (hl), d
- dec l
- dec l
- dec l
- ex de, hl
-
+
+ ld a, c ; Store loop point address
+ ld (RAM_BGMLoopPoint), a
+ ld (RAM_BGMLoopPoint+1), hl
+
jp ProcessBGMRun ; End of subroutine
diff --git a/src-z80/core/macro.z80 b/src-z80/core/macro.z80
new file mode 100644
index 0000000..eedd527
--- /dev/null
+++ b/src-z80/core/macro.z80
@@ -0,0 +1,41 @@
+;****************************************************************************
+; PollPCM
+; Used to update PCM while not idle
+;----------------------------------------------------------------------------
+; breaks: af
+;****************************************************************************
+
+PollPCM: macro
+ ld a, ($4000)
+ rrca
+ rst $08
+ endm
+
+;****************************************************************************
+; BankSwitch
+; Switches into a new bank (won't update player status!)
+;----------------------------------------------------------------------------
+; input A .... New bank to switch into
+; input HL ... Must be $60xx
+;----------------------------------------------------------------------------
+; breaks ..... AF
+;****************************************************************************
+
+BankSwitch: macro
+ ld (hl), a
+ rrca
+ ld (hl), a
+ rrca
+ ld (hl), a
+ rrca
+ ld (hl), a
+ rrca
+ ld (hl), a
+ rrca
+ ld (hl), a
+ rrca
+ ld (hl), a
+ ld (hl), h
+ rrca
+ ld (hl), a
+ endm
diff --git a/src-z80/core/main.z80 b/src-z80/core/main.z80
index 4eb6e5a..387b879 100644
--- a/src-z80/core/main.z80
+++ b/src-z80/core/main.z80
@@ -4,10 +4,11 @@
;****************************************************************************
EntryPoint:
- ld sp, RAM_Stack ; Init stack
+ xor a ; Reset Echo status (we don't clear
+ ld (RAM_Status), a ; RAM_Command since Echo_Init fills in values
+ ld (RAM_Command2), a ; before Echo gets to run!)
- xor a ; Reset Echo status
- ld (RAM_Status), a
+ ld sp, RAM_Stack ; Init stack
ld hl, $7F11 ; Mute PSG
ld (hl), $9F
@@ -88,22 +89,11 @@ EntryPoint:
jp IdleLoop ; Go into idle loop
;****************************************************************************
-; PollPCM
-; Used to update PCM while not idle
-;----------------------------------------------------------------------------
-; breaks: af
-;****************************************************************************
-
-PollPCM: macro
- ld a, ($4000)
- rrca
- call c, UpdatePCM
- endm
-
-;****************************************************************************
; RunCommand
; Checks which command to run
;----------------------------------------------------------------------------
+; notes: doesn't return
+;----------------------------------------------------------------------------
; To-do: replace with pointer list?
;****************************************************************************
@@ -122,17 +112,36 @@ RunCommand:
jp z, ResumeBGM
dec a ; Command $07: set PCM rate
jp z, SetPCMRate
+ dec a ; Command $08: pause BGM
+ jp z, PauseBGM
PollPCM
- xor a ; Bad command, ignore >:(
- ld (RAM_Command), a
+ ; Bad command, ignore >:(
+
+;****************************************************************************
+; EndOfCommand
+; Cleans up when a command finishes
+;----------------------------------------------------------------------------
+; notes: doesn't return
+;****************************************************************************
+EndOfCommand:
+ ld hl, ($1FF8) ; Copy second slot into first
+ ld ($1FFC), hl
+ ld hl, ($1FFA)
+ ld ($1FFE), hl
+
+ xor a ; Free up second slot
+ ld (RAM_Command2), a
+
PollPCM
;****************************************************************************
; IdleLoop
; Loop that runs when not processing SFX or BGM
+;----------------------------------------------------------------------------
+; notes: doesn't return (d'oh)
;****************************************************************************
IdleLoop:
@@ -153,13 +162,11 @@ IdleLoop:
;****************************************************************************
; DoTick
; Called whenever a new tick triggers
+;----------------------------------------------------------------------------
+; notes: doesn't return
;****************************************************************************
DoTick:
-; ld a, (ix+0)
-; bit 0, a
-; call nz, UpdatePCM
-
PollPCM
ld (ix+0), $27 ; Retrigger the timer
@@ -181,6 +188,9 @@ DoTick_SFXSkip:
PollPCM
+ ld a, (RAM_Paused) ; BGMs are paused?
+ or a
+ jr nz, DoTick_BGMSkip
DoTick_BGM: ; Process BGMs
jp DoTick_BGMSkip
DoTick_BGMSkip:
@@ -195,57 +205,30 @@ DoTick_PSGSkip:
jp IdleLoop ; End of subroutine
;****************************************************************************
-; BankSwitch
-; Switches into a new bank (won't update player status!)
-;
-; input A .... New bank to switch into
-; input HL ... Must be $6000
-; breaks ..... AF
-;****************************************************************************
-
-BankSwitch: macro
- ld (hl), a
- rrca
- ld (hl), a
- rrca
- ld (hl), a
- rrca
- ld (hl), a
- rrca
- ld (hl), a
- rrca
- ld (hl), a
- rrca
- ld (hl), a
- ld (hl), h
- rrca
- ld (hl), a
- endm
-
-;****************************************************************************
; LoadList [command $01]
; Loads the pointer list
;****************************************************************************
LoadList:
- ld hl, RAM_ComBank ; Get command parameters
- ld c, (hl)
- inc l
- ld e, (hl)
- inc l
- ld d, (hl)
- ex de, hl
-
- xor a ; Command parsed
- ld (RAM_Command), a
+; 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
ld de, RAM_PointerList ; Where the pointer list starts
-.loop:
+.loadloop:
call GetParam ; Get high byte address
ld a, b ; Is it the end of the list?
or a
- jp z, .end
+ jp z, .loadend
ld (de), a ; Store high byte address
inc d
@@ -261,10 +244,10 @@ LoadList:
dec d ; Go for next byte
dec d
inc e
- jp .loop
+ jp .loadloop
-.end:
- jp IdleLoop ; End of subroutine
+.loadend:
+ jp EndOfCommand ; End of subroutine
;****************************************************************************
; GetParam
diff --git a/src-z80/core/sfx.z80 b/src-z80/core/sfx.z80
index 4bca4c7..8c5e7dd 100644
--- a/src-z80/core/sfx.z80
+++ b/src-z80/core/sfx.z80
@@ -25,9 +25,6 @@ PlaySFX:
PollPCM
- xor a ; Command parsed
- ld (RAM_Command), a
-
ld hl, RAM_SFXData ; Set SFX as playing
ld (hl), $01
inc l ; No delays!
@@ -45,7 +42,7 @@ PlaySFX:
ld (DoTick_SFX+1), hl
PollPCM
- jp IdleLoop ; End of subroutine
+ jp EndOfCommand ; End of subroutine
;****************************************************************************
; ProcessSFX
@@ -153,6 +150,14 @@ ProcessSFXRun:
jp c, SetFMParamSFX
cp $FA ; Events $F8-$F9: set FM register
jp c, SetFMRegSFX
+ jp z, SetFlagsSFX ; Events $FA-$FB: set/clear flags
+ cp $FB
+ jp z, ClearFlagsSFX
+
+ cp $FC
+ jp z, LoopSFX ; Event $FC: loop SFX
+ cp $FD
+ jp z, SetLoopSFX ; Event $FD: set loop point
;****************************************************************************
; StopSFX* [command $03, event $FF]
@@ -166,10 +171,8 @@ StopSFXEvent:
jp DoTick_SFXSkip ; End of subroutine
StopSFXCmd:
- xor a ; Command parsed
- ld (RAM_Command), a
call StopSFX ; We're just a wrapper
- jp IdleLoop ; End of subroutine
+ jp EndOfCommand ; End of subroutine
StopSFX:
PollPCM
@@ -283,9 +286,36 @@ ClearSFX:
.fmfree:
dec e ; Go for next FM channel to unlock
- dec b
- jp nz, .unlockfm
+ djnz .unlockfm
;----------------------------------------------------------------------------
ret ; End of subroutine
+
+;****************************************************************************
+; LoopSFX [event $FC]
+; Makes a SFX loop
+;****************************************************************************
+
+LoopSFX:
+ PollPCM
+
+ ld hl, (RAM_SFXLoopPoint+1) ; Get looping address
+ ld a, (RAM_SFXLoopPoint)
+ ld c, a
+
+ jp ProcessSFXRun ; End of subroutine
+
+;****************************************************************************
+; SetLoopSFX [event $FD]
+; Sets the SFX loop point
+;****************************************************************************
+
+SetLoopSFX:
+ PollPCM
+
+ ld a, c ; Store loop point address
+ ld (RAM_SFXLoopPoint), a
+ ld (RAM_SFXLoopPoint+1), hl
+
+ jp ProcessSFXRun ; End of subroutine
diff --git a/src-z80/core/vars.z80 b/src-z80/core/vars.z80
index cd7162d..79e4a1d 100644
--- a/src-z80/core/vars.z80
+++ b/src-z80/core/vars.z80
@@ -42,13 +42,23 @@ RAM_SFXPlaying: ds 1 ; Set if a SFX is playing
RAM_SFXDelay: ds 1 ; How many ticks to wait
RAM_SFXBank: ds 1 ; Current SFX bank
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_PCMBank1: db 1 ; (not implemented yet)
+RAM_PCMAddr1: dw 1 ; (not implemented yet)
+RAM_PCMBank2: db 1 ; (not implemented yet)
+RAM_PCMAddr2: dw 1 ; (not implemented yet)
RAM_Scratch: ds 32 ; Scratch bytes, may be useful when
; buffering to speed up to avoid bank
; switching conflicts
ds $F0-($&$FF), $FF
-RAM_PCMBuffer: ds 16 ; PCM buffer
+RAM_PCMBuffer: ds 0 ; PCM buffer
+RAM_PCMBuffer1: ds 8 ; (not implemented yet)
+RAM_PCMBuffer2: ds 8 ; (not implemented yet)
;****************************************************************************
; Pointer list starts being stored from here
@@ -71,6 +81,12 @@ RAM_Stack: equ $1FE0 ; Where stack starts
RAM_GlobalVol: equ $1FE0 ; Global volume for all channels
RAM_Status: equ $1FF0 ; Current playback status
RAM_RefreshVol: equ $1FF1 ; Set to refresh all volumes
+RAM_Flags: equ $1FF2 ; Track flags
+
RAM_Command: equ $1FFF ; Command type
RAM_ComAddr: equ $1FFD ; Command address parameter
RAM_ComBank: equ $1FFC ; Command bank parameter
+
+RAM_Command2: equ $1FFB ; (second slot for all the above)
+RAM_ComAddr2: equ $1FF9
+RAM_ComBank2: equ $1FF8
diff --git a/src-z80/player/fm.z80 b/src-z80/player/fm.z80
index 505e849..d5d49ba 100644
--- a/src-z80/player/fm.z80
+++ b/src-z80/player/fm.z80
@@ -432,7 +432,13 @@ LoadFMDirect:
;****************************************************************************
SetFMVolSFX:
- call SetFMVolSFXEvent ; We're just a wrapper
+ push af
+ PollPCM
+ call GetParam ; Get new volume
+ PollPCM
+ pop af
+
+ call SetFMVolLoad ; We're just a wrapper
jp ProcessSFXRun ; End of subroutine
SetFMVolBGM:
@@ -487,12 +493,21 @@ SetFMVolBGM:
call SetFMVolLoad ; We're just a wrapper
jp ProcessBGMRun ; End of subroutine
-SetFMVolSFXEvent:
- push af
- PollPCM
- call GetParam ; Get new volume
- PollPCM
- pop af
+;----------------------------------------------------------------------------
+; input a = channel ID
+; input b = new volume level
+;----------------------------------------------------------------------------
+
+SetFMVolTempLoad:
+ push bc
+ push de
+ push hl
+ jp SetFMVolDoIt
+
+;----------------------------------------------------------------------------
+; input a = channel ID (bottom 3 bits)
+; input b = new volume level
+;----------------------------------------------------------------------------
SetFMVolLoad:
push bc
@@ -508,6 +523,7 @@ SetFMVolLoad:
ld (hl), b
pop af
+SetFMVolDoIt:
push af
ld h, RAM_FMData>>8 ; Get address of FM data
add RAM_FMData&$FF
diff --git a/src-z80/player/misc.z80 b/src-z80/player/misc.z80
index dee980e..56e11b4 100644
--- a/src-z80/player/misc.z80
+++ b/src-z80/player/misc.z80
@@ -1,6 +1,8 @@
;****************************************************************************
; SetDelay* [event $FE, events $D0-$DF]
; Adds a delay in playback
+;----------------------------------------------------------------------------
+; breaks: c, de, hl
;****************************************************************************
SetDelaySFX:
@@ -46,6 +48,58 @@ SetDelayShort:
ret ; End of subroutine
;****************************************************************************
+; SetFlags [event $FA]
+; Sets some of the flags.
+;----------------------------------------------------------------------------
+; breaks: c, de, hl
+;****************************************************************************
+
+SetFlagsSFX:
+ call SetFlags
+ jp ProcessSFXRun
+
+SetFlagsBGM:
+ call SetFlags
+ jp ProcessBGMRun
+
+SetFlags:
+ PollPCM ; Get which flags to set
+ call GetParam
+ PollPCM
+
+ ld a, (RAM_Flags) ; Set the flags
+ or b
+ ld (RAM_Flags), a
+
+ ret ; End of subroutine
+
+;****************************************************************************
+; ClearFlags [event $FB]
+; Clears some of the flags.
+;----------------------------------------------------------------------------
+; breaks: c, de, hl
+;****************************************************************************
+
+ClearFlagsSFX:
+ call ClearFlags
+ jp ProcessSFXRun
+
+ClearFlagsBGM:
+ call ClearFlags
+ jp ProcessBGMRun
+
+ClearFlags:
+ PollPCM ; Get which flags to clear
+ call GetParam
+ PollPCM
+
+ ld a, (RAM_Flags) ; Clear the flags
+ and b
+ ld (RAM_Flags), a
+
+ ret ; End of subroutine
+
+;****************************************************************************
; RefreshVolume
; Reloads the volume for all channels.
;----------------------------------------------------------------------------
@@ -69,6 +123,7 @@ RefreshVolume:
inc l
inc e
dec c
+ PollPCM
jr nz, .fixfmvol
ld hl, $1FE8 ; Update PSG volume
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/pcm.z80 b/src-z80/player/pcm.z80
index 99feb6d..2b7bcc4 100644
--- a/src-z80/player/pcm.z80
+++ b/src-z80/player/pcm.z80
@@ -1,100 +1,21 @@
;****************************************************************************
-; 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:
-
- ;ld b, $01 ; Play PCM!
- exx ; Back to standard registers
- xor a ; 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
-
-;****************************************************************************
; UpdatePCM
; Updates PCM output upon a timer event
;****************************************************************************
UpdatePCM:
- ret ; RET = no PCM playback
- ; NOP = PCM playback
+ 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
+ ;push hl
+ ;ld hl, $1F27
+ ;ld ($4000), hl
+ ;pop hl
ld a, (hl) ; Fetch next sample
inc a ; Check if it's the end of the waveform
@@ -110,7 +31,9 @@ UpdatePCM:
ret ; End of subroutine
.stop:
- ld b, $00 ; Stop playback
+; ld b, $00 ; Stop playback
+ ld a, $C9 ; Stop playback
+ ld (UpdatePCM), a
ld (ix+0), $2A ; Turn off DAC
ld (ix+1), $80
ld (ix+0), $2B
@@ -210,6 +133,88 @@ UpdatePCM:
; 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
;****************************************************************************
@@ -257,21 +262,21 @@ LockChannelPCM:
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
+ ld b, a ; Set high bits of timer
+ ld hl, $4000
+ ld (hl), $24
rrca
rrca
or $C0
- ld (ix+1), a
+ inc l
+ ld (hl), a
ld a, b ; Set low bits of timer
- ld (ix+0), $25
+ dec l
+ ld (hl), $25
and $03
- ld (ix+1), a
+ inc l
+ ld (hl), a
- jp IdleLoop ; End of subroutine
+ jp EndOfCommand ; End of subroutine
diff --git a/src-z80/player/psg.z80 b/src-z80/player/psg.z80
index b88978c..6ddaae7 100644
--- a/src-z80/player/psg.z80
+++ b/src-z80/player/psg.z80
@@ -10,8 +10,10 @@ UpdatePSG:
push bc
ld a, (hl) ; Get channel volume
- bit 7, a
- jr nz, .noskip
+; bit 7, a
+; jr nz, .noskip
+ or a
+ jp m, .noskip
ld b, $0F
inc l
jp .skip