aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier Degirolmo2012-07-09 09:40:47 -0300
committerJavier Degirolmo2012-07-09 09:40:47 -0300
commit5316d8125babafb0200f84e4c3a3796b4f1374c0 (patch)
tree4330b2bb5dfd8cd1655da4fe8d020a98b0e80373
parent7acb3981cda42444d44c531377116620ad6fe441 (diff)
Workaround for linker issue, completely ditches the old way of doing instrument lists though. Will update the README in the next commit (working on that now)
-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 *);