aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--c/echo.c38
-rw-r--r--c/echo.h16
2 files changed, 28 insertions, 26 deletions
diff --git a/c/echo.c b/c/echo.c
index 3b081cb..0c4fc33 100644
--- a/c/echo.c
+++ b/c/echo.c
@@ -25,26 +25,42 @@ static volatile uint16_t* const z80_reset = (uint16_t *) 0xA11200;
// param list: pointer to instrument list
//***************************************************************************
-void echo_init(const void *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;
+ // Tell Echo to not run any commands by default (the assembly counterpart
+ // would tell it to load the instrument list, but we can't do that here
+ // due to linker shenanigans)
+ z80_ram[0x1FFF] = 0x00;
+
+ // Load the instrument list manually, since thanks to linker shenanigans
+ // we can't implement the list properly in ROM :/
+ volatile uint8_t *dest = &z80_ram[0x1C00];
+ while (*list) {
+ // Retrieve pointer to next instrument
+ // Cast it to an integer since we need to treat it as such
+ // This should be considered bad C, but since this is hardware-specific
+ // code this should be fine to do (portability is not expected)
+ uint32_t ptr = (uint32_t) *list;
+
+ // Turn the pointer into the base+address notation Echo wants and store
+ // it in Z80 RAM directly (where the list would go)
+ dest[0x000] = (ptr >> 8 & 0x7F) | 0x80;
+ dest[0x100] = (ptr & 0xFF);
+ dest[0x200] = (ptr >> 15 & 0x7F) | (ptr >> 16 & 0x80);
+
+ // Go for next pointer
+ list++;
+ dest++;
+ }
// 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;
+ dest = z80_ram;
int16_t count = sizeof(echo_blob)-1;
while (count-- >= 0)
*dest++ = *src++;
diff --git a/c/echo.h b/c/echo.h
index edeb08b..c571443 100644
--- a/c/echo.h
+++ b/c/echo.h
@@ -1,20 +1,6 @@
#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 */
@@ -31,7 +17,7 @@ enum {
#define ECHO_STAT_BUSY 0x8000 /* Echo still didn't parse command */
/* Function prototypes */
-void echo_init(void);
+void echo_init(const void **);
void echo_play_bgm(const void *);
void echo_stop_bgm(void);
void echo_play_sfx(const void *);