diff options
| author | Javier Degirolmo | 2012-08-27 07:58:24 -0300 |
|---|---|---|
| committer | Javier Degirolmo | 2012-08-27 07:58:24 -0300 |
| commit | 6266e3e5577bc7c11d300a873c150b6a7900376a (patch) | |
| tree | 82b14ee437f6f802cd5cd896dd66c58c29ea7ec0 /doc | |
| parent | 2f83b4822b5825d58ab4a74e4e9e5f0be2cc78f2 (diff) | |
Fuck it, we're doing it live
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/api-asm.68k | 104 | ||||
| -rw-r--r-- | doc/api-c.txt | 120 | ||||
| -rw-r--r-- | doc/eef.txt | 35 | ||||
| -rw-r--r-- | doc/eif.txt | 27 | ||||
| -rw-r--r-- | doc/esf.txt | 355 | ||||
| -rw-r--r-- | doc/ewf.txt | 15 |
6 files changed, 656 insertions, 0 deletions
diff --git a/doc/api-asm.68k b/doc/api-asm.68k new file mode 100644 index 0000000..e6f466c --- /dev/null +++ b/doc/api-asm.68k @@ -0,0 +1,104 @@ +============================================================================= + +*** How to use *** + +You need to take "src-68k/echo.68k" and include it in your program. Then you +need to take "built/prog-z80.bin" (or if you built Echo from source, the +generated binary). Finally, go to the echo.68k file, look for @Z80Program +(should be near the end of the file) and change the filename to point where +the prog-z80.bin file is. + +Echo should now be inside your program. Now call Echo_Init (see below) to +initialize Echo and load the instrument list, and then you can proceed to use +Echo as needed (e.g. call Echo_PlayBGM to start playing music). + +Unless stated otherwise, calling the API subroutines will *not* modify the +68000 registers. + +============================================================================= + +*** Initialization *** + +Echo_Init + + 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 + the program is just starting). + + The address of the instrument list is given in register a0. The instrument + list can be built using the Echo_List* macros. An example of a short + instrument list is as follows: + + Echo_ListEntry instrument1 + Echo_ListEntry instrument2 + Echo_ListEntry instrument3 + Echo_ListEnd + + Where the parameter for Echo_ListEntry is the address (e.g. a label) to + the EIF/EEF/EWF data of the instrument. + +============================================================================= + +*** Background music *** + +Echo_PlayBGM + + 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). + +Echo_ResumeBGM + + Resumes playback of whatever background music was playing last time before + Echo_StopBGM was called. Used when you want to unpause music. + +============================================================================= + +*** Sound effects *** + +Echo_PlaySFX + + Starts playback of the specified sound effect. The register a0 points to + the ESF data for the sound effect. + +Echo_StopSFX + + Stops playback of sound effects. + +============================================================================= + +*** Control *** + +Echo_GetStatus + + Gets the current status of Echo. The status is returned as a word in d0, + with the following bits set as relevant: + + Bit 0 .... Sound effect is playing + Bit 1 .... Background music is playing + Bit 15 ... Echo is busy (can't take commands) + + The API will automatically wait if you try to send a command while Echo is + busy, so the only reason to check for that is if you don't want to halt + the 68000 until Echo is ready to take more commands. + +============================================================================= + +*** Raw access *** + +Echo_SendCommand + + Sends an argument-less command to Echo. The command ID is given as a byte + in register d0. + +Echo_SendCommandEx + + 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. + +============================================================================= diff --git a/doc/api-c.txt b/doc/api-c.txt new file mode 100644 index 0000000..fcfd07b --- /dev/null +++ b/doc/api-c.txt @@ -0,0 +1,120 @@ +============================================================================= + +*** How to use *** + +Add "echo.c" and "echoblob.h" in your program files. Then include the header +"echo.h" in whatever source files you need to access the Echo API, i.e. + + #include "echo.h" + +(these files are present in the "c" directory) + +Then use echo_init to initialize Echo and load the instrument list (see +below). After that you can use Echo as needed (e.g. call echo_play_bgm to +start playing music, etc.). + +The file "echoblob.h" is the Z80 binary turned into a C array. If you want to +change the blob, just use the included blob2c tool. It's invoked as follows: + + blob2c «input.bin» «output.h» + +============================================================================= + +*** Initialization *** + +void echo_init(const void **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 + the program is just starting). + + The parameter 'list' is a pointer to an array of pointers, where each + entry points to the EIF/EEF/EWF data of each instrument. The list ends + with a NULL pointer. For example: + + const void* const list[] = { + instrument1, + instrument2, + instrument3, + NULL + }; + + (if NULL isn't defined for whatever reason just use 0 instead) + +============================================================================= + +*** Background music *** + +void echo_play_bgm(const void *esf) + + Starts playback of the specified background music. The parameter 'esf' + points to the ESF data for the background music. + +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). + +void echo_resume_bgm() + + Resumes playback of whatever background music was playing last time before + echo_stop_bgm was called. Used when you want to unpause music. + +============================================================================= + +*** Sound effects *** + +void echo_play_sfx(const void *esf) + + Starts playback of the specified sound effect. The parameter 'esf' points + to the ESF data for the sound effect. + +void echo_stop_sfx() + + Stops playback of sound effects. + +============================================================================= + +*** Control *** + +uint16_t echo_get_status() + + Gets the current status of Echo. Returns an OR of the following flags, + as relevant: + + ECHO_STAT_BGM .... Background music is playing + ECHO_STAT_SFX .... Sound effect is playing + ECHO_STAT_BUSY ... Echo is busy (can't take commands) + + The API will automatically wait if you try to send a command while Echo is + busy, so the only reason to check for that is if you don't want to halt + the 68000 until Echo is ready to take more commands. + +============================================================================= + +*** Raw access *** + +void echo_send_command(uint8_t command) + + Sends an argument-less command to Echo. The parameter 'command' is the + command to send, and may be one of the following: + + ECHO_CMD_STOPBGM ..... Stop background music playback + ECHO_CMD_RESUMEBGM ... Resume background music playback + ECHO_CMD_STOPSFX ..... Stop sound effect playback + +void echo_send_command_ex(uint8_t command, const void *address) + + Sends a command to Echo that takes an address as its argument. The + parameter 'command' is the command to send, while the parameter 'address' + is the address to use as argument. The command may be one of these: + + ECHO_CMD_PLAYBGM .... Start background music playback + ECHO_CMD_PLAYSFX .... Start sound effect playback + ECHO_CMD_LOADLIST ... Load instrument list (warning: see below) + + Do *NOT* use ECHO_CMD_LOADLIST unless you *REALLY* know you're doing, this + makes Echo load the instrument list by itself and it expects a different + format from the one used by the C API. + +============================================================================= diff --git a/doc/eef.txt b/doc/eef.txt new file mode 100644 index 0000000..c3ab92e --- /dev/null +++ b/doc/eef.txt @@ -0,0 +1,35 @@ +============================================================================= + +OVERVIEW + + EEF stands for "Echo Envelope Format" and it's the format in which PSG + instruments are stored. + +FORMAT + + EEF instruments consist of a list of volume levels. Each byte represents + a different volume level, and the value ranges from $00 (loudest) to $0F + (quietest). Each byte represents one tick (i.e. 1/60th of a second). + + Looping is possible. The start of the loop is marked by a byte with value + $FE, while the end of the loop is marked by a byte with value $FF. There + must be at least one volume byte between them or Echo will hang. + + To make a non-looping PSG instrument, just put the last volume value + inside the loop. + +============================================================================= + +NOTES + + Yes, this format was kind of an afterthought. Later I may improve it to + provide at least some kind of RLE-like compression, but for now you'll + have to stick with this :P + + Also, since PSG instruments are required to use PSG channels and I know + many of you don't want to mess with them at all, here's a flat PSG + instrument (i.e. no envelope): + + $FE,$00,$FF + +============================================================================= diff --git a/doc/eif.txt b/doc/eif.txt new file mode 100644 index 0000000..3d1f27d --- /dev/null +++ b/doc/eif.txt @@ -0,0 +1,27 @@ +============================================================================= + +OVERVIEW + + EIF stands for "Echo Instrument Format" and it's the format in which FM + instruments are stored. + +FORMAT + + EIF instruments are essentially raw dumps of the YM2612 registers. They + consist of 29 bytes, where each byte belongs to a different YM2612 + register. The registers are stored in the following order (assuming the + first FM channel): + + $B4 -- Algorithm and feedback + $30, $34, $38, $3C -- Multiplier and detune + $40, $44, $48, $4C -- Total level + $50, $54, $58, $5C -- Attack rate + $60, $64, $68, $6C -- Decay rate + $70, $74, $78, $7C -- Sustain rate + $80, $84, $88, $8C -- Release rate and sustain level + $90, $94, $98, $9C -- SSG-EG + + Some bits are unused and ignored by the YM2612. In an EIF instrument, + they *must* be 0, since Echo will rely on this for optimization purposes. + +============================================================================= diff --git a/doc/esf.txt b/doc/esf.txt new file mode 100644 index 0000000..a7b833e --- /dev/null +++ b/doc/esf.txt @@ -0,0 +1,355 @@ +============================================================================= + +OVERVIEW + + ESF stands for "Echo Stream Format". This is the format in which BGM and + SFX sequences are stored. Essentially this is the music arrangement data. + The format is mostly the same for both BGM and SFX, with just a few + exceptions. + +FORMAT + + ESF is a streamed format (think MIDI without the useless complexity). + It's stored as a sequence of events, where each event takes up between + one and three bytes. An event could be something like "note on", "set + volume", "stop", etc. + +CHANNEL LOCKING + + When both BGM and SFX are being played, it's likely that some channels + may get used by both. In this case, Echo will give the SFX privilege over + those channels. + + This is achieved by channel "locking". When the SFX starts, it first + locks the channels it needs to use. When the SFX ends, those channels get + unlocked. BGM won't play on the locked channels while the SFX is playing. + +============================================================================= + +EVENT LIST + + $00nn ..... Note on FM channel #1 + $01nn ..... Note on FM channel #2 + $02nn ..... Note on FM channel #3 + $04nn ..... Note on FM channel #4 + $05nn ..... Note on FM channel #5 + $06nn ..... Note on FM channel #6 + $08nn ..... Note on PSG channel #1 + $09nn ..... Note on PSG channel #2 + $0Ann ..... Note on PSG channel #3 + $0Bnn ..... Note on PSG channel #4 + $0Cnn ..... Note on PCM channel + + $10 ....... Note off FM channel #1 + $11 ....... Note off FM channel #2 + $12 ....... Note off FM channel #3 + $14 ....... Note off FM channel #4 + $15 ....... Note off FM channel #5 + $16 ....... Note off FM channel #6 + $18 ....... Note off PSG channel #1 + $19 ....... Note off PSG channel #2 + $1A ....... Note off PSG channel #3 + $1B ....... Note off PSG channel #4 + $1C ....... Note off PCM channel + + $20nn ..... Set volume FM channel #1 + $21nn ..... Set volume FM channel #2 + $22nn ..... Set volume FM channel #3 + $24nn ..... Set volume FM channel #4 + $25nn ..... Set volume FM channel #5 + $26nn ..... Set volume FM channel #6 + $28nn ..... Set volume PSG channel #1 + $29nn ..... Set volume PSG channel #2 + $2Ann ..... Set volume PSG channel #3 + $2Bnn ..... Set volume PSG channel #4 + + $30nnnn ... Set frequency FM channel #1 + $31nnnn ... Set frequency FM channel #2 + $32nnnn ... Set frequency FM channel #3 + $34nnnn ... Set frequency FM channel #4 + $35nnnn ... Set frequency FM channel #5 + $36nnnn ... Set frequency FM channel #6 + $38nnnn ... Set frequency PSG channel #1 + $39nnnn ... Set frequency PSG channel #2 + $3Annnn ... Set frequency PSG channel #3 + $3Bnn ..... Set noise type PSG channel #4 + + $40nn ..... Set instrument FM channel #1 + $41nn ..... Set instrument FM channel #2 + $42nn ..... Set instrument FM channel #3 + $44nn ..... Set instrument FM channel #4 + $45nn ..... Set instrument FM channel #5 + $46nn ..... Set instrument FM channel #6 + $48nn ..... Set instrument PSG channel #1 + $49nn ..... Set instrument PSG channel #2 + $4Ann ..... Set instrument PSG channel #3 + $4Bnn ..... Set instrument PSG channel #4 + + $E0 ....... [SFX] Lock FM channel #1 + $E1 ....... [SFX] Lock FM channel #2 + $E2 ....... [SFX] Lock FM channel #3 + $E4 ....... [SFX] Lock FM channel #4 + $E5 ....... [SFX] Lock FM channel #5 + $E6 ....... [SFX] Lock FM channel #6 + $E8 ....... [SFX] Lock PSG channel #1 + $E9 ....... [SFX] Lock PSG channel #2 + $EA ....... [SFX] Lock PSG channel #3 + $EB ....... [SFX] Lock PSG channel #4 + + $F0nn ..... Set parameters FM channel #1 + $F1nn ..... Set parameters FM channel #2 + $F2nn ..... Set parameters FM channel #3 + $F4nn ..... Set parameters FM channel #4 + $F5nn ..... Set parameters FM channel #5 + $F6nn ..... Set parameters FM channel #6 + + $FC ....... [BGM] Go to loop + $FD ....... [BGM] Set loop point + $FEnn ..... Delay ticks + $FF ....... Stop playback + +============================================================================= + +$00nn: Note on FM channel #1 +$01nn: Note on FM channel #2 +$02nn: Note on FM channel #3 +$04nn: Note on FM channel #4 +$05nn: Note on FM channel #5 +$06nn: Note on FM channel #6 + + These events do a "note on" at the specified FM channel. The event is + followed by a byte, which indicates which note to play. The value is as + follows, where "octave" ranges from 0 to 7 and "semitone" ranges from 0 + to 11: + + 32 * octave + 2 * semitone + 1 + +$08nn: Note on PSG channel #1 +$09nn: Note on PSG channel #2 +$0Ann: Note on PSG channel #3 + + These events do a "note on" at the specified square wave PSG channel. + The event is followed by a byte, which indicates which note to play. The + value is as follows, where "octave" ranges from 0 to 5 and "semitone" + ranges from 0 to 11: + + 24 * octave + 2 * semitone + +$0Bnn: Note on PSG channel #4 + + This event does a "note on" at the noise PSG channel. The event is + followed by a byte, which indicates what kind of noise to play. The + following values are valid: + + $00 ... Periodic noise, high pitch + $01 ... Periodic noise, medium pitch + $02 ... Periodic noise, low pitch + $03 ... Periodic noise, PSG3 frequency + $04 ... White noise, high pitch + $05 ... White noise, medium pitch + $06 ... White noise, low pitch + $07 ... White noise, PSG3 frequency + + When using values $03 and $07, the third square wave PSG channel controls + the noise frequency. You can change this frequency using the events to + change the frequency of that channel (usually you'd use event type $3A). + +$0Cnn: Note on PCM channel + + This event does a "note on" at the PCM channel. More specifically, it + starts playback of a PCM sample. This event is followed by a byte, that + specifies an index in the pointer list indicating where's the sample + data. Samples are stored as EWF (Echo Waveform Format). + + NOTE: FM channel #6 will be disabled. That channel will be re-enabled + when PCM playback is over (either because the waveform is over or because + the channel is stopped explicitly). + +============================================================================= + +$10: Note off FM channel #1 +$11: Note off FM channel #2 +$12: Note off FM channel #3 +$14: Note off FM channel #4 +$15: Note off FM channel #5 +$16: Note off FM channel #6 +$18: Note off PSG channel #1 +$19: Note off PSG channel #2 +$1A: Note off PSG channel #3 +$1B: Note off PSG channel #4 + + These events do a "note off" at the specified channel. + +$1C: Note off PCM channel + + This event does a "note off" at the PCM channel. This means that any PCM + playback is immediately stopped. FM channel #6 is immediately enabled as + well. + +============================================================================= + +$20nn: Set volume FM channel #1 +$21nn: Set volume FM channel #2 +$22nn: Set volume FM channel #3 +$24nn: Set volume FM channel #4 +$25nn: Set volume FM channel #5 +$26nn: Set volume FM channel #6 + + These events set the volume of a specific FM channel. The event is + followed by a byte, which indicates the new volume. A value of $00 is the + loudest, a value of $7F is the quietest. + +$28nn: Set volume PSG channel #1 +$29nn: Set volume PSG channel #2 +$2Ann: Set volume PSG channel #3 +$2Bnn: Set volume PSG channel #4 + + These events set the volume of a specific PSG channel. The event is + followed by a byte, which indicates the new volume. A value of $00 is the + loudest, a value of $0F is the quietest. + +============================================================================= + +$30nnnn: Set frequency FM channel #1 +$31nnnn: Set frequency FM channel #2 +$32nnnn: Set frequency FM channel #3 +$34nnnn: Set frequency FM channel #4 +$35nnnn: Set frequency FM channel #5 +$36nnnn: Set frequency FM channel #6 + + These events set the raw frequency of a specific FM channel, without + triggering a new note. Meant for note slides. The following two bytes + specify the new frequency in the same format as the YM2612 expects. The + first byte is register +$A4, the second byte is register +$A0. + + Echo uses the following frequency values for each semitone: + + C - 644 | E - 810 | G# - 1021 + C# - 681 | F - 858 | A - 1081 + D - 722 | F# - 910 | A# - 1146 + D# - 765 | G - 964 | B - 1214 + +$38nnnn: Set frequency PSG channel #1 +$39nnnn: Set frequency PSG channel #2 +$3Annnn: Set frequency PSG channel #3 + + These events set the raw frequency of a specific square wave PSG channel, + without triggering a new note. Meant for note slides. The following two + bytes specify the new frequency, the first byte containing the four least + significant bits (LSB aligned), and the next byte containing the six most + significant bits (LSB aligned too). + + Echo uses the following frequency values for each semitone: + + |Oct.0|Oct.1|Oct.2|Oct.3|Oct.4|Oct.5 + ---|-----|-----|-----|-----|-----|----- + C | 851 | 425 | 212 | 106 | 53 | 26 + C# | 803 | 401 | 200 | 100 | 50 | 25 + D | 758 | 379 | 189 | 94 | 47 | 23 + D# | 715 | 357 | 178 | 89 | 44 | 22 + E | 675 | 337 | 168 | 84 | 42 | 21 + F | 637 | 318 | 159 | 79 | 39 | 19 + F# | 601 | 300 | 150 | 75 | 37 | 18 + G | 568 | 284 | 142 | 71 | 35 | 17 + G# | 536 | 268 | 134 | 67 | 33 | 16 + A | 506 | 253 | 126 | 63 | 31 | 15 + A# | 477 | 238 | 119 | 59 | 29 | 14 + B | 450 | 225 | 112 | 56 | 28 | 14 + +$3Bnn: Set noise type PSG channel #4 + + This event works like event $0Bnn, but it doesn't trigger a note attack + (i.e. instrument envelope won't be reset, note won't start playing if it + wasn't already). + +============================================================================= + +$40nn: Set instrument FM channel #1 +$41nn: Set instrument FM channel #2 +$42nn: Set instrument FM channel #3 +$44nn: Set instrument FM channel #4 +$45nn: Set instrument FM channel #5 +$46nn: Set instrument FM channel #6 + + These events are used to set the instrument to be used by a specific FM + channel. The event is followed by a byte, which has an index in the + pointer list that indicates where's the FM instrument data. Instruments + are stored as EIF (Echo Instrument Format). + +$48nn: Set instrument PSG channel #1 +$49nn: Set instrument PSG channel #2 +$4Ann: Set instrument PSG channel #3 +$4Bnn: Set instrument PSG channel #4 + + These events are used to set the instrument to be used by a specific PSG + channel. The event is followed by a byte, which has an index in the + pointer list that indicates where's the PSG instrument data. Instruments + are stored as EEF (Echo Envelope Format). + +============================================================================= + +$E0: Lock FM channel #1 [SFX ONLY] +$E1: Lock FM channel #2 [SFX ONLY] +$E2: Lock FM channel #3 [SFX ONLY] +$E4: Lock FM channel #4 [SFX ONLY] +$E5: Lock FM channel #5 [SFX ONLY] +$E6: Lock FM channel #6 [SFX ONLY] +$E8: Lock PSG channel #1 [SFX ONLY] +$E9: Lock PSG channel #1 [SFX ONLY] +$EA: Lock PSG channel #1 [SFX ONLY] +$EB: Lock PSG channel #1 [SFX ONLY] + + These events are used to "lock" specific channels. When a channel is + locked, BGM can't mess up with it. All channels used by a SFX must be + locked before they're used. Channels get unlocked when the SFX stream is + over. + + To lock the PCM channel, you need to lock FM channel #6 (event $E6). Echo + will behave accordingly. + +============================================================================= + +$F0: Set parameters FM channel #1 +$F1: Set parameters FM channel #2 +$F2: Set parameters FM channel #3 +$F4: Set parameters FM channel #4 +$F5: Set parameters FM channel #5 +$F6: Set parameters FM channel #6 + + These events set up some miscellaneous parameters for the FM channels. + The event is followed by a byte, which speficies the new parameters to be + used. The format of this byte is as follows: + + Bit 7 ..... 1 to enable left speaker, 0 to mute it + Bit 6 ..... 1 to enable right speaker, 0 to mute it + Bit 5-0 ... Must be 0 + +============================================================================= + +$FC: Go to loop [BGM ONLY] +$FD: Set loop point [BGM ONLY] + + This event are used in BGM 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. + +$FEnn: Delay ticks + + This event is used for timing. It tells Echo to wait a specific amount of + ticks before continuing with the stream. A byte follows this event, it's + the amount of ticks to wait. If it's $00, then Echo waits 256 ticks + instead. + + If you need to wait more than 256 ticks, you can trigger this event + several times in a row. For example, to wait 320 ticks, use this event + twice: $FE00FE40 --> 256 ticks + 64 ticks = 320 ticks. + + One tick lasts 1/60th of a second. + +$FF: Stop playback + + This event indicates the end of the stream and tells Echo to stop + playback from this stream. If the stream was a SFX, then any locked + channels will be unlocked as well. + +============================================================================= diff --git a/doc/ewf.txt b/doc/ewf.txt new file mode 100644 index 0000000..e83dbbe --- /dev/null +++ b/doc/ewf.txt @@ -0,0 +1,15 @@ +============================================================================= + +OVERVIEW + + EWF stands for "Echo Waveform Format" and it's the format in which PCM + instruments are stored. + +FORMAT + + There isn't much to it. PCM data is stored as unsigned 8-bit, 10250 Hz, + mono. The bytes specifying the waveform data contain values ranging from + $00 to $FE. When a byte with value $FF is found, this is the end of the + waveform. + +============================================================================= |
