aboutsummaryrefslogtreecommitdiff
path: root/c
diff options
context:
space:
mode:
Diffstat (limited to 'c')
-rw-r--r--c/LICENSE17
-rw-r--r--c/README97
-rw-r--r--c/echo.c183
-rw-r--r--c/echo.h42
-rw-r--r--c/echoblob.h290
-rw-r--r--c/tool/blob2c.c77
6 files changed, 706 insertions, 0 deletions
diff --git a/c/LICENSE b/c/LICENSE
new file mode 100644
index 0000000..05d9fdb
--- /dev/null
+++ b/c/LICENSE
@@ -0,0 +1,17 @@
+© 2010-2012 Javier Degirolmo
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
diff --git a/c/README b/c/README
new file mode 100644
index 0000000..5413ec0
--- /dev/null
+++ b/c/README
@@ -0,0 +1,97 @@
+Quick readme that's going to be here until proper documentation is made.
+
+Echo is licensed under the zlib license. Feel free to use it as long as you
+don't claim you made Echo (no credit needed though). If you modify it don't
+claim it's vanilla Echo either :P
+
+THIS CODE HAS NOT BEEN TESTED YET. I CURRENTLY DON'T HAVE ANY C DEVKIT TO
+VERIFY IT WORKS FINE. I HAVE DONE AS MANY CHECKS AS POSSIBLE (AND IT
+DEFINITELY SHOULD BUILD) BUT I NEED REPORTS TO KNOW IF IT'S WORKING AS
+EXPECTED. SORRY FOR THE INCONVENIENCE.
+
+=============================================================================
+
+To include Echo in your program, you need to include echo.c, echo.h and
+echoblob.h in it (and yes, you can put echo.h as a system file if you want).
+That's pretty much it.
+
+To access the Echo stuff, include echo.h in the source files that need to
+make use of it. It contains all the function definitions and such, as well as
+the macros needed to make the instrument list.
+
+echoblob.h is already included here, but if you want to use a different Z80
+blob from the included one, you can use the blob2c tool. It's a command line
+tool and its usage is pretty simple: blob2c «input.bin» «output.c»
+
+=============================================================================
+
+Echo makes use of an instrument list. There are some macros in echo.h to help
+you make the lists in your C program. Basically, do something like this:
+
+ ECHO_LIST_START(list)
+ ECHO_LIST_ENTRY(instrument1)
+ ECHO_LIST_ENTRY(instrument2)
+ ECHO_LIST_ENTRY(instrument3)
+ ECHO_LIST_ENTRY(instrument4)
+ ECHO_LIST_ENTRY(instrument5)
+ ECHO_LIST_END
+
+Where 'list' is the name the list will have (this creates a standard C
+array). This is the same name you have to pass to echo_init().
+
+Each ECHO_LIST_ENTRY is an instrument, and you pass a pointer to their blob
+data (EIF, EEF, EWF) as the parameter. Put as many ECHO_LIST_ENTRY as
+instruments you want in the list.
+
+Make sure to NOT put semicolons or you'll get weird compiler errors.
+
+=============================================================================
+
+Quick overview of the functions. The functions map 1:1 to their asm
+counterparts, by the way.
+
+ echo_init(list)
+
+ Initializes Echo. 'list' is a pointer to the instrument list (pass here
+ the name you passed to ECHO_LIST_START). Make sure to call this before
+ doing anything else with Echo.
+
+ echo_play_bgm(stream)
+
+ Plays background music. 'stream' is a pointer to the ESF data.
+
+ echo_stop_bgm()
+
+ Stops background music playback.
+
+ echo_play_sfx(stream)
+
+ Plays a sound effect. 'stream' is a pointer to the ESF data.
+
+ echo_stop_sfx()
+
+ Stops sound effect playback.
+
+ echo_get_status()
+
+ Gets the current status of Echo. It returns a value which is an OR of
+ the following flags (as appropriate):
+
+ ECHO_STAT_BGM .... Background music is playing
+ ECHO_STAT_SFX .... Sound effect is playing
+ ECHO_STAT_BUSY ... Echo is busy (can't parse commands yet)
+
+ And just to make it clear: if you send a command to Echo while it's
+ busy, it won't fail, it'll just make the 68000 wait until Echo is
+ ready. No need to explicitly check for it. Check this only if you want
+ to prevent the 68000 waiting.
+
+ echo_send_command(command)
+
+ Lets you send a raw command to Echo. Use this for commands not taking
+ parameters.
+
+ echo_send_command_ex(command, address)
+
+ Lets you send a raw command to Echo. Use this for commands that take an
+ address as a parameter.
diff --git a/c/echo.c b/c/echo.c
new file mode 100644
index 0000000..246c6b6
--- /dev/null
+++ b/c/echo.c
@@ -0,0 +1,183 @@
+// Required headers
+#include <stdint.h>
+#include "echoblob.h"
+#include "echo.h"
+
+// Z80 addresses
+static volatile uint8_t* const z80_ram = (uint8_t *) 0xA00000;
+static volatile uint16_t* const z80_busreq = (uint16_t *) 0xA11100;
+static volatile uint16_t* const z80_reset = (uint16_t *) 0xA11200;
+
+// Macros to control the Z80
+#define Z80_REQUEST() \
+ { *z80_busreq = 0x100; while (*z80_busreq & 0x100); }
+#define Z80_RELEASE() \
+ { *z80_busreq = 0; }
+#define Z80_RESET() \
+ { *z80_reset = 0; \
+ int16_t i; for (i = 8; i >= 0; i--); \
+ *z80_reset = 0x100; }
+
+//***************************************************************************
+// echo_init
+// Initializes Echo and gets it running.
+//---------------------------------------------------------------------------
+// param list: pointer to instrument list
+//***************************************************************************
+
+void echo_init(const void *list) {
+ // Take over the Z80
+ Z80_RESET();
+ Z80_REQUEST();
+
+ // Tell Echo to load the pointer list as soon as it starts
+ uint32_t param = (uint32_t) list;
+ z80_ram[0x1FFF] = ECHO_CMD_LOADLIST;
+ z80_ram[0x1FFD] = param;
+ param >>= 8;
+ z80_ram[0x1FFE] = param | 0x80;
+ param >>= 8;
+ param = (param & 0x7F) | (param >> 1 & 0x80);
+ z80_ram[0x1FFC] = param;
+
+ // Copy the Echo blob into Z80 RAM
+ // No, memcpy() won't do here since we must ensure accesses are byte-sized
+ // (memcpy() may not know this and try word or long accesses)
+ const uint8_t *src = echo_blob;
+ volatile uint8_t *dest = z80_ram;
+ int16_t count = sizeof(echo_blob)-1;
+ while (count >= 0)
+ *dest++ = *src++;
+
+ // Let Echo start running!
+ Z80_RESET();
+ Z80_RELEASE();
+}
+
+//***************************************************************************
+// echo_send_command
+// Sends a raw command to Echo. No parameters are taken.
+//---------------------------------------------------------------------------
+// param cmd: command to send
+//***************************************************************************
+
+void echo_send_command(unsigned char cmd) {
+ // We need access to Z80 bus
+ Z80_REQUEST();
+
+ // Is Echo busy yet?
+ while (z80_ram[0x1FFF] != 0x00) {
+ Z80_RELEASE();
+ int16_t i;
+ for (i = 0x3FF; i >= 0; i--);
+ Z80_REQUEST();
+ }
+
+ // Write the command
+ z80_ram[0x1FFF] = cmd;
+
+ // Done with the Z80
+ Z80_RELEASE();
+}
+
+//***************************************************************************
+// echo_send_command_ex
+// Sends a raw command to Echo. An address parameter is taken.
+//---------------------------------------------------------------------------
+// param cmd: command to send
+// param addr: address parameter
+//***************************************************************************
+
+void echo_send_command_ex(unsigned char cmd, const void *addr) {
+ // Since we need to split the address into multiple bytes we put it in an
+ // integer. This is a bad practice in general, period, but since we don't
+ // care about portability here we can afford to do it this time.
+ uint32_t param = (uint32_t) addr;
+
+ // We need access to Z80 bus
+ Z80_REQUEST();
+
+ // Is Echo busy yet?
+ while (z80_ram[0x1FFF] != 0x00) {
+ Z80_RELEASE();
+ int16_t i;
+ for (i = 0x3FF; i >= 0; i--);
+ Z80_REQUEST();
+ }
+
+ // Write the command
+ z80_ram[0x1FFF] = cmd;
+ z80_ram[0x1FFD] = param;
+ param >>= 8;
+ z80_ram[0x1FFE] = param | 0x80;
+ param >>= 8;
+ param = (param & 0x7F) | (param >> 1 & 0x80);
+ z80_ram[0x1FFC] = param;
+
+ // Done with the Z80
+ Z80_RELEASE();
+}
+
+//***************************************************************************
+// echo_play_bgm
+// Starts playing background music.
+//---------------------------------------------------------------------------
+// param ptr: pointer to BGM stream
+//***************************************************************************
+
+void echo_play_bgm(const void *ptr) {
+ echo_send_command_ex(ECHO_CMD_PLAYBGM, ptr);
+}
+
+//***************************************************************************
+// echo_stop_bgm
+// Stops background music playback.
+//***************************************************************************
+
+void echo_stop_bgm(void) {
+ echo_send_command(ECHO_CMD_STOPBGM);
+}
+
+//***************************************************************************
+// echo_play_sfx
+// Starts playing a sound effect.
+//---------------------------------------------------------------------------
+// param ptr: pointer to SFX stream
+//***************************************************************************
+
+void echo_play_sfx(const void *ptr) {
+ echo_send_command_ex(ECHO_CMD_PLAYSFX, ptr);
+}
+
+//***************************************************************************
+// echo_stop_sfx
+// Stops sound effect playback.
+//***************************************************************************
+
+void echo_stop_sfx(void) {
+ echo_send_command(ECHO_CMD_STOPSFX);
+}
+
+//***************************************************************************
+// echo_get_status
+// Retrieves Echo's current status.
+//---------------------------------------------------------------------------
+// return: status flags (see ECHO_STAT_*)
+//***************************************************************************
+
+unsigned short echo_get_status(void) {
+ // We need access to the Z80
+ Z80_REQUEST();
+
+ // Retrieve status from Z80 RAM
+ uint16_t status = 0;
+ status = z80_ram[0x1FF0];
+ if (z80_ram[0x1FFF] != 0)
+ status |= ECHO_STAT_BUSY;
+
+ // Done with the Z80
+ Z80_RELEASE();
+
+ // Return status
+ return status;
+}
diff --git a/c/echo.h b/c/echo.h
new file mode 100644
index 0000000..526e24e
--- /dev/null
+++ b/c/echo.h
@@ -0,0 +1,42 @@
+#ifndef ECHO_H
+#define ECHO_H
+
+/*
+ * Macros used to define instrument lists
+ * Yeah, this thing is a mess
+ */
+#define ECHO_LIST_START(name) \
+ static const unsigned char name[] = {
+#define ECHO_LIST_ENTRY(addr) \
+ ((unsigned long)(addr) >> 8 & 0x7F) | 0x80, \
+ (unsigned long)(addr) & 0xFF, \
+ ((unsigned long)(addr) >> 15 & 0x7F) | \
+ ((unsigned long)(addr) >> 16 & 0x80)),
+#define ECHO_LIST_END \
+ 0x00 };
+
+/* Echo commands */
+enum {
+ ECHO_CMD_NONE, /* 0x00 - No command */
+ ECHO_CMD_LOADLIST, /* 0x01 - Load instrument list */
+ ECHO_CMD_PLAYSFX, /* 0x02 - Play a SFX */
+ ECHO_CMD_STOPSFX, /* 0x03 - Stop SFX playback */
+ ECHO_CMD_PLAYBGM, /* 0x04 - Play a BGM */
+ ECHO_CMD_STOPBGM /* 0x05 - Stop BGM playback */
+};
+
+/* Echo status flags */
+#define ECHO_STAT_BGM 0x0001 /* Background music is playing */
+#define ECHO_STAT_SFX 0x0002 /* Sound effect is playing */
+#define ECHO_STAT_BUSY 0x8000 /* Echo still didn't parse command */
+
+/* Function prototypes */
+void echo_play_bgm(const void *);
+void echo_stop_bgm(void);
+void echo_play_sfx(const void *);
+void echo_stop_sfx(void);
+unsigned short echo_get_status(void);
+void echo_send_command(unsigned char);
+void echo_send_command_ex(unsigned char, const void *);
+
+#endif
diff --git a/c/echoblob.h b/c/echoblob.h
new file mode 100644
index 0000000..36a0283
--- /dev/null
+++ b/c/echoblob.h
@@ -0,0 +1,290 @@
+static uint8_t echo_blob[] = {
+ 49,240, 31,175, 50,240, 31, 33, 17,127, 54,159, 54,191, 54,223,
+ 54,255,175, 50, 0, 17, 50, 16, 17, 50, 32, 17, 50, 48, 17, 33,
+ 0, 96,117,117,117,117,117,117,117,117,117,221, 33, 0, 64,253,
+ 38, 64,217, 1, 0, 0, 17, 0, 0, 33, 0, 96,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,238, 0, 61,202, 66, 1, 61,202,211, 4,
+ 61,202,248, 5, 61,202,193, 2, 61,202, 5, 4, 58, 0, 64, 15,
+ 220, 61, 2,175, 50,255, 31, 58, 0, 64, 15,220, 61, 2, 58,255,
+ 31,183, 32,212, 58, 0, 64, 15,220, 61, 2, 58, 0, 64,203, 79,
+ 32, 8,203, 71,196, 61, 2,195,238, 0,221,126, 0,203, 71,196,
+ 61, 2,221, 54, 0, 39,221, 54, 1, 47, 58, 0, 64, 15,220, 61,
+ 2,195, 36, 1, 58, 0, 64, 15,220, 61, 2,195, 46, 1, 58, 0,
+ 64, 15,220, 61, 2,195,195, 11, 58, 0, 64, 15,220, 61, 2,195,
+ 238, 0, 33,252, 31, 78, 44, 94, 44, 86,235,175, 50,255, 31,121,
+ 17, 0, 96,235,119, 15,119, 15,119, 15,119, 15,119, 15,119, 15,
+ 119,117, 15,119,235, 17, 0, 28,126,183,202,206, 1, 18, 20, 44,
+ 32, 25, 36, 32, 22, 12,121, 38, 96,119, 15,119, 15,119, 15,119,
+ 15,119, 15,119, 15,119,117, 15,119, 38,128,126, 18, 20, 44, 32,
+ 25, 36, 32, 22, 12,121, 38, 96,119, 15,119, 15,119, 15,119, 15,
+ 119, 15,119, 15,119,117, 15,119, 38,128,126, 18, 21, 21, 28, 44,
+ 32, 25, 36, 32, 22, 12,121, 38, 96,119, 15,119, 15,119, 15,119,
+ 15,119, 15,119, 15,119,117, 15,119, 38,128,195,104, 1,121, 50,
+ 140, 17,195,238, 0, 58,140, 17,185,202,242, 1,121, 50,140, 17,
+ 217,119, 15,119, 15,119, 15,119, 15,119, 15,119, 15,119,117, 15,
+ 119,217, 70, 44,194,254, 1, 36,194,254, 1, 38,128, 12,201,205,
+ 25, 2,195, 76, 5, 58, 0, 64, 15,220, 61, 2, 58,134, 17,183,
+ 194,234, 3,205, 25, 2,195, 51, 3,205,213, 1,120,217, 6, 1,
+ 38, 28,111, 86, 36, 94, 36, 78, 33, 0, 96,217,221, 54, 0, 43,
+ 221, 54, 1,128,221, 54, 0, 42,221, 54, 1,128,201,221, 54, 0,
+ 39,221, 54, 1, 31,217,120,183, 40, 47, 58,140, 17,185,202,101,
+ 2,121, 50,140, 17,119, 15,119, 15,119, 15,119, 15,119, 15,119,
+ 15,119,117, 15,119, 26, 60, 40, 18,221, 54, 0, 42,221,119, 1,
+ 28, 32, 6, 20, 32, 3, 22,128, 12,217,201, 6, 0,221, 54, 0,
+ 42,221, 54, 1,128,221, 54, 0, 43,221, 54, 1, 0,217,201,205,
+ 169, 2,195, 76, 5, 58, 0, 64, 15,220, 61, 2, 58,134, 17,183,
+ 194, 51, 3,205,169, 2,195, 51, 3,217, 6, 0,217,221, 54, 0,
+ 43,221, 54, 1, 0,201, 62, 1, 50,134, 17,205,169, 2,195, 76,
+ 5, 58, 0, 64, 15,220, 61, 2,205, 51, 4, 58, 0, 64, 15,220,
+ 61, 2, 58,240, 31,246, 2, 50,240, 31, 58, 0, 64, 15,220, 61,
+ 2, 33,252, 31, 78, 44, 94, 44, 86, 58, 0, 64, 15,220, 61, 2,
+ 175, 50,255, 31, 33,141, 17, 54, 1, 44, 54, 1, 44,113, 44,115,
+ 44,114, 58, 0, 64, 15,220, 61, 2, 33, 18, 3, 34, 44, 1,195,
+ 238, 0, 58, 0, 64, 15,220, 61, 2, 33,142, 17,126, 61,202, 37,
+ 3,119,195, 46, 1, 58, 0, 64, 15,220, 61, 2, 44, 78, 44, 94,
+ 44, 86,235, 58, 0, 64, 15,220, 61, 2,205,213, 1, 58, 0, 64,
+ 15,220, 61, 2,120,254, 8,218,240, 6,254, 11,218,127, 12,202,
+ 3, 13,254, 12,202, 5, 2, 58, 0, 64, 15,220, 61, 2,120,254,
+ 24,218,145, 7,254, 28,218, 95, 13,202,149, 2, 58, 0, 64, 15,
+ 220, 61, 2,120,254,254,202,101, 15,254,255,202,255, 3,254,252,
+ 202,169, 4,254,253,202,190, 4, 58, 0, 64, 15,220, 61, 2,120,
+ 254, 40,218,120, 9,254, 44,218,188, 13, 58, 0, 64, 15,220, 61,
+ 2,120,254, 56,218,191, 7,254, 59,218,208, 14,202, 42, 15, 58,
+ 0, 64, 15,220, 61, 2,120,254, 72,218, 62, 8,254, 76,218, 83,
+ 14, 58, 0, 64, 15,220, 61, 2,120,254,248,218,203, 10, 58, 0,
+ 64, 15,220, 61, 2,195,255, 3, 58, 0, 64, 15,220, 61, 2, 44,
+ 194,234, 3, 36,194,234, 3, 38,128, 12, 58, 0, 64, 15,220, 61,
+ 2, 44,194,252, 3, 36,194,252, 3, 38,128, 12,195, 51, 3,205,
+ 15, 4,195, 46, 1,175, 50,255, 31,205, 15, 4,195,238, 0, 58,
+ 240, 31,230,253, 50,240, 31, 58, 0, 64, 15,220, 61, 2,205, 51,
+ 4, 58, 0, 64, 15,220, 61, 2,175, 50,141, 17, 33, 46, 1, 34,
+ 44, 1,201, 58,134, 17,183,204,169, 2, 6, 4, 17, 63, 17, 33,
+ 139, 17, 58, 0, 64, 15,220, 61, 2, 54, 0,123,214, 15, 95,126,
+ 183, 32, 2,175, 18, 58, 0, 64, 15,220, 61, 2, 29, 45, 16,226,
+ 6, 8, 17, 79, 17, 58, 0, 64, 15,220, 61, 2, 62,127, 18, 29,
+ 58, 0, 64, 15,220, 61, 2,126,183,194,154, 4, 5,120,205, 82,
+ 11, 58, 0, 64, 15,220, 61, 2,120,230, 4,253,111,120,230, 3,
+ 198,180,253,119, 0,253, 54, 1,192, 4, 45, 16,200, 33, 80, 17,
+ 62,192, 6, 8,119, 44, 16,252,201, 58, 0, 64, 15,220, 61, 2,
+ 235, 44, 78, 44, 94, 44, 86, 45, 45, 45,235,195, 51, 3, 58, 0,
+ 64, 15,220, 61, 2,235, 44,113, 44,115, 44,114, 45, 45, 45,235,
+ 195, 51, 3, 58, 0, 64, 15,220, 61, 2,205, 52, 6, 58, 0, 64,
+ 15,220, 61, 2, 58,240, 31,246, 1, 50,240, 31, 58, 0, 64, 15,
+ 220, 61, 2, 33,252, 31, 78, 44, 94, 44, 86, 58, 0, 64, 15,220,
+ 61, 2,175, 50,255, 31, 33,149, 17, 54, 1, 44, 54, 1, 44,113,
+ 44,115, 44,114, 58, 0, 64, 15,220, 61, 2, 33, 43, 5, 34, 34,
+ 1, 58, 0, 64, 15,220, 61, 2,195,238, 0, 58, 0, 64, 15,220,
+ 61, 2, 33,150, 17,126, 61,202, 62, 5,119,195, 36, 1, 58, 0,
+ 64, 15,220, 61, 2, 44, 78, 44, 94, 44, 86,235, 58, 0, 64, 15,
+ 220, 61, 2,205,213, 1, 58, 0, 64, 15,220, 61, 2,120,254, 8,
+ 218,234, 6,254, 11,218,121, 12,202,253, 12,254, 12,202,255, 1,
+ 58, 0, 64, 15,220, 61, 2,120,254, 24,218,139, 7,254, 28,218,
+ 89, 13,202,143, 2, 58, 0, 64, 15,220, 61, 2,120,254,254,202,
+ 95, 15,254,255,202,242, 5, 58, 0, 64, 15,220, 61, 2,120,254,
+ 40,218,114, 9,254, 44,218,150, 13, 58, 0, 64, 15,220, 61, 2,
+ 120,254, 56,218,185, 7,254, 59,218,202, 14,202, 36, 15, 58, 0,
+ 64, 15,220, 61, 2,120,254, 72,218, 56, 8,254, 76,218, 13, 14,
+ 58, 0, 64, 15,220, 61, 2,120,254,232,218, 32, 11,254,236,218,
+ 55, 15,202,182, 2, 58, 0, 64, 15,220, 61, 2,120,254,248,218,
+ 156, 10,205, 2, 6,195, 36, 1,175, 50,255, 31,205, 2, 6,195,
+ 238, 0, 58, 0, 64, 15,220, 61, 2, 58,240, 31,230,254, 50,240,
+ 31, 58, 0, 64, 15,220, 61, 2,175, 50,149, 17, 33, 36, 1, 34,
+ 34, 1, 58, 0, 64, 15,220, 61, 2,205, 52, 6, 58, 0, 64, 15,
+ 220, 61, 2,201, 58,134, 17,183,196,169, 2, 6, 4, 17,139, 17,
+ 58, 0, 64, 15,220, 61, 2, 26,183, 40, 64,175, 18, 58, 0, 64,
+ 15,220, 61, 2,120, 15, 15, 15, 15, 61, 38, 17,111, 78,214, 15,
+ 111,113, 58, 0, 64, 15,220, 61, 2,213,125,198, 8,111,198, 4,
+ 95, 84, 58, 0, 64, 15,220, 61, 2, 26,119, 44, 28, 26,119, 44,
+ 28, 26,119,209, 58, 0, 64, 15,220, 61, 2, 29, 16,178, 6, 8,
+ 58, 0, 64, 15,220, 61, 2, 26,183,202,221, 6,175, 18, 58, 0,
+ 64, 15,220, 61, 2, 5,120, 38, 17,198, 64,111,197,120, 70,205,
+ 181, 8,193, 58, 0, 64, 15,220, 61, 2,197,125,198, 8,111,120,
+ 70,205,232, 9,193,125,198, 8,111,120,230, 3,198,180,253,119,
+ 0,126,253,119, 1, 58, 0, 64, 15,220, 61, 2, 4, 58, 0, 64,
+ 15,220, 61, 2, 29, 5,194,144, 6,201,205, 14, 7,195, 76, 5,
+ 71, 58, 0, 64, 15,220, 61, 2,229,120,230, 7, 33,128, 17,133,
+ 111,126,225,183,194,234, 3,120,205, 14, 7,195, 51, 3,230, 7,
+ 221, 54, 0, 40,221,119, 1, 71, 8, 58, 0, 64, 15,220, 61, 2,
+ 120,230, 4, 15,253,111, 58, 0, 64, 15,220, 61, 2,205,213, 1,
+ 58, 0, 64, 15,220, 61, 2, 8,213,229, 87,230, 3,198,164, 95,
+ 58, 0, 64, 15,220, 61, 2, 38, 16,120,230, 31,198,144,111, 58,
+ 0, 64, 15,220, 61, 2,120,230,224, 15, 15, 71,126,176,253,115,
+ 0,253,119, 1, 58, 0, 64, 15,220, 61, 2,123,214, 4, 95, 45,
+ 126,253,115, 0,253,119, 1, 58, 0, 64, 15,220, 61, 2,122,246,
+ 240,221, 54, 0, 40,221,119, 1,225,209,201,205,175, 7,195, 76,
+ 5, 71, 58, 0, 64, 15,220, 61, 2,120,229,230, 7, 33,128, 17,
+ 133,111,126,225,183,194, 51, 3,120,205,175, 7,195, 51, 3,230,
+ 7,221, 54, 0, 40,221,119, 1,201,205,221, 7,195, 76, 5, 71,
+ 58, 0, 64, 15,220, 61, 2,120,229,230, 7, 33,128, 17,133,111,
+ 126,225,183,194,216, 3,120,205,221, 7,195, 51, 3,245, 71, 58,
+ 0, 64, 15,220, 61, 2,120,230, 4, 15,253,111, 58, 0, 64, 15,
+ 220, 61, 2,205,213, 1, 58, 0, 64, 15,220, 61, 2,241,213,230,
+ 7, 87,230, 3,198,164, 95, 58, 0, 64, 15,220, 61, 2,253,115,
+ 0,253,112, 1, 58, 0, 64, 15,220, 61, 2,205,213, 1, 58, 0,
+ 64, 15,220, 61, 2,123,214, 4, 95,253,115, 0,253,112, 1, 58,
+ 0, 64, 15,220, 61, 2,209,201,205,160, 8,195, 76, 5,230, 7,
+ 71, 58, 0, 64, 15,220, 61, 2,213,197,120, 17, 64, 17,131, 95,
+ 58, 0, 64, 15,220, 61, 2,205,213, 1, 58, 0, 64, 15,220, 61,
+ 2,120, 18,123,198, 8, 95,175, 18, 89,193, 75,209, 58, 0, 64,
+ 15,220, 61, 2,229,120, 38, 17,198,128,111,126,225,183,194, 51,
+ 3, 58, 0, 64, 15,220, 61, 2,120,229, 33, 64, 17,133,111, 70,
+ 225, 8, 58, 0, 64, 15,220, 61, 2, 8,205,181, 8,195, 51, 3,
+ 230, 7, 8, 58, 0, 64, 15,220, 61, 2,205,213, 1, 58, 0, 64,
+ 15,220, 61, 2, 8,245,230, 4, 15,253,111, 58, 0, 64, 15,220,
+ 61, 2,241,197,213,229, 38, 28,104, 86, 36, 94, 36, 78,235,245,
+ 58, 0, 64, 15,220, 61, 2, 6, 7, 17,154, 17,120, 8,205,213,
+ 1,235,112,235, 28,205,213, 1,235,112,235, 28,205,213, 1,235,
+ 112,235, 28,205,213, 1,235,112,235, 28, 8, 71, 16,222,205,213,
+ 1,235,112,235, 58, 0, 64, 15,220, 61, 2,241, 71,205, 82, 11,
+ 120, 17, 88, 17,230, 7,131, 95,245,230, 3,198,176, 33,154, 17,
+ 8, 58, 0, 64, 15,220, 61, 2, 8,253,119, 0, 70, 44,253,112,
+ 1, 8,120, 18,123,198, 8, 95, 58, 0, 64, 15,220, 61, 2, 8,
+ 214,128, 6, 28,253,119, 0, 78,253,113, 1,198, 4, 44, 16,244,
+ 58, 0, 64, 15,220, 61, 2,125,214, 24,111, 6, 4,126, 18,123,
+ 198, 8, 95, 44, 16,247, 58, 0, 64, 15,220, 61, 2,241,225,209,
+ 193,201,205,213, 9,195, 76, 5,230, 7, 71, 58, 0, 64, 15,220,
+ 61, 2,213,197,120, 22, 17,198, 72, 95, 58, 0, 64, 15,220, 61,
+ 2,205,213, 1, 58, 0, 64, 15,220, 61, 2,235,112,235, 89,193,
+ 75,209, 58, 0, 64, 15,220, 61, 2,229,120, 33,128, 17,133,111,
+ 126,225,183,194, 51, 3, 58, 0, 64, 15,220, 61, 2,120,229, 33,
+ 72, 17,133,111, 70,225,245, 58, 0, 64, 15,220, 61, 2,241,205,
+ 232, 9,195, 51, 3,245, 58, 0, 64, 15,220, 61, 2,205,213, 1,
+ 58, 0, 64, 15,220, 61, 2,241,197,213,229,230, 7,245, 38, 17,
+ 198, 88,111, 8, 58, 0, 64, 15,220, 61, 2, 8,230, 4, 15,253,
+ 111, 58, 0, 64, 15,220, 61, 2,241,230, 3,198, 64, 79,126,230,
+ 7, 95, 58, 0, 64, 15,220, 61, 2,125,198, 8,111,123,254, 7,
+ 56, 14,253,113, 0,126,128,254,127, 56, 2, 62,127,253,119, 1,
+ 121,198, 4, 79, 58, 0, 64, 15,220, 61, 2,125,198, 8,111,123,
+ 254, 5, 56, 14,253,113, 0,126,128,254,127, 56, 2, 62,127,253,
+ 119, 1,121,198, 4, 79, 58, 0, 64, 15,220, 61, 2,125,198, 8,
+ 111,123,254, 4, 56, 14,253,113, 0,126,128,254,127, 56, 2, 62,
+ 127,253,119, 1,121,198, 4, 79, 58, 0, 64, 15,220, 61, 2,125,
+ 198, 8,111,253,113, 0,126,128,254,127, 56, 2, 62,127,253,119,
+ 1, 58, 0, 64, 15,220, 61, 2,225,209,193,201, 71, 58, 0, 64,
+ 15,220, 61, 2,120,230, 4, 15,253,111,120, 8, 58, 0, 64, 15,
+ 220, 61, 2,205,213, 1, 58, 0, 64, 15,220, 61, 2, 8,230, 3,
+ 198,180,253,119, 0,253,112, 1,195, 76, 5, 71, 58, 0, 64, 15,
+ 220, 61, 2,120,120,230, 4, 15,253,111, 8, 58, 0, 64, 15,220,
+ 61, 2,205,213, 1, 58, 0, 64, 15,220, 61, 2, 8,229,230, 7,
+ 38, 17,198, 80,108,112, 8, 58, 0, 64, 15,220, 61, 2, 8,230,
+ 7,198,128,111, 8,126,183,225,194, 51, 3, 58, 0, 64, 15,220,
+ 61, 2, 8,230, 3,198,180,253,119, 0,253,112, 1,195, 51, 3,
+ 230, 7, 71, 58, 0, 64, 15,220, 61, 2,229, 38, 17,120,198,128,
+ 111, 54, 1,225, 58, 0, 64, 15,220, 61, 2,120,230, 4, 15,253,
+ 111,120,230, 3,135,135,198,180,253,119, 0,253, 54, 1,192,195,
+ 76, 5,230, 7,245,213,229, 79,230, 4, 15,253,111,121,230, 3,
+ 198, 64, 14, 6, 33,168, 16, 8, 58, 0, 64, 15,220, 61, 2, 8,
+ 94,253,119, 0,198, 4,253,115, 1, 0,253,119, 0,198, 4,253,
+ 115, 1, 0,253,119, 0,198, 4,253,115, 1, 0,253,119, 0,198,
+ 4,253,115, 1, 44, 13,194,103, 11,225,209, 58, 0, 64, 15,220,
+ 61, 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,
+ 61, 2,201, 33, 48, 17, 6, 3,197,126,203,127, 32, 6, 6, 15,
+ 44,195, 40, 12,230,127, 71, 44,126,128, 71, 58, 0, 64, 15,220,
+ 61, 2,197, 44, 78, 44, 94, 44, 86,235, 58, 0, 64, 15,220, 61,
+ 2,205,213, 1, 58, 0, 64, 15,220, 61, 2,120,254,254,202, 79,
+ 12,254,255,202,100, 12,253,104, 58, 0, 64, 15,220, 61, 2,235,
+ 114, 45,115, 45,113, 45,193, 58, 0, 64, 15,220, 61, 2,253,125,
+ 128, 71,254, 16, 56, 2, 6, 15, 58, 0, 64, 15,220, 61, 2,120,
+ 7, 7, 7,193,176, 15, 15, 15,246,144, 50, 17,127,125,214, 17,
+ 111, 58, 0, 64, 15,220, 61, 2, 5,242,200, 11,195, 56, 1, 58,
+ 0, 64, 15,220, 61, 2, 28,235,113, 44,115, 44,114,235, 29, 29,
+ 29,195,234, 11, 58, 0, 64, 15,220, 61, 2, 28,235, 78, 44, 94,
+ 44, 86,235, 29, 29, 29,195,234, 11,205,157, 12,195, 76, 5, 71,
+ 58, 0, 64, 15,220, 61, 2,120,229,230, 3, 33,136, 17,133,111,
+ 126,225,183,194,234, 3,120,205,157, 12,195, 51, 3,230, 3, 71,
+ 8, 58, 0, 64, 15,220, 61, 2,229, 38, 17,120, 15, 15, 15, 15,
+ 111,126,246,128,119, 58, 0, 64, 15,220, 61, 2,213, 44, 44, 84,
+ 125,198, 6, 95, 58, 0, 64, 15,220, 61, 2, 26,119, 44, 28, 26,
+ 119, 44, 28, 26,119,209,225, 58, 0, 64, 15,220, 61, 2,205,213,
+ 1, 58, 0, 64, 15,220, 61, 2, 8,229,213, 38, 16,104, 17, 17,
+ 127, 15, 15, 15, 70,176, 18, 44,126, 18,209,225,201,205, 16, 13,
+ 195, 76, 5, 58,139, 17,183,194,234, 3,205, 16, 13,195, 51, 3,
+ 58, 0, 64, 15,220, 61, 2,229, 33, 48, 17,126,246,128,119, 58,
+ 0, 64, 15,220, 61, 2,213, 44, 44, 84,125,198, 6, 95, 58, 0,
+ 64, 15,220, 61, 2, 26,119, 44, 28, 26,119, 44, 28, 26,119,209,
+ 225, 58, 0, 64, 15,220, 61, 2,205,213, 1, 58, 0, 64, 15,220,
+ 61, 2, 62,224,176, 50, 17,127,201,205,125, 13,195, 76, 5, 71,
+ 58, 0, 64, 15,220, 61, 2,120,229,230, 3, 33,136, 17,133,111,
+ 126,225,183,194, 51, 3,120,205,125, 13,195, 51, 3,230, 3, 71,
+ 58, 0, 64, 15,220, 61, 2,229, 38, 17,120, 15, 15, 15, 15,111,
+ 126,230,127,119,225,201,230, 3, 8, 58, 0, 64, 15,220, 61, 2,
+ 205,213, 1, 58, 0, 64, 15,220, 61, 2, 8,229, 38, 17, 15, 15,
+ 15, 15,111,126,230,128,176,119,225,195, 76, 5,230, 3, 8, 58,
+ 0, 64, 15,220, 61, 2,205,213, 1, 58, 0, 64, 15,220, 61, 2,
+ 8,213,229,245, 17,136, 17,131, 95, 26, 95, 58, 0, 64, 15,220,
+ 61, 2,241, 38, 17, 15, 15, 15, 15,198, 15,111,112, 58, 0, 64,
+ 15,220, 61, 2,123,183, 32, 16,125,214, 15,111,126,230,128,176,
+ 119, 58, 0, 64, 15,220, 61, 2,225,209,195, 51, 3,230, 3, 8,
+ 58, 0, 64, 15,220, 61, 2,205,213, 1, 58, 0, 64, 15,220, 61,
+ 2, 8,213,229, 22, 28, 88, 38, 17, 15, 15, 15, 15,198, 10,111,
+ 58, 0, 64, 15,220, 61, 2, 26,119, 20, 45, 26,119, 20, 45, 26,
+ 119, 58, 0, 64, 15,220, 61, 2,125,214, 8,111, 54, 0,225,209,
+ 195, 76, 5,230, 3, 8, 58, 0, 64, 15,220, 61, 2,205,213, 1,
+ 58, 0, 64, 15,220, 61, 2, 8,213,229, 22, 28, 88, 33,136, 17,
+ 245,133,111,241, 70, 38, 17, 15, 15, 15, 15,198, 15,111, 58, 0,
+ 64, 15,220, 61, 2,119, 45, 26,119, 20, 45, 26,119, 20, 45, 26,
+ 119, 58, 0, 64, 15,220, 61, 2,120,183,202,162, 14,225,209,195,
+ 51, 3, 58, 0, 64, 15,220, 61, 2, 84,125,214, 4, 95,126, 18,
+ 44, 28,126, 18, 44, 28,126, 18, 58, 0, 64, 15,220, 61, 2,125,
+ 214, 8,111, 54, 0,225,209,195, 51, 3,205,238, 14,195, 76, 5,
+ 71, 58, 0, 64, 15,220, 61, 2,120,229,230, 15, 38, 17,198,128,
+ 111,126,225,183,194,216, 3,120,205,238, 14,195, 51, 3,230, 3,
+ 8, 58, 0, 64, 15,220, 61, 2,205,213, 1, 58, 0, 64, 15,220,
+ 61, 2, 8,213, 17, 17,127, 15, 15, 15,176,246,128, 18, 58, 0,
+ 64, 15,220, 61, 2,205,213, 1, 58, 0, 64, 15,220, 61, 2,235,
+ 112,235,209,201,205, 65, 13,195, 76, 5, 58,139, 17,183,194,234,
+ 3,205, 65, 13,195, 51, 3,230, 3, 71, 58, 0, 64, 15,220, 61,
+ 2,229, 38, 17,120,198,136,111, 54, 1, 58, 0, 64, 15,220, 61,
+ 2,120, 15, 15, 15, 15,111, 38, 17, 54, 0,225,195, 76, 5,205,
+ 107, 15,195, 36, 1,205,107, 15,195, 46, 1, 58, 0, 64, 15,220,
+ 61, 2,205,213, 1, 58, 0, 64, 15,220, 61, 2,235,114, 45,115,
+ 45,113, 58, 0, 64, 15,220, 61, 2, 45,112,201,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 131, 53,131, 50,134, 47,139, 44,131, 42,141, 39,137, 37,136, 35,
+ 136, 33,138, 31,141, 29,130, 28,137, 26,129, 25,139, 23,133, 22,
+ 129, 21,142, 19,140, 18,140, 17,140, 16,141, 15,142, 14,129, 14,
+ 132, 13,136, 12,141, 11,130, 11,136, 10,143, 9,134, 9,142, 8,
+ 134, 8,142, 7,135, 7,128, 7,138, 6,132, 6,142, 5,137, 5,
+ 132, 5,143, 4,139, 4,135, 4,131, 4,143, 3,139, 3,136, 3,
+ 133, 3,130, 3,143, 2,140, 2,138, 2,135, 2,133, 2,131, 2,
+ 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,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,255,255,255,255,255,255,255,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,
+ 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, 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, 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,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
diff --git a/c/tool/blob2c.c b/c/tool/blob2c.c
new file mode 100644
index 0000000..d76aaae
--- /dev/null
+++ b/c/tool/blob2c.c
@@ -0,0 +1,77 @@
+// Required headers
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+// Where the Z80 blob is stored
+#define MAX_SIZE 0x2000
+uint8_t blob[MAX_SIZE];
+size_t blob_size;
+
+//***************************************************************************
+// Program entry point
+//***************************************************************************
+
+int main(int argc, char **argv) {
+ // Check number of arguments
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s <input> <output>\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ // Open input file
+ FILE *file = fopen(argv[1], "rb");
+ if (file == NULL) {
+ fputs("Error: couldn't open input file\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ // Read the blob into memory and get its filesize
+ // Use ferror() to check for failure since most likely we will be
+ // attempting to read more data than is actually in the blob
+ blob_size = fread(blob, 1, MAX_SIZE, file);
+ if (ferror(file) && !feof(file)) {
+ fputs("Error: couldn't read input file\n", stderr);
+ fclose(file);
+ return EXIT_FAILURE;
+ }
+
+ // Done with input file
+ fclose(file);
+
+ // Open output file
+ file = fopen(argv[2], "w");
+ if (file == NULL) {
+ fputs("Error: couldn't open output file\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ // Start the table
+ fputs("static uint8_t echo_blob[] = {", file);
+
+ // Output the blob data as a C array
+ // Pretty formatting too!
+ unsigned i;
+ for (i = 0; i < blob_size; i++) {
+ fprintf(file, "%s%3u%s",
+ i % 0x10 == 0 ? "\n " : "", blob[i],
+ i == blob_size-1 ? "" : ",");
+ }
+
+ // End the table
+ fputs("\n};\n", file);
+
+ // Check if there was an error (to output an error message)
+ if (ferror(file)) {
+ fputs("Error: couldn't write output file\n", stderr);
+ fclose(file);
+ return EXIT_FAILURE;
+ }
+
+ // Done with output file
+ fclose(file);
+
+ // Done
+ return EXIT_SUCCESS;
+}