From 9fb3ba347cf3b19c37b6988ac4adc7b9ac1d183f Mon Sep 17 00:00:00 2001 From: Tim Stirrat Date: Wed, 17 Jul 2024 09:59:50 +1000 Subject: [PATCH] WIP big C refactor --- .editorconfig | 20 + .vscode/c_cpp_properties.json | 7 +- .vscode/tasks.json | 9 + Source/Makefile | 75 +- Source/{mGBMidiFunctions.c => io/midi.c} | 23 +- Source/io/midi.h | 24 + Source/io/midi_asm.h | 7 + .../{mGBASMMidiFunctions.s => io/midi_asm.s} | 51 +- Source/{ => io}/serial.c | 9 +- Source/io/serial.h | 7 + Source/{mGBMemoryFunctions.c => io/sram.c} | 37 +- Source/io/sram.h | 12 + Source/io/sram/sram.b0.c | 5 + Source/mGB.c | 220 ++--- Source/mGB.h | 460 +-------- Source/mGBASMFunctions.s | 118 --- Source/mGBASMSynthFunctions.s | 924 ------------------ Source/mGBDisplayFunctions.c | 263 ----- Source/mGBSynthCommonFunctions.c | 172 ---- Source/mGBSynthPitchFunctions.c | 93 -- Source/mGBUserFunctions.c | 170 ---- Source/mgb_save.c | 3 - Source/screen/main.c | 541 ++++++++++ Source/screen/main.h | 60 ++ Source/screen/splash.c | 13 + Source/screen/splash.h | 8 + Source/screen/utils.c | 192 ++++ Source/screen/utils.h | 32 + Source/synth/common.c | 163 +++ Source/synth/common.h | 54 + Source/synth/data.c | 135 +++ Source/synth/data.h | 47 + Source/synth/noi.c | 100 ++ Source/synth/noi.h | 15 + Source/synth/poly.c | 46 + Source/synth/poly.h | 8 + Source/synth/pulse.c | 107 ++ Source/synth/pulse.h | 23 + Source/synth/wav.c | 215 ++++ Source/synth/wav.h | 43 + 40 files changed, 2110 insertions(+), 2401 deletions(-) create mode 100644 .editorconfig rename Source/{mGBMidiFunctions.c => io/midi.c} (73%) create mode 100644 Source/io/midi.h create mode 100644 Source/io/midi_asm.h rename Source/{mGBASMMidiFunctions.s => io/midi_asm.s} (95%) rename Source/{ => io}/serial.c (72%) create mode 100644 Source/io/serial.h rename Source/{mGBMemoryFunctions.c => io/sram.c} (75%) create mode 100644 Source/io/sram.h create mode 100644 Source/io/sram/sram.b0.c delete mode 100644 Source/mGBASMFunctions.s delete mode 100644 Source/mGBASMSynthFunctions.s delete mode 100644 Source/mGBDisplayFunctions.c delete mode 100644 Source/mGBSynthCommonFunctions.c delete mode 100644 Source/mGBSynthPitchFunctions.c delete mode 100644 Source/mGBUserFunctions.c delete mode 100644 Source/mgb_save.c create mode 100644 Source/screen/main.c create mode 100644 Source/screen/main.h create mode 100644 Source/screen/splash.c create mode 100644 Source/screen/splash.h create mode 100644 Source/screen/utils.c create mode 100644 Source/screen/utils.h create mode 100644 Source/synth/common.c create mode 100644 Source/synth/common.h create mode 100644 Source/synth/data.c create mode 100644 Source/synth/data.h create mode 100644 Source/synth/noi.c create mode 100644 Source/synth/noi.h create mode 100644 Source/synth/poly.c create mode 100644 Source/synth/poly.h create mode 100644 Source/synth/pulse.c create mode 100644 Source/synth/pulse.h create mode 100644 Source/synth/wav.c create mode 100644 Source/synth/wav.h diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a922223 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[Makefile] +indent_style = tab +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index becf50c..e2e92c1 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -2,11 +2,12 @@ "configurations": [ { "name": "Mac", - "includePath": ["${workspaceFolder}/**"], + "includePath": ["${workspaceFolder}/gbdk/include"], "defines": ["__TARGET_gb=1", "__PORT_sm83=1"], - "compilerPath": "", + "compilerPath": "${workspaceFolder}/gbdk/bin/lcc", "cStandard": "c11", - "intelliSenseMode": "${default}" + "intelliSenseMode": "${default}", + "browse": { "limitSymbolsToIncludedHeaders": true } } ], "version": 4 diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 901b11d..de8d61f 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -28,6 +28,15 @@ }, "problemMatcher": [] }, + { + "label": "make-clean", + "type": "shell", + "command": "make clean", + "options": { + "cwd": "Source/" + }, + "problemMatcher": [] + }, { "label": "install", "detail": "Installs the rom onto a cartridge using ems-flasher (bank 2)", diff --git a/Source/Makefile b/Source/Makefile index 4792d73..008f5e9 100644 --- a/Source/Makefile +++ b/Source/Makefile @@ -1,16 +1,18 @@ -# If you move this project you can change the directory +# If you move this project you can change the directory # to match your GBDK root directory (ex: GBDK_HOME = "C:/GBDK/" ifndef GBDK_HOME - GBDK_HOME = ../gbdk + GBDK_HOME = ../gbdk endif PROJECTNAME = mGB -LCC = $(GBDK_HOME)/bin/lcc +MAKEFLAGS += --no-builtin-rules + +LCC = $(GBDK_HOME)/bin/lcc LCCFLAGS += -msm83:gb # GB/GBC # LCCFLAGS += -v # verbose -# LCCFLAGS += -autobank +# LCCFLAGS += -autobank ifdef DEBUG LCCFLAGS += -debug -v @@ -44,28 +46,59 @@ endif # LCCFLAGS += -Wm-yS # Convert .noi file named like input file to .sym LCCFLAGS += -Wm-yc # GBC compatible LCCFLAGS += -Wm-yn"$(PROJECTNAME)" # cartridge name -LCCFLAGS += -Wm-yt3 # MBC type = ROM+MBC1+RAM+BATT +LCCFLAGS += -Wm-yt3 # MBC type = ROM+MBC1+RAM+BATT LCCFLAGS += -Wm-ya1 # number of ram banks: -ya 1 +LCCFLAGS += -Wf-MMD + +OBJDIR = obj +OUTDIR = out + + +BIN = $(OUTDIR)/$(PROJECTNAME).gb + +MKDIRS = $(OUTDIR) $(OBJDIR)/io $(OBJDIR)/screen $(OBJDIR)/synth $(OBJDIR)/io/sram + +C_SOURCES = $(wildcard *.c) +C_SOURCES += $(wildcard **/*.c) + +SRAM_BANK0 = $(wildcard io/sram/*.b0.c) + +ASM_SOURCES = $(wildcard **/*.s) + + +OBJS = $(C_SOURCES:%.c=$(OBJDIR)/%.o) +OBJS += $(ASM_SOURCES:%.s=$(OBJDIR)/%.o) +OBJS += $(SRAM_BANK0:%.b0.c=$(OBJDIR)/%.b0.o) + + +# Builds all targets sequentially +all: $(BIN) + +# Dependencies - for better incremental builds +DEPS = $(OBJS:%.o=%.d) +-include $(DEPS) + +# sram banks +$(OBJDIR)/%.b0.o: %.b0.c + $(LCC) $(LCCFLAGS) -Wf-ba0 -c -o $@ $< -OBJ=obj -OUT=out +# Compile .c files to .o object files +$(OBJDIR)/%.o: %.c + $(LCC) $(LCCFLAGS) -c -o $@ $< -build: - mkdir -p $(OBJ) - mkdir -p $(OUT) - - # mostly so you can see the .asm - $(LCC) $(LCCFLAGS) -c -o $(OBJ)/mGB.rel mGB.c +# Compile .s assembly files to .o object files +$(OBJDIR)/%.o: %.s + $(LCC) $(LCCFLAGS) -c -o $@ $< - # SRAM bank 0 - $(LCC) $(LCCFLAGS) -Wf-ba0 -c -o $(OBJ)/mgb_save.rel mgb_save.c - $(LCC) $(LCCFLAGS) -o $(OUT)/$(PROJECTNAME).gb $(OBJ)/mGB.rel $(OBJ)/mgb_save.rel *.s +# Link the compiled object files into a .gb ROM file +$(BIN): makedirs $(OBJS) + $(LCC) $(LCCFLAGS) -o $(BIN) $(OBJS) -compile.bat: Makefile - @echo "REM Automatically generated from Makefile" > compile.bat - @make -sn | sed y/\\//\\\\/ | sed s/mkdir\ \-p/mkdir/ | grep -v make >> compile.bat +.PHONY: makedirs +makedirs: + mkdir -p $(MKDIRS) +.PHONY: clean clean: - rm -rf $(OBJ) - rm -rf $(OUT) \ No newline at end of file + rm -rf $(OBJDIR) $(OUTDIR) diff --git a/Source/mGBMidiFunctions.c b/Source/io/midi.c similarity index 73% rename from Source/mGBMidiFunctions.c rename to Source/io/midi.c index aa81893..87f9b11 100644 --- a/Source/mGBMidiFunctions.c +++ b/Source/io/midi.c @@ -1,15 +1,12 @@ -#include "mGB.h" +#include "midi.h" +#include "../mGB.h" +#include "midi_asm.h" +#include "serial.h" -#define MIDI_STATUS_BIT 0x80 -#define MIDI_STATUS_NOTE_ON 0x09 -#define MIDI_STATUS_NOTE_OFF 0x08 -#define MIDI_STATUS_AT 0x0A -#define MIDI_STATUS_CC 0x0B -#define MIDI_STATUS_PC 0x0C -#define MIDI_STATUS_AT_MONO 0x0D -#define MIDI_STATUS_PB 0x0E - -#define MIDI_STATUS_SYSTEM 0xF0 +uint8_t statusByte; +uint8_t addressByte; +uint8_t valueByte; +uint8_t capturedAddress; void updateMidiBuffer(void) { if (serialBufferReadPosition == serialBufferPosition) { @@ -18,7 +15,7 @@ void updateMidiBuffer(void) { serialBufferReadPosition++; // unsigned overflow from 255 -> 0 is automatic. - UBYTE byte = serialBuffer[serialBufferReadPosition]; + uint8_t byte = serialBuffer[serialBufferReadPosition]; // STATUS BYTE if (byte & MIDI_STATUS_BIT) { @@ -61,4 +58,4 @@ void updateMidiBuffer(void) { asmEventMidiPC(); break; } -} \ No newline at end of file +} diff --git a/Source/io/midi.h b/Source/io/midi.h new file mode 100644 index 0000000..cb809ed --- /dev/null +++ b/Source/io/midi.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#define MIDI_STATUS_BIT 0x80 +#define MIDI_STATUS_NOTE_ON 0x09 +#define MIDI_STATUS_NOTE_OFF 0x08 +#define MIDI_STATUS_AT 0x0A +#define MIDI_STATUS_CC 0x0B +#define MIDI_STATUS_PC 0x0C +#define MIDI_STATUS_AT_MONO 0x0D +#define MIDI_STATUS_PB 0x0E + +#define MIDI_STATUS_SYSTEM 0xF0 + +// MIDI status +extern uint8_t statusByte; +// MIDI address (e.g. note/CC control) +extern uint8_t addressByte; +// MIDI value (e.g. velocity/value) +extern uint8_t valueByte; +extern uint8_t capturedAddress; + +void updateMidiBuffer(void); diff --git a/Source/io/midi_asm.h b/Source/io/midi_asm.h new file mode 100644 index 0000000..6148774 --- /dev/null +++ b/Source/io/midi_asm.h @@ -0,0 +1,7 @@ +#pragma once + +extern void asmEventMidiPB(void); +extern void asmEventMidiCC(void); +extern void asmEventMidiNote(void); +extern void asmEventMidiNoteOff(void); +extern void asmEventMidiPC(void); diff --git a/Source/mGBASMMidiFunctions.s b/Source/io/midi_asm.s similarity index 95% rename from Source/mGBASMMidiFunctions.s rename to Source/io/midi_asm.s index 3f82cad..0c62e30 100644 --- a/Source/mGBASMMidiFunctions.s +++ b/Source/io/midi_asm.s @@ -1,4 +1,27 @@ -.module mGBASMMidiFunctions + .module midi_asm + .optsdcc -msm83 + + .globl _addressByte + .globl _dataSet + .globl _noiEnv + .globl _noiSus + .globl _parameterLock + .globl _pbRange + .globl _pbWheelIn + .globl _playNoteNoi + .globl _playNotePoly + .globl _playNotePu1 + .globl _playNotePu2 + .globl _playNoteWav + .globl _pu1State + .globl _pu2State + .globl _statusByte + .globl _valueByte + .globl _vibratoDepth + .globl _vibratoSpeed + .globl _wavDataOffset + .globl _wavSus + .globl _wavSweepSpeed _popReturn$:: ret @@ -13,15 +36,15 @@ _asmEventMidiNote:: ld a,(#_statusByte) AND #0x0F cp #0x00 - jp z,_asmPlayNotePu1; + jp z,_playNotePu1 cp #0x01 - jp z,_asmPlayNotePu2$; + jp z,_playNotePu2 cp #0x02 - jp z,_asmPlayNoteWav$; + jp z,_playNoteWav cp #0x03 - jp z,_asmPlayNoteNoi$; + jp z,_playNoteNoi cp #0x04 - jp z,_asmPlayNotePoly$; + jp z,_playNotePoly ret _asmEventMidiCC:: @@ -232,7 +255,7 @@ _asmPu1Env$:: RRCA AND #0x0F - ld hl,#_pu1Env + ld hl,#_pu1State + 0 ld (hl),A ld de,#_dataSet + 2 @@ -369,14 +392,14 @@ _asmPu1SusOn$:: ld A,#0x01 ld de,#_dataSet + 5 ld (de),A - ld hl,#_pu1Sus + ld hl,#_pu1State + 1 ld (hl),A ret _asmPu1SusOff$:: ld A,#0x00 ld de,#_dataSet + 5 ld (de),A - ld hl,#_pu1Sus + ld hl,#_pu1State + 1 ld (hl),A ld hl,#_noteStatus + 0 @@ -393,7 +416,7 @@ ret _asmPu1Nf$:: ld A,#0x00 ld (#0xFF12),A - ld hl,#_pu1Sus + ld hl,#_pu1State + 1 ld (hl),A ld de,#_dataSet + 5 ld (de),A @@ -463,7 +486,7 @@ _asmPu2Env$:: RRCA AND #0x0F - ld hl,#_pu2Env + ld hl,#_pu2State + 0 ld (hl),A ld de,#_dataSet + 9 @@ -583,14 +606,14 @@ _asmPu2SusOn$:: ld A,#0x01 ld de,#_dataSet + 11 ld (de),A - ld hl,#_pu2Sus + ld hl,#_pu2State + 1 ld (hl),A ret _asmPu2SusOff$:: ld A,#0x00 ld de,#_dataSet + 11 ld (de),A - ld hl,#_pu2Sus + ld hl,#_pu2State + 1 ld (hl),A ld hl,#_noteStatus + 5 @@ -607,7 +630,7 @@ ret _asmPu2Nf$:: ld A,#0x00 ld (#0xFF17),A - ld hl,#_pu2Sus + ld hl,#_pu2State + 1 ld (hl),A ld de,#_dataSet + 11 ld (de),A diff --git a/Source/serial.c b/Source/io/serial.c similarity index 72% rename from Source/serial.c rename to Source/io/serial.c index 788ba49..54c1df9 100644 --- a/Source/serial.c +++ b/Source/io/serial.c @@ -1,6 +1,11 @@ -#include "mGB.h" +#include "serial.h" +#include "../mGB.h" #include +uint8_t serialBuffer[256]; +uint8_t serialBufferPosition; +uint8_t serialBufferReadPosition; + void serial_isr(void) CRITICAL INTERRUPT { serialBufferPosition++; // unsigned overflow from 255 -> 0 is automatic. serialBuffer[serialBufferPosition] = rSB; @@ -14,4 +19,4 @@ void serial_isr(void) CRITICAL INTERRUPT { systemIdle = 0; } -ISR_VECTOR(VECTOR_SERIAL, serial_isr) \ No newline at end of file +ISR_VECTOR(VECTOR_SERIAL, serial_isr) diff --git a/Source/io/serial.h b/Source/io/serial.h new file mode 100644 index 0000000..f1a16f9 --- /dev/null +++ b/Source/io/serial.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +extern uint8_t serialBuffer[256]; +extern uint8_t serialBufferPosition; +extern uint8_t serialBufferReadPosition; diff --git a/Source/mGBMemoryFunctions.c b/Source/io/sram.c similarity index 75% rename from Source/mGBMemoryFunctions.c rename to Source/io/sram.c index 14281c0..2a36ae4 100644 --- a/Source/mGBMemoryFunctions.c +++ b/Source/io/sram.c @@ -1,6 +1,9 @@ -#include "mGB.h" +#include "sram.h" +#include "../mGB.h" +#include "../synth/data.h" +#include -void saveDataSet(UBYTE synth) { +void saveDataSet(uint8_t synth) { ENABLE_RAM_MBC1; x = (synth + 24U); x = dataSet[x] * 8; @@ -34,7 +37,7 @@ void saveDataSet(UBYTE synth) { DISABLE_RAM_MBC1; } -void loadDataSet(UBYTE synth) { +void loadDataSet(uint8_t synth) { ENABLE_RAM_MBC1; x = dataSet[(synth + 24U)] * 8U; i = 0; @@ -72,33 +75,9 @@ void loadDataSet(UBYTE synth) { DISABLE_RAM_MBC1; } -void snapRecall(void) { - if (cursorRowMain == 0x08U) { - for (l = 0; l < 4; l++) { - if (cursorEnable[l]) { - if (!recallMode) { - saveDataSet(l); - } else { - loadDataSet(l); - updateSynth(l); - } - } - } - } else { - if (!recallMode) { - for (j = 0; j != 24; j++) - dataSetSnap[j] = dataSet[j]; - } else { - for (j = 0; j != 24; j++) - dataSet[j] = dataSetSnap[j]; - updateDisplay(); - } - } -} - void checkMemory(void) { ENABLE_RAM_MBC1; - if (saveData[512] != 0xF7) { + if (saveData[512] != SRAM_INITIALIZED) { for (x = 0; x != 128; x += 8) { l = 0; for (i = 0; i < 7; i++) { @@ -121,7 +100,7 @@ void checkMemory(void) { l++; } } - saveData[512] = 0xF7; + saveData[512] = SRAM_INITIALIZED; } DISABLE_RAM_MBC1; diff --git a/Source/io/sram.h b/Source/io/sram.h new file mode 100644 index 0000000..fe68841 --- /dev/null +++ b/Source/io/sram.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +#define SRAM_INITIALIZED 0xF7 + +// 512 + sentinel +extern uint8_t saveData[513U]; + +void saveDataSet(uint8_t synth); +void loadDataSet(uint8_t synth); +void checkMemory(void); \ No newline at end of file diff --git a/Source/io/sram/sram.b0.c b/Source/io/sram/sram.b0.c new file mode 100644 index 0000000..8999edf --- /dev/null +++ b/Source/io/sram/sram.b0.c @@ -0,0 +1,5 @@ +/// @file Bank 0 SRAM structure + +#include + +uint8_t saveData[513]; \ No newline at end of file diff --git a/Source/mGB.c b/Source/mGB.c index 6885018..ec8d1eb 100644 --- a/Source/mGB.c +++ b/Source/mGB.c @@ -1,123 +1,97 @@ -#include "mGB.h" - -void printbyte(UBYTE v1, UBYTE v2, UBYTE v3) { - bkg[0] = (v1 >> 4) + 1; - bkg[1] = (0x0F & v1) + 1; - - bkg[2] = 0; - - bkg[3] = (v2 >> 4) + 1; - bkg[4] = (0x0F & v2) + 1; - - bkg[5] = 0; - - bkg[6] = (v3 >> 4) + 1; - bkg[7] = (0x0F & v3) + 1; - - bkg[8] = 0; - set_bkg_tiles(1, 16, 10, 1, bkg); -} - -#include "mGBDisplayFunctions.c" -#include "mGBMemoryFunctions.c" -#include "mGBMidiFunctions.c" -#include "mGBSynthCommonFunctions.c" -#include "mGBSynthPitchFunctions.c" -#include "mGBUserFunctions.c" -#include "serial.c" - -void setSoundDefaults(void) { - rAUDENA = 0x8FU; // Turn sound on - rAUDVOL = 0x77U; // Turn on Pulses outs - - setOutputPan(0U, 64U); - setOutputPan(1U, 64U); - setOutputPan(2U, 64U); - setOutputPan(3U, 64U); - - asmLoadWav(wavDataOffset); // tRIANGLE - rAUD3LEVEL = 0x00U; - - rAUD4GO = 0x80U; - rAUD4LEN = 0x3FU; // sound length -} - -void testSynths(void) { - addressByte = 0x40; - valueByte = 0x7F; - asmPlayNotePu1(); -} - -void main(void) { - - CRITICAL { - cpu_fast(); - checkMemory(); - displaySetup(); - setSoundDefaults(); - add_TIM(updateSynths); - - loadDataSet(0x00U); - loadDataSet(0x01U); - loadDataSet(0x02U); - loadDataSet(0x03U); - } - - /* Set TMA to divide clock by 0x100 */ - rTMA = 0x00U; - /* Set clock to 262144 Hertz */ - rTAC = TACF_START | TACF_262KHZ; - /* Handle VBL and TIM interrupts */ - - set_interrupts(VBL_IFLAG | TIM_IFLAG | SIO_IFLAG); - - SHOW_BKG; - SHOW_SPRITES; - - showSplashScreen(); - delay(2000); - - showMainScreen(); - printversion(); - // testSynths(); - gameMain(); -} - -inline void gameMain(void) { - rSC = SIOF_XFER_START | SIOF_CLOCK_EXT; - while (1) { - systemIdle = 1; - - updateMidiBuffer(); - - if (systemIdle) - getPad(); - - if (systemIdle) - asmUpdatePu1(); - - if (systemIdle) - asmUpdatePu2(); - - if (systemIdle) - asmUpdateWav(); - - if (systemIdle) - asmUpdateNoi(); - - if (systemIdle) - mainScreen(); - } -} - -void mainScreen(void) { - if (currentScreen == 0) { - return; - }; - - updateDisplaySynthCounter = (updateDisplaySynthCounter + 1) & 3U; - - updateDisplaySynth(); - // printbyte(statusByte, addressByte, valueByte); - setPlayMarker(); -} \ No newline at end of file +#include "mGB.h" +#include "io/midi.h" +#include "io/sram.h" +#include "screen/main.h" +#include "screen/splash.h" +#include "screen/utils.h" +#include "synth/common.h" +#include "synth/noi.h" +#include "synth/pulse.h" +#include "synth/wav.h" + +uint8_t i; +uint8_t x; +uint8_t j; +uint8_t l; +bool systemIdle = true; + +void setSoundDefaults(void) { + rAUDENA = AUDENA_ON; // Turn sound on + rAUDVOL = AUDVOL_VOL_LEFT(7U) | AUDVOL_VOL_RIGHT(7U); + + setOutputPan(PU1, 64U); + setOutputPan(PU2, 64U); + setOutputPan(WAV, 64U); + setOutputPan(NOI, 64U); + + loadWav(wavDataOffset); // tRIANGLE + rAUD3LEVEL = 0x00U; + + rAUD4GO = 0x80U; + rAUD4LEN = 0x3FU; // sound length +} + +void testSynths(void) { + addressByte = 0x40; + valueByte = 0x7F; + playNotePu1(); +} + +void main(void) { + + CRITICAL { + cpu_fast(); + checkMemory(); + displaySetup(); + initMainScreen(); + setSoundDefaults(); + add_TIM(updateSynths); + + loadDataSet(PU1); + loadDataSet(PU2); + loadDataSet(WAV); + loadDataSet(NOI); + } + + /* Set TMA to divide clock by 0x100 */ + rTMA = 0x00U; + /* Set clock to 262144 Hertz */ + rTAC = TACF_START | TACF_262KHZ; + /* Handle VBL and TIM interrupts */ + set_interrupts(VBL_IFLAG | TIM_IFLAG | SIO_IFLAG); + + showSplashScreen(); + delay(2000); + + showMainScreen(); + printversion(); + // testSynths(); + gameMain(); +} + +inline void gameMain(void) { + rSC = SIOF_XFER_START | SIOF_CLOCK_EXT; + while (1) { + systemIdle = 1; + + updateMidiBuffer(); + + if (systemIdle) + getPad(); + + if (systemIdle) + updatePu1(); + + if (systemIdle) + updatePu2(); + + if (systemIdle) + updateWav(); + + if (systemIdle) + updateNoi(); + + if (systemIdle) + mainScreen(); + } +} diff --git a/Source/mGB.h b/Source/mGB.h index ad4a520..bbdd5c6 100644 --- a/Source/mGB.h +++ b/Source/mGB.h @@ -1,459 +1,13 @@ #pragma once #include -#include +#include -extern UBYTE saveData[513U]; +extern uint8_t i; +extern uint8_t x; +extern uint8_t j; +extern uint8_t l; -UBYTE serialBuffer[256]; -UBYTE serialBufferPosition; -UBYTE serialBufferReadPosition; +extern bool systemIdle; -// MIDI status -UBYTE statusByte; -// MIDI address (e.g. note/CC control) -UBYTE addressByte; -// MIDI value (e.g. velocity/value) -UBYTE valueByte; -UBYTE capturedAddress; -UBYTE updateDisplaySynthCounter; - -void asmLoadWav(UBYTE offset) OLDCALL; -void updateMidiBuffer(void); -void asmUpdatePu1(void); -void asmUpdatePu2(void); -void asmUpdateWav(void); -void asmUpdateNoi(void); -void asmPlayNotePu1(void); -void asmEventMidiPB(void); -void asmEventMidiCC(void); -void asmEventMidiNote(void); -void asmEventMidiNoteOff(void); -void asmEventMidiPC(void); - -inline void gameMain(void); -void mainScreen(void); -void updateVibratoPosition(UBYTE synth); -void updateSynth(UBYTE synth); -void updateValueSynth(UBYTE p); - -#define PU1 0 -#define PU2 1 -#define WAV 2 -#define NOI 3 - -#define PU1_CURRENT_STATUS 0 -#define PU1_CURRENT_NOTE 1 -#define PU2_CURRENT_STATUS 2 -#define PU2_CURRENT_NOTE 3 -#define WAV_CURRENT_STATUS 4 -#define WAV_CURRENT_NOTE 5 -#define NOI_CURRENT_STATUS 6 -#define NOI_CURRENT_NOTE 7 - -#define PBWHEEL_CENTER 0x80 - -#define RGB_LIGHT RGB(23, 29, 31) -#define RGB_DARK RGB(0, 0, 2) -#define RGB_HAWT RGB(31, 5, 31) -#define RGB_HAWTBLU RGB(0, 15, 31) -#define SPRITE_ARRL 0x79 -#define SPRITE_ARRT 0x80 -#define SPRITE_ARRT_START 26 -#define SPRITE_ARRL_START 27 -#define SPRITE_PUFREQ_LOW 1 - -UWORD freq[72] = { - 44, 156, 262, 363, 457, 547, 631, 710, 786, 854, 923, 986, - 1046, 1102, 1155, 1205, 1253, 1297, 1339, 1379, 1417, 1452, 1486, 1517, - 1546, 1575, 1602, 1627, 1650, 1673, 1694, 1714, 1732, 1750, 1767, 1783, - 1798, 1812, 1825, 1837, 1849, 1860, 1871, 1881, 1890, 1899, 1907, 1915, - 1923, 1930, 1936, 1943, 1949, 1954, 1959, 1964, 1969, 1974, 1978, 1982, - 1985, 1988, 1992, 1995, 1998, 2001, 2004, 2006, 2009, 2011, 2013, 2015}; - -UBYTE noteStatus[8]; - -UBYTE noiFreq[72] = { - 0x94, 0x87, 0x86, 0x85, 0x84, 0x77, 0x76, 0x75, 0x74, 0x67, 0x66, 0x65, - 0x64, 0x57, 0x56, 0x55, 0x54, 0x47, 0x46, 0x45, 0x44, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x25, 0x24, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x00, - 0x9C, 0x8F, 0x8E, 0x8D, 0x8C, 0x7F, 0x7E, 0x7D, 0x7C, 0x6F, 0x6E, 0x6D, - 0x6C, 0x5F, 0x5E, 0x5D, 0x5C, 0x4F, 0x4E, 0x4D, 0x4C, 0x3F, 0x3E, 0x3D, - 0x3C, 0x2F, 0x2E, 0x2D, 0x2C, 0x1F, 0x1E, 0x1D, 0x1C, 0x0F, 0x0E, 0x08}; - -UBYTE pu1Env; -UBYTE pu2Env; -UBYTE noiEnv; -UBYTE noiMode; - -UBYTE pu1Trig = 0x80; -UBYTE pu2Trig = 0x80; - -UBYTE pu1Vel; -UBYTE pu2Vel; - -BOOLEAN pu1NoteOffTrigger; -BOOLEAN pu2NoteOffTrigger; -BOOLEAN wavNoteOffTrigger; -BOOLEAN noiNoteOffTrigger; - -UINT8 polyVoiceSelect; -UBYTE polyNoteState[3]; - -BOOLEAN pu1Sus; -BOOLEAN pu2Sus; -BOOLEAN noiSus; -BOOLEAN wavSus; - -UBYTE outputSwitch[4] = {0x01, 0x02, 0x40, 0x80}; -UBYTE outputSwitchMute[4] = {0x01, 0x02, 0x40, 0x80}; -UBYTE outputSwitchValue[4] = {3, 3, 3, 3}; - -UBYTE counterWavStart; -UBYTE wavShapeLast; -UBYTE wavDataOffset; -UBYTE pbWheelIn[4] = {0x80, 0x80, 0x80, 0x80}; -UBYTE pbWheelInLast[4] = {0x80, 0x80, 0x80, 0x80}; -BOOLEAN pbWheelActive[4] = {0x00, 0x00, 0x00, 0x00}; -UBYTE pbRange[4] = {2, 2, 2, 12}; -UBYTE pbNoteRange[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -UWORD currentFreq; -UINT8 i; -UINT8 x; -UBYTE j; -UBYTE l; -UINT8 lastPadRead; -BOOLEAN joyState[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -UBYTE wavSweepSpeed; -UWORD wavCurrentFreq; -UWORD currentFreqData[4]; -const UBYTE wavData[256] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, - - 0x22, 0x55, 0x77, 0xAA, 0xBB, 0xDD, 0xEE, 0xFF, - 0xEE, 0xDD, 0xBB, 0xAA, 0x77, 0x66, 0x44, 0x00, - - 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, - 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, - - 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, - - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - - 0x16, 0x13, 0xAA, 0xB3, 0x25, 0x81, 0xE8, 0x2A, - 0x1B, 0xEB, 0xF8, 0x85, 0xE1, 0x28, 0xFF, 0xA4, - - 0x34, 0x09, 0x91, 0xA7, 0x63, 0xB8, 0x99, 0xA1, - 0x3F, 0xE4, 0xD0, 0x61, 0x66, 0x73, 0x59, 0x7C, - - 0x86, 0x04, 0x2F, 0xAC, 0x85, 0x17, 0xD6, 0xA1, - 0x03, 0xCF, 0x27, 0xE4, 0xF8, 0x27, 0x89, 0x2C, - - 0x30, 0x1B, 0xD4, 0x93, 0xD3, 0x6E, 0x35, 0x13, - 0x53, 0x05, 0x75, 0xB9, 0x79, 0xCF, 0x36, 0x00, - - 0xD4, 0x2C, 0xC6, 0x4E, 0x2C, 0x12, 0xE2, 0x15, - 0x8B, 0xAF, 0x3D, 0xEF, 0x6E, 0xF1, 0xBF, 0xD9, - - 0x43, 0x17, 0x2B, 0xF3, 0x12, 0xC2, 0xCB, 0x8C, - 0x3B, 0x43, 0xF2, 0xDF, 0x5D, 0xF9, 0xEF, 0x31, - - 0x6D, 0x46, 0xF6, 0x7A, 0xEE, 0x17, 0x35, 0xF4, - 0xDA, 0xFE, 0x7C, 0x28, 0xB8, 0x55, 0x12, 0x57, - - 0xFF, 0x82, 0xBB, 0x85, 0xEF, 0xD4, 0x7C, 0xA1, - 0x05, 0xB4, 0xFF, 0xC1, 0x95, 0x27, 0x30, 0x03}; - -INT8 pu1Oct; -INT8 pu2Oct; -INT8 wavOct; -INT8 noiOct; - -UINT16 counterWav; - -BOOLEAN cueWavSweep; - -const unsigned char data_barrow[16] = {0x00, 0x00, 0xE7, 0xE7, 0x7E, 0x7E, - 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}; - -const unsigned char data_larrow[] = {0xC0, 0xC0, 0xE0, 0xE0, 0x70, 0x70, - 0xE0, 0xE0, 0xC0, 0xC0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}; - -const unsigned char data_font[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0xC6, 0xC6, 0xE6, 0xE6, 0xD6, 0xD6, - 0xCE, 0xCE, 0xC6, 0xC6, 0x7E, 0x7E, 0x00, 0x00, 0x38, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x08, 0x08, 0x00, 0x00, - 0xFC, 0xFC, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, - 0x7C, 0x7C, 0x00, 0x00, 0xFC, 0xFC, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x3E, - 0x06, 0x06, 0x06, 0x06, 0xFC, 0xFC, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0x7E, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x02, 0x02, 0x00, 0x00, - 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, - 0xFE, 0xFE, 0x00, 0x00, 0x7E, 0x7E, 0xC0, 0xC0, 0xFE, 0xFE, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0xC6, 0xFC, 0xFC, 0x00, 0x00, 0xFE, 0xFE, 0x06, 0x06, - 0x0E, 0x0E, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x08, 0x08, 0x00, 0x00, - 0xFC, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, - 0x7E, 0x7E, 0x00, 0x00, 0xFC, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xFE, - 0x06, 0x06, 0x06, 0x06, 0x0C, 0x0C, 0x00, 0x00, 0x7E, 0x7E, 0xC6, 0xC6, - 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x82, 0x82, 0x00, 0x00, - 0xFC, 0xFC, 0xC6, 0xC6, 0xFC, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0xFC, 0xFC, 0x00, 0x00, 0x7E, 0x7E, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0x7E, 0x7E, 0x00, 0x00, 0xF8, 0xF8, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xF8, 0xF8, 0x00, 0x00, - 0x7E, 0x7E, 0xC0, 0xC0, 0xC0, 0xC0, 0xF8, 0xF8, 0xC0, 0xC0, 0xC0, 0xC0, - 0x7E, 0x7E, 0x00, 0x00, 0x7E, 0x7E, 0xC0, 0xC0, 0xC0, 0xC0, 0xF8, 0xF8, - 0xC0, 0xC0, 0xC0, 0xC0, 0x40, 0x40, 0x00, 0x00, 0x7C, 0x7C, 0xC0, 0xC0, - 0xCE, 0xCE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x7C, 0x00, 0x00, - 0xC4, 0xC4, 0xC6, 0xC6, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0x46, 0x46, 0x00, 0x00, 0xFE, 0xFE, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0xFE, 0xFE, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xFC, 0xFC, 0x00, 0x00, - 0xC6, 0xC6, 0xCC, 0xCC, 0xF8, 0xF8, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0x46, 0x46, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0x7E, 0x7E, 0x00, 0x00, 0xC6, 0xC6, 0xEE, 0xEE, - 0xD6, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x82, 0x82, 0x00, 0x00, - 0xFC, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0x82, 0x82, 0x00, 0x00, 0x7C, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x7C, 0x00, 0x00, 0x7E, 0x7E, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0xC6, 0xFC, 0xFC, 0xC0, 0xC0, 0x40, 0x40, 0x00, 0x00, - 0x7E, 0x7E, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x7E, 0x06, 0x06, - 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xF8, 0xF8, - 0xC6, 0xC6, 0xC6, 0xC6, 0x46, 0x46, 0x00, 0x00, 0x7E, 0x7E, 0xC0, 0xC0, - 0xC0, 0xC0, 0x7C, 0x7C, 0x06, 0x06, 0x06, 0x06, 0xFC, 0xFC, 0x00, 0x00, - 0xFE, 0xFE, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x08, 0x08, 0x00, 0x00, 0x46, 0x46, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0xC6, 0xFC, 0xFC, 0x00, 0x00, 0x82, 0x82, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x6C, 0x10, 0x10, 0x00, 0x00, - 0x82, 0x82, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xEE, 0xEE, - 0x44, 0x44, 0x00, 0x00, 0xC6, 0xC6, 0xEE, 0xEE, 0x6C, 0x6C, 0x38, 0x38, - 0x6C, 0x6C, 0xEE, 0xEE, 0xC6, 0xC6, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0x7E, 0x7E, 0x0C, 0x0C, 0x18, 0x18, 0x30, 0x30, 0x00, 0x00, - 0xFE, 0xFE, 0x0E, 0x0E, 0x1C, 0x1C, 0x38, 0x38, 0x70, 0x70, 0xE0, 0xE0, - 0xFE, 0xFE, 0x00, 0x00, 0x82, 0x82, 0x44, 0x44, 0x28, 0x28, 0x10, 0x10, - 0x28, 0x28, 0x44, 0x44, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, - 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x14, 0x14, 0x22, 0x22, 0x41, 0x41, 0x80, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x24, 0x24, 0x24, 0x24, 0x42, 0x42, - 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x14, 0x14, - 0x24, 0x24, 0x44, 0x44, 0x87, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x0D, 0x0D, 0x31, 0x31, 0xC1, 0xC1, 0x01, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3F, 0x3F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x90, 0x90, 0x0D, 0x0D, 0x42, 0x42, 0xA9, 0xA9, 0x04, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0xFF, 0xFF, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0, 0xFF, 0xFF, 0x7F, 0x7F, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0, 0xE0, 0xE0, 0xFF, 0xFF, - 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xC0, 0xE0, 0xE0, - 0xF0, 0xF0, 0xFF, 0xFF, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, - 0xF0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xFF, 0xFF, 0x7F, 0x7F, 0x00, 0x00, - 0x00, 0x00, 0xF0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, - 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x00, 0x00, - 0x00, 0x00, 0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x3F, 0x3F, 0x7F, 0x7F, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, - 0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x00, 0x00, - 0x00, 0x00, 0x07, 0x07, 0x1F, 0x1F, 0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, - 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x0F, 0x0F, 0x3F, 0x3F, - 0x7F, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, - 0x03, 0x03, 0x0F, 0x0F, 0x3F, 0x3F, 0xFF, 0xFF, 0xFE, 0xFE, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x07, 0x1F, 0x1F, 0xFF, 0xFF, - 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, - 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x6C, 0x6C, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x70, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, - 0x00, 0x08, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x06, 0x00, 0x06, 0x00, 0xFE, - 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x7E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x3E, 0x00, 0x06, 0x00, 0x06, 0x00, 0xFC, 0x00, 0x00, - 0x00, 0xC6, 0x00, 0xC6, 0x00, 0xC6, 0x00, 0x7E, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0xF3, 0xF3, 0xAB, 0xAB, - 0xAB, 0xAB, 0x89, 0x89, 0x04, 0x04, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, - 0x00, 0x00, 0xEF, 0xEF, 0x0C, 0x0C, 0x7F, 0x7F, 0x0C, 0x0C, 0xFF, 0xFF, - 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x20, 0x20, 0x90, 0x90, - 0xD1, 0xD1, 0xD1, 0xD1, 0xD0, 0xD0, 0x90, 0x90, 0x20, 0x20, 0xC0, 0xC0, - 0x00, 0x00, 0x00, 0x00, 0xB4, 0xB4, 0xF7, 0xF7, 0xE4, 0xE4, 0x44, 0x44, - 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x76, 0x55, 0x55, - 0x67, 0x67, 0x55, 0x55, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x75, 0x75, 0x45, 0x45, 0x77, 0x77, 0x15, 0x15, 0x31, 0x31, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x05, 0x05, 0x77, 0x77, 0x05, 0x05, - 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x50, 0x50, - 0x50, 0x50, 0x50, 0x50, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, - 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0xF8, 0xF8, 0xF8, 0xF8, - 0xF8, 0xF8, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x50, 0x50, 0x20, 0x20, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0F, - 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, - 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0xFF, 0x00, 0xFF, - 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, - 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x00, 0x70, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -const unsigned char versionnumber[10] = {32, 81, 2, 81, 4, 81, 4, 0, 0, 0}; - -const UBYTE helpdata[10][18] = { - {25, 13, 30, 11, 32, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {33, 11, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 1, 2}, - {15, 24, 32, 15, 22, 25, 26, 15, 0, 0, 0, 0, 0, 0, 13, 13, 1, 3}, - {29, 33, 15, 15, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 1, 4}, - {26, 12, 0, 28, 11, 24, 17, 15, 0, 0, 0, 0, 0, 0, 13, 13, 1, 5}, - {29, 31, 29, 30, 11, 19, 24, 0, 0, 0, 0, 0, 0, 0, 13, 13, 7, 5}, - {26, 11, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 2, 1}, - {26, 28, 15, 29, 15, 30, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 1, 6}, - {33, 11, 32, 0, 25, 16, 16, 29, 15, 30, 0, 0, 0, 0, 13, 13, 1, 3}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -}; - -const UBYTE helpmap[4][9] = {{0, 1, 2, 3, 4, 5, 6, 9, 7}, - {0, 1, 2, 9, 4, 5, 6, 9, 7}, - {0, 1, 8, 3, 4, 5, 6, 9, 7}, - {0, 9, 2, 9, 9, 5, 6, 9, 7}}; - -UBYTE bkg[20] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -const UBYTE logo[] = {70, 72, 74, 0, 0, 0, 0, 0, - 71, 73, 75, 76, 77, 78, 79, 80}; - -const UWORD bgpalette[] = {RGB_BLACK, RGB_BLACK, RGB_HAWT, RGB_WHITE}; - -const UWORD spritepalette[] = {RGB_WHITE, RGB_LIGHTGRAY, RGB_LIGHTGRAY, - RGB_BLACK, RGB_HAWT, RGB_HAWT, - RGB_HAWT, RGB_HAWT}; - -BOOLEAN recallMode; - -const UBYTE SCREEN_XO = 8; -const UBYTE SCREEN_YO = 16; -const UBYTE SCREEN_XSPACE = 32; -const UBYTE SCREEN_YSPACE = 8; -const UBYTE SCREEN_PSTARTX = 24; -const UBYTE SCREEN_PSTARTY = 41; - -BOOLEAN cursorEnable[4] = {1, 0, 0, 0}; -UBYTE cursorColumn; -UBYTE cursorRow[4]; -UBYTE cursorBigStartX[4]; -UBYTE cursorBigStartY[4]; -UBYTE cursorStartX[4]; -UBYTE cursorStartY[4]; -UBYTE cursorColumnLast; -UBYTE cursorRowMain; -BOOLEAN shiftSelect; - -BOOLEAN systemIdle = 1; - -UBYTE vibratoPosition[4] = {0, 0, 0, 0}; -UBYTE vibratoSpeed[4] = {1, 1, 1, 1}; -UBYTE vibratoDepth[4] = {0, 0, 0, 0}; -BOOLEAN vibratoSlope[4] = {0, 0, 0, 0}; - -UBYTE dataSetSnap[28]; -UBYTE dataSet[28] = { - 0x02, // 0 Transpose 0 - 6 - 0x00, // 1 Shape 0 - 3 - 0x06, // 2 Envelope 0 - F - 0x00, // 3 Sweep 0 - F - 0x02, // 4 PB Range 0 - 12 - 0x00, // 5 Sustain 0 - 1 - 0x03, // 6 Output 0 - 3 - - 0x02, // 7 Transpose 0 - 6 - 0x00, // 8 Shape 0 - 3 - 0x06, // 9 Envelope 0 - F - 0x02, // 10 PB Range 0 - 12 - 0x00, // 11 Sustain 0 - 1 - 0x03, // 12 Output 0 - 3 - - 0x02, // 13 Transpose 0 - 6 - 0x00, // 14 Shape 0 - F - 0x00, // 15 Offset 0 - F - 0x00, // 16 Sweep 0 - F - 0x02, // 17 PB Range 0 - 12 - 0x00, // 18 Sustain 0 - 1 - 0x03, // 19 Output 0 - 3 - - 0x02, // 20 Transpose 0 - 6 - 0x06, // 21 Env 0 - F - 0x00, // 22 Sustain 0 - 1 - 0x03, // 23 Output 0 - 3 - - 0x00, // 24 Save 0 - 0x00, // 25 Save 1 - 0x00, // 26 Save 2 - 0x00, // 27 Save 3 -}; - -UBYTE currentScreen; - -BOOLEAN parameterLock[24]; - -const UBYTE synthAddress[4][2] = {{0, 7}, {7, 13}, {13, 20}, {20, 24}}; - -const UBYTE tableCursorLookup[4][9] = { - {0, 1, 2, 3, 4, 5, 6, 255, 24}, - {7, 8, 9, 255, 10, 11, 12, 255, 25}, - {13, 14, 15, 16, 17, 18, 19, 255, 26}, - {20, 255, 21, 255, 255, 22, 23, 255, 27}}; - -const UBYTE tableData[28][3] = { - {3, 5, 6}, {3, 6, 4}, {3, 7, 16}, {3, 8, 255}, - {3, 9, 49}, {3, 10, 2}, {3, 11, 4}, - - {7, 5, 6}, {7, 6, 4}, {7, 7, 16}, {7, 9, 49}, - {7, 10, 2}, {7, 11, 4}, - - {11, 5, 6}, {11, 6, 16}, {11, 7, 32}, {11, 8, 16}, - {11, 9, 49}, {11, 10, 2}, {11, 11, 4}, - - {15, 5, 6}, {15, 7, 16}, {15, 10, 2}, {15, 11, 4}, - - {3, 13, 16}, {7, 13, 16}, {11, 13, 16}, {15, 13, 16}, -}; - -const UBYTE octmap[6][2] = {{3, 65}, {2, 65}, {83, 83}, - {2, 64}, {3, 64}, {4, 64}}; - -const UBYTE panmap[4][2] = { - {37, 37}, - {37, 28}, - {22, 37}, - {22, 28}, -}; - -const UBYTE susmap[2][2] = { - {83, 0}, - {82, 0}, -}; - -const UBYTE markerMapTiles[4][4] = {{0x03, 0x02, 0x00, 0x5B}, - {0x07, 0x02, 0x00, 0x5B}, - {0x0B, 0x02, 0x00, 0x5B}, - {0x0F, 0x02, 0x00, 0x5B}}; +void gameMain(void); diff --git a/Source/mGBASMFunctions.s b/Source/mGBASMFunctions.s deleted file mode 100644 index a8ccdb9..0000000 --- a/Source/mGBASMFunctions.s +++ /dev/null @@ -1,118 +0,0 @@ -.module mGBASMFunctions - -_asmLoadWav:: -push bc - lda hl,4(sp) ; Load a stack offset - ld A,(hl) ; Load micro offset into a - - ld bc,#_wavShapeLast - ld (bc),A - - ld HL, #_wavData; load HL with the beginning - ld C, A - ld B, #0x00 - add HL, BC - - - ;ld HL, #_wavData; load HL with the beginning - ld C,#0x30 ; #0xFF30 is the bottom of wave RAM - ld A, #0x00 ; \ - ld (#0xFF1A),A ; / Turn off wave channel - - ; Copy - ; 1 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 2 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 3 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 4 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 5 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 6 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 7 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 8 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 9 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 10 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 11 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 12 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 13 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 14 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 15 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ; 16 - ld A,(HL+) ; Load 1 byte... (And increment source pointer) - ldh (C),A ; ... and dump it into wave RAM - inc C ; Increment target pointer - - ld A, #0x80 ; \ - ld (#0xFF1A),A ; / Turn on wave channel - - - ld hl, #_wavCurrentFreq - ld A, (hl+) - ld (#0xFF1D),A - - ld A,(hl) - or #0x80 - ld (#0xFF1E),A - - ld hl,#_systemIdle - ld (hl),#0x00 -pop bc -ret \ No newline at end of file diff --git a/Source/mGBASMSynthFunctions.s b/Source/mGBASMSynthFunctions.s deleted file mode 100644 index 54a1e55..0000000 --- a/Source/mGBASMSynthFunctions.s +++ /dev/null @@ -1,924 +0,0 @@ -.module mGBASMSynthFunctions - -_asmUpdatePu1:: - ld hl, #_pu1NoteOffTrigger - ld A,(hl) - bit 0,A - jr nz, _asmUpdatePu1Noff$ - - ld hl, #_pbWheelIn + 0 - ld A,(hl) - cp #0x80 - jr nz, _asmUpdatePu1PbWheel$ - - ld hl, #_pbWheelActive + 0 - ld A,(hl) - bit 0,A - jr nz, _asmUpdatePu1PbWheelReset$ -ret - -_asmUpdatePu1Noff$:: - ld A,#0x00 - ld (#0xFF12),A - ld (hl),A -ret - -_asmUpdatePu1PbWheel$:: - ld hl, #_pbWheelInLast + 0 - cp (hl) - jr nz, _asmUpdatePu1PbWheelSet$ - - ld A, #0x01 - ld hl, #_pbWheelActive + 0 - ld (hl), A -ret -_asmUpdatePu1PbWheelSet$:: - ld (hl), A - - ld A, #0x01 - ld hl, #_pbWheelActive + 0 - ld (hl), A - - ld A, #0x00 - push af - inc sp - call _setPitchBendFrequencyOffset - inc sp -ret - -_asmUpdatePu1PbWheelReset$:: - ld A, #0x00 - ld (hl), A - ld A, #0x80 - ld hl, #_pbWheelInLast + 0 - ld (hl), A - - ld hl, #_noteStatus + 1 - ld A,(hl) - ld B,A - - ld A,#<_freq - add A,B - add A,B - ld E,A - ld A,#>_freq - ld D,A - - ld A,(DE) - ld (#0xFF13),A - ld hl, #_currentFreqData + 0 - ld (hl+), A - - inc DE - - ld A,(DE) - ld (hl), A - ld (#0xFF14),A -ret - -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- - -_asmUpdatePu2:: - ld hl, #_pu2NoteOffTrigger - ld A,(hl) - bit 0,A - jr nz, _asmUpdatePu2Noff$ - - ld hl, #_pbWheelIn + 1 - ld A,(hl) - cp #0x80 - jr nz, _asmUpdatePu2PbWheel$ - - ld hl, #_pbWheelActive + 1 - ld A,(hl) - bit 0,A - jr nz, _asmUpdatePu2PbWheelReset$ -ret - -_asmUpdatePu2Noff$:: - ld A,#0x00 - ld (#0xFF17),A - ld (hl),A -ret - -_asmUpdatePu2PbWheel$:: - ld hl, #_pbWheelInLast + 1 - cp (hl) - jr nz, _asmUpdatePu2PbWheelSet$ - - ld A, #0x01 - ld hl, #_pbWheelActive + 1 - ld (hl), A -ret -_asmUpdatePu2PbWheelSet$:: - ld (hl), A - - ld A, #0x01 - ld hl, #_pbWheelActive + 1 - ld (hl), A - - ld A, #0x01 - push af - inc sp - call _setPitchBendFrequencyOffset - inc sp -ret - -_asmUpdatePu2PbWheelReset$:: - ld A, #0x00 - ld (hl), A - ld A, #0x80 - ld hl, #_pbWheelInLast + 1 - ld (hl), A - - ld hl, #_noteStatus + 3 - ld A,(hl) - ld B,A - - - ld A,#<_freq - add A,B - add A,B - ld E,A - ld A,#>_freq - ld D,A - - ld A,(DE) - ld (#0xFF18),A - ld hl, #_currentFreqData + 2 - ld (hl+), A - - inc DE - - ld A,(DE) - ld (hl), A - ld (#0xFF19),A -ret - -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- - -_asmUpdateWav:: - ld hl, #_wavNoteOffTrigger - ld A,(hl) - bit 0,A - jr nz, _asmUpdateWavNoff$ - - ld hl, #_wavShapeLast - ld A,(hl) - ld hl, #_wavDataOffset - cp (hl) - jr nz, _asmUpdateWavData$ - - - ld hl, #_pbWheelIn + 2 - ld A,(hl) - cp #0x80 - jr nz, _asmUpdateWavPbWheel$ - - ld hl, #_pbWheelActive + 2 - ld A,(hl) - bit 0,A - jr nz, _asmUpdateWavPbWheelReset$ - -ret - -_asmUpdateWavNoff$:: - ld A,#0x00 - ld (#0xFF1C),A - ld (hl),A -ret - - - -_asmUpdateWavData$:: - ld A,(hl) - push af - inc sp - call _asmLoadWav - lda sp,1(sp) - - ld A, #0x80 - ld hl, #_pbWheelInLast + 2 - ld (hl), A -ret - -_asmUpdateWavPbWheel$:: - ld hl, #_pbWheelInLast + 2 - cp (hl) - jr nz, _asmUpdateWavPbWheelSet$ - - ld A, #0x01 - ld hl, #_pbWheelActive + 2 - ld (hl), A -ret -_asmUpdateWavPbWheelSet$:: - ld (hl), A - - ld A, #0x01 - ld hl, #_pbWheelActive + 2 - ld (hl), A - - ld A, #0x02 - push af - inc sp - call _setPitchBendFrequencyOffset - inc sp -ret - -_asmUpdateWavPbWheelReset$:: - ld A, #0x00 - ld (hl), A - ld A, #0x80 - ld hl, #_pbWheelInLast + 2 - ld (hl), A - - ld hl, #_noteStatus + 5 - ld A,(hl) - ld B,A - - ld A,#<_freq - add A,B - add A,B - ld E,A - ld A,#>_freq - ld D,A - - ld A,(DE) - - ld hl, #_wavCurrentFreq - ld (hl), A - ld hl, #_currentFreqData + 4 - ld (hl), A - ld C,A - ;ld A,#0x00 - ;ld (#0xFF1E),A - ld A,C - ld (#0xFF1D),A - - inc DE - ld A,(DE) - - inc hl - ld (hl), A - - ld hl, #_wavCurrentFreq + 1 - ld (hl), A - - and #0x7F - ld (#0xFF1E),A -ret - -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- - -_asmUpdateNoi:: - ld hl, #_pbWheelIn + 3 - ld A,(hl) - cp #0x80 - jr nz, _asmUpdateNoiPbWheel$ - - ld hl, #_pbWheelActive + 3 - ld A,(hl) - bit 0,A - jr nz, _asmUpdateNoiPbWheelReset$ -ret - -_asmUpdateNoiPbWheel$:: - ld hl, #_pbWheelInLast + 3 - cp (hl) - jr nz, _asmUpdateNoiPbWheelSet$ - - ld A, #0x01 - ld hl, #_pbWheelActive + 3 - ld (hl), A -ret -_asmUpdateNoiPbWheelSet$:: - ld (hl), A - - ld A, #0x01 - ld hl, #_pbWheelActive + 3 - ld (hl), A - - call _setPitchBendFrequencyOffsetNoise -ret - -_asmUpdateNoiPbWheelReset$:: - ld A, #0x00 - ld (hl), A - ld A, #0x80 - ld hl, #_pbWheelInLast + 3 - ld (hl), A - - ld hl, #_noteStatus + 3 - ld A,(hl) - ld B,A - - ld A,#<_noiFreq - add A,B - ld E,A - ld A,#>_noiFreq - ld D,A - - ld A,(DE) - ld (#0xFF22),A - ld hl, #_currentFreqData + 6 - ld (hl), A - - ld A,#0xFF - ld (#0xFF20),A - ;ld A,#0x80 - ;ld (#0xFF23),A -ret - -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- - -_asmPlayNotePu1:: - ld hl, #_addressByte - ld A,(hl) - SUB #0x24 - ld hl, #_pu1Oct - add (hl) - - ld B, A - ld hl, #_valueByte - ld A,(hl) - ld C, A - - cp #0x00 - jr nz,_asmPlayNotePu1OnSet$ - jr _asmPlayNotePu1Off$ - -_asmPlayNotePu1OnSet$:: - ld A, (#0xFF12) - cp #0x00 - jr z,_asmPlayNotePu1OnSetOn$ - jr _asmPlayNotePu1OnSetOff$ -_asmPlayNotePu1OnSetOn$:: - ld A, #0x80 - ld hl, #_pu1Trig - ld (hl),A - - ld hl, #_pu1Vel - ld A,C - ld (hl),A - RLCA - AND #0xF0 - ld hl, #_pu1Env - OR (hl) - ld (#0xFF12),A - - jr _asmPlayNotePu1On$ -_asmPlayNotePu1OnSetOff$:: - - ld hl, #_pu1Vel - ld A,(hl) - cp C - jr nz,_asmPlayNotePu1OnSetOn$ - ld hl, #_pu1NoteOffTrigger - ld A, (hl) - bit 0, A - jr nz,_asmPlayNotePu1OnSetOn$ - - ld A, #0x00 - ld hl, #_pu1Trig - ld (hl),A - - jr _asmPlayNotePu1On$ -ret - - -_asmPlayNotePu1On$:: - ld hl, #_noteStatus + 1 - ld (hl),B - - ld A,#<_freq - add A,B - add A,B - ld E,A - ld A,#>_freq - ld D,A - - ld A,(DE) - ld (#0xFF13),A - ld hl, #_currentFreqData + 0 - ld (hl+), A - - inc DE - - ld A,(DE) - ld (hl), A - - ld hl, #_pu1Trig - ld C,(hl) - or C - ld (#0xFF14),A - - ld A,#0x00 - ld hl,#_vibratoPosition + 0 - ld (hl),A - - ld A,#0x80 - ld hl,#_pbWheelInLast + 0 - ld (hl),A - - ld hl,#_pbRange + 0 - ld C,(hl) - ld A,B - sub C - ld hl,#_pbNoteRange + 0 - ld (hl+),A - ld A,B - add C - ld (hl),A - - ld A,#0x01 - ld hl, #_noteStatus + 0 - ld (hl),A - - ld A,#0x00 - ld hl, #_pu1NoteOffTrigger - ld (hl),A -ret - -_asmPlayNotePu1Off$:: - ld hl, #_noteStatus + 1 - ld A,(hl) - cp B - jr nz,_asmPlayNoteOffPu1Return$ - - ld hl, #_noteStatus + 0 - ld A,#0x00 - ld (hl), A - - ld hl, #_pu1Sus - ld A,(hl) - bit 0, A - jr nz,_asmPlayNoteOffPu1Return$ - - ld A,#0x01 - ld hl, #_pu1NoteOffTrigger - ld (hl),A - - ;ld A,#0x00 - ;ld (#0xFF12),A -ret - -_asmPlayNoteOffPu1Return$:: -ret - -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- - -_asmPlayNotePu2$:: - ld hl, #_addressByte - ld A,(hl) - SUB #0x24 - ld hl, #_pu2Oct - add (hl) - - ld B, A - ld hl, #_valueByte - ld A,(hl) - ld C, A - - cp #0x00 - jr nz,_asmPlayNotePu2OnSet$ - jr _asmPlayNotePu2Off$ - -_asmPlayNotePu2OnSet$:: - ld A, (#0xFF17) - cp #0x00 - jr z,_asmPlayNotePu2OnSetOn$ - jr _asmPlayNotePu2OnSetOff$ -_asmPlayNotePu2OnSetOn$:: - ld A, #0x80 - ld hl, #_pu2Trig - ld (hl),A - - ld hl, #_pu2Vel - ld A,C - ld (hl),A - RLCA - AND #0xF0 - ld hl, #_pu2Env - OR (hl) - ld (#0xFF17),A - - jr _asmPlayNotePu2On$ -_asmPlayNotePu2OnSetOff$:: - ld hl, #_pu2Vel - ld A,(hl) - cp C - jr nz,_asmPlayNotePu2OnSetOn$ - ld hl, #_pu2NoteOffTrigger - ld A, (hl) - bit 0, A - jr nz,_asmPlayNotePu2OnSetOn$ - - ld A, #0x00 - ld hl, #_pu2Trig - ld (hl),A - - jr _asmPlayNotePu2On$ -ret - -_asmPlayNotePu2On$:: - ld hl, #_noteStatus + 3 - ld (hl),B - - ld A,#<_freq - add A,B - add A,B - ld E,A - ld A,#>_freq - ld D,A - - ld A,(DE) - ld (#0xFF18),A - ld hl, #_currentFreqData + 2 - ld (hl+), A - - inc DE - - ld A,(DE) - ld (hl), A - ld hl, #_pu2Trig - ld C,(hl) - or C - ld (#0xFF19),A - - ld A,#0x00 - ld hl,#_vibratoPosition + 1 - ld (hl),A - - ld A,#0x80 - ld hl,#_pbWheelInLast + 1 - ld (hl),A - - ld hl,#_pbRange + 1 - ld C,(hl) - ld A,B - sub C - ld hl,#_pbNoteRange + 2 - ld (hl+),A - ld A,B - add C - ld (hl),A - - ld A,#0x01 - ld hl, #_noteStatus + 2 - ld (hl),A - - ld A,#0x00 - ld hl, #_pu2NoteOffTrigger - ld (hl),A -ret - -_asmPlayNotePu2Off$:: - ld hl, #_noteStatus + 3 - ld A,(hl) - cp B - jp nz,_popReturn$ - - ld hl, #_noteStatus + 2 - ld A,#0x00 - ld (hl), A - - ld hl, #_pu2Sus - ld A,(hl) - bit 0, A - jp nz,_popReturn$ - - ld A,#0x01 - ld hl, #_pu2NoteOffTrigger - ld (hl),A - - ;ld A,#0x00 - ;ld (#0xFF17),A -ret - - -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- - - -_asmPlayNoteWav$:: - ld hl, #_addressByte - ld A,(hl) - SUB #0x18 - ld hl, #_wavOct - add (hl) - ld B, A - ld hl, #_valueByte - ld A,(hl) - ld C, A - - cp #0x00 - jr nz,_asmPlayNoteWavOn$ - jp _asmPlayNoteWavOff$ -ret - -_asmPlayNoteWavOn$:: - ld hl, #_noteStatus + 5 - ld (hl),B - and #0x60 - cp #0x60 - jr z,_asmPlayNoteWavVolF$ - cp #0x40 - jr z,_asmPlayNoteWavVolM$ - ld A,#0x60 - ld (#0xFF1C),A - jr _asmPlayNoteWavSet$ -ret -_asmPlayNoteWavVolF$:: - ld A,#0x20 - ld (#0xFF1C),A - jr _asmPlayNoteWavSet$ -ret -_asmPlayNoteWavVolM$:: - ld A,#0x40 - ld (#0xFF1C),A - jr _asmPlayNoteWavSet$ -ret - -_asmPlayNoteWavSet$:: - ld A,#<_freq - add A,B - add A,B - ld E,A - ld A,#>_freq - ld D,A - - ld A,(DE) - - ld hl, #_wavCurrentFreq - ld (hl), A - ld hl, #_currentFreqData + 4 - ld (hl), A - ld C,A - ld A,#0x00 - ld (#0xFF1E),A - ld A,C - ld (#0xFF1D),A - - inc DE - ld A,(DE) - - inc hl - ld (hl), A - - ld hl, #_wavCurrentFreq + 1 - ld (hl), A - - ld (#0xFF1E),A - - ld A,#0x00 - ld hl,#_vibratoPosition + 2 - ld (hl),A - - ld A,#0x00 - ld hl,#_wavStepCounter - ld (hl),A - ld hl,#_counterWav - ld (hl+),A - ld (hl),A - ld hl,#_counterWavStart - ld (hl),A - - ld A,#0x80 - ld hl,#_pbWheelInLast + 2 - ld (hl),A - - ld hl,#_pbRange + 2 - ld C,(hl) - ld A,B - sub C - ld hl,#_pbNoteRange + 4 - ld (hl+),A - ld A,B - add C - ld (hl),A - - ld A,#0x01 - ld hl, #_noteStatus + 4 - ld (hl),A - ld hl,#_cueWavSweep - ld (hl),A - - ld A,#0x00 - ld hl, #_wavNoteOffTrigger - ld (hl),A -ret - - - -_asmPlayNoteWavOff$:: - ld hl, #_noteStatus + 5 - ld A,(hl) - cp B - jp nz,_popReturn$ - - - ld hl, #_noteStatus + 4 - ld A,#0x00 - ld (hl), A - - ld hl, #_wavSus - ld A,(hl) - bit 0, A - jp nz,_popReturn$ - - ld A,#0x01 - ld hl, #_wavNoteOffTrigger - ld (hl),A - - ;ld A,#0x00 - ;ld (#0xFF1C),A -ret - - -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- - -_asmPlayNoteNoi$:: - ld hl, #_addressByte - ld A,(hl) - SUB #0x18 - ld hl, #_pu2Oct - add (hl) - ld B, A - ld hl, #_valueByte - ld A,(hl) - ld C, A - - cp #0x00 - jr nz,_asmPlayNoteNoiOn$ - jr _asmPlayNoteNoiOff$ -ret - -_asmPlayNoteNoiOn$:: - ld hl, #_noteStatus + 7 - ld (hl),B - - ld hl, #_noiEnv - ld A,C - RLCA - AND #0xF0 - OR (hl) - ld (#0xFF21),A - - ld A,#<_noiFreq - add A,B - ld E,A - ld A,#>_noiFreq - ld D,A - - ld A,(DE) - ld (#0xFF22),A - ld hl, #_currentFreqData + 6 - ld (hl), A - - ld A,#0xFF - ld (#0xFF20),A - ld A,#0x80 - ld (#0xFF23),A - - ld A,#0x00 - ld hl,#_vibratoPosition + 3 - ld (hl),A - - ld A,#0x80 - ld hl,#_pbWheelInLast + 3 - ld (hl),A - - ld A,#0x01 - ld hl, #_noteStatus + 6 - ld (hl),A -ret - -_asmPlayNoteNoiOff$:: - ld hl, #_noteStatus + 7 - ld A,(hl) - cp B - jp nz,_popReturn$ - - ld hl, #_noteStatus + 6 - ld A,#0x00 - ld (hl), A - - ld hl, #_pu2Sus - ld A,(hl) - bit 0, A - jp nz,_popReturn$ - - ld A,#0x00 - ld (#0xFF21),A -ret - - -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- -;-------------------------------------------------------------- - -_asmPlayNotePoly$:: - ld hl, #_addressByte - ld A,(hl) - ld B, A - ld hl, #_valueByte - ld A,(hl) - ld C, A - - cp #0x00 - jr nz,_asmPlayNotePolyOn$ - jr _asmPlayNotePolyOff$ -ret -_asmPlayNotePolyOff$:: - ld hl,#_polyNoteState + 0 - ld A,(hl) - cp B - call z,_asmPlayNotePolyPu1Off$; - - ld hl, #_addressByte - ld A,(hl) - ld B, A - ld hl,#_polyNoteState + 1 - ld A,(hl) - cp B - call z,_asmPlayNotePolyPu2Off$; - - ld hl, #_addressByte - ld A,(hl) - ld B, A - ld hl,#_polyNoteState + 2 - ld A,(hl) - cp B - call z,_asmPlayNotePolyWavOff$; -ret - -_asmPlayNotePolyPu1Off$:: - call _asmPlayNotePu1 - -ret -_asmPlayNotePolyPu2Off$:: - call _asmPlayNotePu2$ - -ret -_asmPlayNotePolyWavOff$:: - call _asmPlayNoteWav$ - -ret - -_asmPlayNotePolyOn$:: - ld hl,#_polyVoiceSelect - ld A,(hl) - inc A - cp #0x03 - jr z,_asmPlayNotePolyRst$ - jr _asmPlayNotePolyCon$ -ret -_asmPlayNotePolyRst$:: - ld A, #0x00 - jr _asmPlayNotePolyCon$ -ret -_asmPlayNotePolyCon$:: - ld (hl),A - cp #0x00 - jr z,_asmPlayNotePolyPu1$ - cp #0x01 - jr z,_asmPlayNotePolyPu2$ - - ld hl,#_polyNoteState + 2 - ld (hl),B - jp _asmPlayNoteWav$; -ret -_asmPlayNotePolyPu1$:: - ld hl,#_polyNoteState + 0 - ld (hl),B - jp _asmPlayNotePu1; - -ret -_asmPlayNotePolyPu2$:: - ld hl,#_polyNoteState + 1 - ld (hl),B - jp _asmPlayNotePu2$; -ret diff --git a/Source/mGBDisplayFunctions.c b/Source/mGBDisplayFunctions.c deleted file mode 100644 index fa2aa22..0000000 --- a/Source/mGBDisplayFunctions.c +++ /dev/null @@ -1,263 +0,0 @@ -#include "mGB.h" - -void printversion(void) { set_bkg_tiles(1, 16, 10, 1, versionnumber); } - -void printhelp(void) { - j = helpmap[cursorColumn][cursorRowMain]; - set_bkg_tiles(1, 16, 18, 1, helpdata[j]); -} - -void updateDisplayValue(UBYTE p, UBYTE v) { - bkg[1] = 0; - switch (p) { - case 0U: - case 7U: - case 13U: - case 20U: - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, octmap[v]); - break; - case 1U: - case 8U: - bkg[0] = 44 + v; - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); - break; - case 2U: - case 9U: - case 21U: - if (!v) { - bkg[0] = 83; - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); - } else { - bkg[0] = 48 + v; - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); - } - break; - case 4U: - case 10U: - case 17U: - bkg[0] = 1 + (v >> 4); - bkg[1] = 1 + (0x0F & v); - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); - break; - case 5U: - case 11U: - case 18U: - case 22U: - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, susmap[v]); - break; - case 6U: - case 12U: - case 19U: - case 23U: - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, panmap[v]); - break; - case 14U: - if (v > 7U) { - bkg[1] = v - 7; - bkg[0] = 48; - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); - } else { - bkg[0] = 39 + v; - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); - } - break; - case 3U: - bkg[0] = 1 + (v >> 4); - bkg[1] = 1 + (0x0F & v); - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); - break; - case 15U: - bkg[0] = 1 + (v >> 4); - bkg[1] = 1 + (0x0F & v); - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); - break; - case 16U: - bkg[0] = 1 + v; - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); - break; - case 24U: - case 25U: - case 26U: - case 27U: - bkg[0] = 1 + (0x0F & v); - set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); - break; - default: - break; - } -} - -void updateDisplaySynth(void) { - // printbyte(serialBufferPosition,serialBufferReadPosition,serialBuffer[serialBufferPosition]); - for (i = 0; i != 0x09U; i++) { - if (tableCursorLookup[updateDisplaySynthCounter][i] != 0xFFU) { - updateDisplayValue( - tableCursorLookup[updateDisplaySynthCounter][i], - dataSet[tableCursorLookup[updateDisplaySynthCounter][i]]); - } - } -} - -void updateDisplay(void) { - UBYTE x = 0; - for (j = 0; j != 0x04U; j++) { - for (i = 0; i != 0x09U; i++) { - if (tableCursorLookup[j][i] != 0xFFU) { - // updateValue(tableCursorLookup[j][i],dataSet[tableCursorLookup[j][i]]); - updateDisplayValue(tableCursorLookup[j][i], - dataSet[tableCursorLookup[j][i]]); - updateValueSynth(tableCursorLookup[j][i]); - } - } - } -} - -void setCursor(void) { - if (cursorColumnLast != cursorColumn) { - if (cursorColumn > 0xF0U) - cursorColumn = 0x03U; - if (cursorColumn > 0x03U) - cursorColumn = 0U; - cursorEnable[cursorColumn] = 1U; - if (!joyState[6]) { - cursorEnable[cursorColumnLast] = 0U; - } - - // cursorRow[cursorColumn] = cursorRowMain; - cursorColumnLast = cursorColumn; - } - - for (j = 0; j != 4; j++) { - if (shiftSelect && !joyState[6] && cursorColumn != j) { - cursorEnable[j] = 0; - } - if (cursorEnable[j]) { - if (cursorRow[j] > 0xF0U) - cursorRow[j] = 0x08U; - if (cursorRow[j] > 0x08U) - cursorRow[j] = 0U; - move_sprite(SPRITE_ARRT_START, cursorBigStartX[cursorColumn], - cursorBigStartY[0]); - move_sprite(j + SPRITE_ARRL_START, cursorStartX[j], - (cursorRow[j] * SCREEN_YSPACE) + SCREEN_PSTARTY + SCREEN_YO); - if (j == cursorColumn) - cursorRowMain = cursorRow[j]; - } - } - for (j = 0; j != 4; j++) { - if (!cursorEnable[j]) { - cursorRow[j] = cursorRowMain; - move_sprite(j + SPRITE_ARRL_START, 0, 0); - } - } - if (!joyState[6]) { - shiftSelect = 0; - } else { - shiftSelect = 1; - } - printhelp(); -} - -void hideCursor(void) { - for (j = 0; j != 4; j++) { - move_sprite(j + SPRITE_ARRL_START, 0, 0); - } - move_sprite(SPRITE_ARRT_START, 0, 0); -} - -void showCursor(void) { setCursor(); } - -void setPlayMarker(void) { - for (j = 0; j != 4; j++) { - if (!j) { - bkg[0] = markerMapTiles[j][(2U + noteStatus[0])]; - } else if (j == 1) { - bkg[0] = markerMapTiles[j][(2U + noteStatus[2])]; - } else if (j == 2) { - bkg[0] = markerMapTiles[j][(2U + noteStatus[4])]; - } else { - bkg[0] = markerMapTiles[j][(2U + noteStatus[6])]; - } - set_bkg_tiles(markerMapTiles[j][0], markerMapTiles[j][1U], 1U, 1U, bkg); - } -} - -void cls(void) { - for (j = 0; j != 20; j++) - bkg[j] = 0x00U; - for (j = 0; j != 18; j++) { - set_bkg_tiles(0, j, 20, 1, bkg); - } -} - -void showMainScreen(void) { - cls(); - currentScreen = 1; - bkg[0] = 66; - set_bkg_tiles(3, 3, 1, 1, bkg); - bkg[0] = 67; - set_bkg_tiles(7, 3, 1, 1, bkg); - bkg[0] = 68; - set_bkg_tiles(11, 3, 1, 1, bkg); - bkg[0] = 69; - set_bkg_tiles(15, 3, 1, 1, bkg); - - for (j = 0; j != 28; j++) { - bkg[0] = bkg[1] = 1; - set_bkg_tiles(tableData[j][0], tableData[j][1], 2, 1, bkg); - } - - updateDisplay(); - showCursor(); -} - -void showSplashScreen(void) { - hideCursor(); - cls(); - set_bkg_tiles(6, 7, 8, 2, logo); -} - -void toggleScreen(void) { - if (currentScreen == 0) { - DISPLAY_ON; - showMainScreen(); - } else { - currentScreen = 0; - DISPLAY_OFF; - } -} - -void displaySetup(void) { - DISPLAY_OFF; - set_bkg_palette(0, 1, &bgpalette[0]); - - /* Initialize the background */ - set_bkg_data(0, 92, data_font); - // set_bkg_tiles(1,0, 20, 18, bgmap); - - set_sprite_palette(0, 2, &spritepalette[0]); - - for (j = 0; j != 4; j++) { - cursorBigStartX[j] = SCREEN_XO + SCREEN_PSTARTX + (j * SCREEN_XSPACE) - 1; - cursorBigStartY[j] = SCREEN_YO + SCREEN_PSTARTY - 8; - cursorStartX[j] = SCREEN_XO + SCREEN_PSTARTX + (j * SCREEN_XSPACE) - 8; - cursorStartY[j] = SCREEN_YO + SCREEN_PSTARTY; - cursorRow[j] = cursorStartY[j]; - } - - SPRITES_8x8; - - set_sprite_data(SPRITE_ARRT, 0x01U, data_barrow); - set_sprite_data(SPRITE_ARRL, 0x01U, data_larrow); - - set_sprite_tile(SPRITE_ARRT_START, SPRITE_ARRT); - for (j = 0; j != 4; j++) - set_sprite_tile(j + SPRITE_ARRL_START, SPRITE_ARRL); - - for (j = 0; j != 4; j++) - set_sprite_prop(j + SPRITE_ARRT_START, 1); - for (j = 0; j != 4; j++) - set_sprite_prop(j + SPRITE_ARRL_START, 1); - - DISPLAY_ON; -} diff --git a/Source/mGBSynthCommonFunctions.c b/Source/mGBSynthCommonFunctions.c deleted file mode 100644 index 5b1f2ec..0000000 --- a/Source/mGBSynthCommonFunctions.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "mGB.h" - -UBYTE wavStepCounter; - -void setOutputSwitch(void) { - NR51_REG = - outputSwitch[0] + outputSwitch[1] + outputSwitch[2] + outputSwitch[3]; -} - -void setOutputPanBySynth(UBYTE synth, UBYTE value) { - outputSwitchValue[synth] = value; - - if (value == 3U) { - value = 0x11 << synth; - } else if (value == 2U) { - value = 0x10 << synth; - } else if (value == 1U) { - value = 0x01 << synth; - } else { - value = 0x00; - } - outputSwitch[synth] = value; - NR51_REG = - outputSwitch[0] + outputSwitch[1] + outputSwitch[2] + outputSwitch[3]; -} - -void setOutputPan(UBYTE synth, UBYTE value) { - if (value > 96U) { - value = 0x10U << synth; - outputSwitchValue[synth] = 2; - } else if (value > 32U) { - value = 0x11U << synth; - outputSwitchValue[synth] = 3; - } else { - value = 0x01U << synth; - outputSwitchValue[synth] = 1; - } - outputSwitch[synth] = value; - NR51_REG = - outputSwitch[0] + outputSwitch[1] + outputSwitch[2] + outputSwitch[3]; -} - -void updateValueSynth(UBYTE p) { - switch (p) { - case 0: - pu1Oct = dataSet[p]; - pu1Oct = (pu1Oct - 2U) * 12U; - break; - case 1: - NR11_REG = ((dataSet[p] << 3) << 3) | 7; - break; - case 2: - pu1Env = dataSet[p]; - break; - case 3: - NR10_REG = dataSet[p]; - break; - case 4: - pbRange[0] = dataSet[p]; - break; - case 5: - pu1Sus = dataSet[p]; - if (!dataSet[p] && !noteStatus[PU1_CURRENT_STATUS]) - NR12_REG = 0U; - break; - case 6: - setOutputPanBySynth(0U, dataSet[p]); - break; - case 7: - pu2Oct = dataSet[p]; - pu2Oct = (pu2Oct - 2U) * 12U; - break; - case 8: - NR21_REG = ((dataSet[p] << 3) << 3) | 7; - break; - case 9: - pu2Env = dataSet[p]; - break; - case 10: - pbRange[1] = dataSet[p]; - break; - case 11: - pu2Sus = dataSet[p]; - if (!dataSet[p] && !noteStatus[PU2_CURRENT_STATUS]) - NR22_REG = 0U; - break; - case 12: - setOutputPanBySynth(1U, dataSet[p]); - break; - case 13: - wavOct = dataSet[p]; - wavOct = (wavOct - 2U) * 12U; - break; - case 14: - wavDataOffset = (dataSet[p] << 4) + dataSet[15]; - break; - case 15: - wavDataOffset = (dataSet[14] << 4) + dataSet[p]; - break; - case 16: - wavSweepSpeed = dataSet[p]; - break; - case 17: - pbRange[2] = dataSet[p]; - break; - case 18: - wavSus = dataSet[p]; - if (!dataSet[p] && !noteStatus[WAV_CURRENT_STATUS]) - NR32_REG = 0U; - break; - case 19: - setOutputPanBySynth(2, dataSet[p]); - break; - case 20: - noiOct = dataSet[p]; - noiOct = (noiOct - 2U) * 12U; - break; - case 21: - noiEnv = dataSet[p]; - break; - case 22: - noiSus = dataSet[p]; - if (!dataSet[p] && !noteStatus[NOI_CURRENT_STATUS]) - NR42_REG = 0U; - break; - case 23: - setOutputPanBySynth(3U, dataSet[p]); - break; - default: - break; - } -} - -void updateSynth(UBYTE synth) { - for (i = 0; i != 0x09U; i++) { - if (tableCursorLookup[synth][i] != 0xFFU) { - dataSet[tableCursorLookup[synth][i]] = - dataSet[tableCursorLookup[synth][i]]; - updateValueSynth(tableCursorLookup[synth][i]); - } - } -} - -void updateSynths(void) { - enable_interrupts(); - - if (vibratoDepth[PU1]) - updateVibratoPosition(PU1); - if (vibratoDepth[PU2]) - updateVibratoPosition(PU2); - if (vibratoDepth[WAV]) - updateVibratoPosition(WAV); - if (vibratoDepth[NOI]) - updateVibratoPosition(NOI); - if (wavSweepSpeed) { - if (!wavStepCounter) { - counterWav++; - if (wavSweepSpeed && cueWavSweep) { - wavCurrentFreq = currentFreqData[WAV] - (counterWav << wavSweepSpeed); - if (!(wavSweepSpeed >> 3U) && (wavCurrentFreq > 0x898U)) { - wavCurrentFreq = 0U; - cueWavSweep = 0U; - } - NR34_REG = wavCurrentFreq >> 8U; - NR33_REG = wavCurrentFreq; - } - } - wavStepCounter++; - if (wavStepCounter == 0x02U) - wavStepCounter = 0; - } -} diff --git a/Source/mGBSynthPitchFunctions.c b/Source/mGBSynthPitchFunctions.c deleted file mode 100644 index f9d66f5..0000000 --- a/Source/mGBSynthPitchFunctions.c +++ /dev/null @@ -1,93 +0,0 @@ -#include "mGB.h" - -void setPitchBendFrequencyOffset(UBYTE synth) { - UWORD freqRange; - UWORD f = freq[noteStatus[(synth << 1) + 0x01]]; - systemIdle = 0; - if (pbWheelIn[synth] & 0x80) { - freqRange = freq[pbNoteRange[(synth << 1) + 0x01]]; - currentFreq = (UWORD)(pbWheelIn[synth] - 0x7F); - currentFreq <<= 6; - currentFreq /= 128; - currentFreq = currentFreq * (freqRange - f); - currentFreq = f + (currentFreq >> 6); - } else { - freqRange = freq[pbNoteRange[synth << 1]]; - currentFreq = (UWORD)(0x80 - pbWheelIn[synth]); - currentFreq <<= 6; - currentFreq /= 128; - currentFreq = currentFreq * (f - freqRange); - currentFreq = f - (currentFreq >> 6); - } - switch (synth) { - case PU1: - NR14_REG = (currentFreq >> 8U); - NR13_REG = currentFreq; - currentFreqData[PU1] = currentFreq; - break; - case PU2: - NR24_REG = (currentFreq >> 8U); - NR23_REG = currentFreq; - currentFreqData[PU2] = currentFreq; - break; - default: - NR34_REG = (currentFreq >> 8U); - NR33_REG = currentFreq; - wavCurrentFreq = currentFreq; - currentFreqData[WAV] = currentFreq; - } -} - -void setPitchBendFrequencyOffsetNoise(void) { - systemIdle = 0; - if (pbWheelIn[NOI] & 0x80) { - noteStatus[NOI_CURRENT_NOTE] = noteStatus[NOI_CURRENT_NOTE]; - currentFreq = - noiFreq[noteStatus[NOI_CURRENT_NOTE] + ((pbWheelIn[NOI] - 0x80) >> 3)]; - } else { - noteStatus[NOI_CURRENT_NOTE] = noteStatus[NOI_CURRENT_NOTE]; - currentFreq = - noiFreq[noteStatus[NOI_CURRENT_NOTE] - ((0x80 - pbWheelIn[NOI]) >> 3)]; - } - NR43_REG = currentFreq; - currentFreqData[NOI] = currentFreq; -} - -void addVibrato(UBYTE synth) { - if (vibratoDepth[synth]) { - currentFreq = currentFreqData[synth] + vibratoPosition[synth]; - pbWheelInLast[synth] = PBWHEEL_CENTER; - if (synth == PU1) { - NR14_REG = (currentFreq >> 8U); - NR13_REG = currentFreq; - } else if (synth == PU2) { - NR24_REG = (currentFreq >> 8U); - NR23_REG = currentFreq; - } else if (synth == WAV) { - NR34_REG = (currentFreq >> 8U); - NR33_REG = currentFreq; - } else { - NR43_REG = currentFreq; - } - } -} - -UBYTE vibratoTimer[4]; - -void updateVibratoPosition(UBYTE synth) { - if (vibratoTimer[synth] == vibratoSpeed[synth]) { - vibratoTimer[synth] = 0x00; - if (vibratoSlope[synth] && vibratoPosition[synth] < vibratoDepth[synth]) { - vibratoPosition[synth] += 1; - } else { - vibratoSlope[synth] = 0; - if (vibratoPosition[synth]) { - vibratoPosition[synth] -= 1; - } else { - vibratoSlope[synth] = 1; - } - } - addVibrato(synth); - } - vibratoTimer[synth]++; -} diff --git a/Source/mGBUserFunctions.c b/Source/mGBUserFunctions.c deleted file mode 100644 index 200bfb9..0000000 --- a/Source/mGBUserFunctions.c +++ /dev/null @@ -1,170 +0,0 @@ -#include "mGB.h" - -void clearParameterLocks(void) { - for (j = 0; j != 24; j++) - parameterLock[j] = 0; -} - -void setDataValue(void) { - BOOLEAN up = 0; - UBYTE inc = 1; - systemIdle = 0; - - j = 0; - if (i & J_UP) { - j = 1; - up = 1; - inc = 16; - } else if (i & J_DOWN) { - j = 1; - inc = 16; - } else if (i & J_LEFT) { - j = 1; - } else if (i & J_RIGHT) { - up = 1; - j = 1; - } - if (j) { - for (j = 0; j != 4; j++) { - if (cursorEnable[j] && tableCursorLookup[j][cursorRow[j]] != 0xFFU) { - x = tableCursorLookup[j][cursorRow[j]]; - l = tableData[x][2]; - switch (x) { - case 6: - case 12: - case 19: - case 23: - if (i & J_DOWN) { - dataSet[x] = 0; - } else if (i & J_UP) { - dataSet[x] = 3; - } else if (i & J_LEFT) { - dataSet[x] = 2; - } else if (i & J_RIGHT) { - dataSet[x] = 1; - } - break; - case 0: - case 7: - case 13: - case 20: - inc = 1; - default: - if (up) { - dataSet[x] += inc; - if (dataSet[x] >= l) - dataSet[x] = (l - 1); - } else if (dataSet[x]) { - if (dataSet[x] > inc) { - dataSet[x] -= inc; - } else { - dataSet[x] = 0; - } - } - } - parameterLock[x] = 1; - updateValueSynth(x); - } - } - } -} - -void getPad(void) { - i = joypad(); - if (i != lastPadRead) { - lastPadRead = i; - if (i) { - if ((i & J_A) && !joyState[0]) { - joyState[0] = 1; - if (i & J_SELECT) { - toggleScreen(); - } else { - setDataValue(); - } - return; - } else if (joyState[0]) { - joyState[0] = 0; - setDataValue(); - return; - } - if ((i & J_B) && !joyState[1]) { - joyState[1] = 1; - if (i & J_SELECT) { - recallMode = 0; - } else { - recallMode = 1; - } - snapRecall(); - return; - } else if (joyState[1]) { - joyState[1] = 0; - return; - } - if ((i & J_UP) && !joyState[2]) { - joyState[2] = 1; - cursorRow[cursorColumn]--; - setCursor(); - return; - } else if (joyState[2]) { - joyState[2] = 0; - return; - } - if ((i & J_RIGHT) && !joyState[5]) { - joyState[5] = 1; - cursorColumn++; - setCursor(); - return; - } else if (joyState[5]) { - joyState[5] = 0; - return; - } - if ((i & J_DOWN) && !joyState[3]) { - joyState[3] = 1; - cursorRow[cursorColumn]++; - setCursor(); - return; - } else if (joyState[3]) { - joyState[3] = 0; - return; - } - if ((i & J_LEFT) && !joyState[4]) { - joyState[4] = 1; - cursorColumn--; - setCursor(); - return; - } else if (joyState[4]) { - joyState[4] = 0; - return; - } - if ((i & J_SELECT) && !joyState[6]) { - joyState[6] = 1; - return; - } else if (joyState[6]) { - joyState[6] = 0; - return; - } - if ((i & J_START) && !joyState[7]) { - joyState[7] = 1; - NR12_REG = 0; - NR22_REG = 0; - NR32_REG = 0; - NR42_REG = 0; - pbWheelIn[0] = pbWheelIn[1] = pbWheelIn[2] = pbWheelIn[3] = 0x80; - pu1Sus = pu2Sus = wavSus = 0; - - return; - } else if (joyState[7]) { - joyState[7] = 0; - return; - } - } else { - clearParameterLocks(); - for (j = 0; j != 8; j++) { - if (joyState[j]) { - joyState[j] = 0; - } - } - return; - } - } -} diff --git a/Source/mgb_save.c b/Source/mgb_save.c deleted file mode 100644 index f146e5e..0000000 --- a/Source/mgb_save.c +++ /dev/null @@ -1,3 +0,0 @@ -#include - -UBYTE saveData[513]; \ No newline at end of file diff --git a/Source/screen/main.c b/Source/screen/main.c new file mode 100644 index 0000000..c68b2a6 --- /dev/null +++ b/Source/screen/main.c @@ -0,0 +1,541 @@ + +#include "main.h" +#include "../io/sram.h" +#include "../mGB.h" +#include "../synth/common.h" +#include "../synth/data.h" +#include "../synth/pulse.h" +#include "../synth/wav.h" +#include "utils.h" + +bool recallMode; +uint8_t lastPadRead; +bool joyState[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +// v 1.3.3 +const uint8_t versionnumber[10] = {32, 81, 2, 81, 4, 81, 4, 0, 0, 0}; + +// TODO: can these be represented more clearly as text strings? +const uint8_t helpdata[10][18] = { + {25, 13, 30, 11, 32, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {33, 11, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 1, 2}, + {15, 24, 32, 15, 22, 25, 26, 15, 0, 0, 0, 0, 0, 0, 13, 13, 1, 3}, + {29, 33, 15, 15, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 1, 4}, + {26, 12, 0, 28, 11, 24, 17, 15, 0, 0, 0, 0, 0, 0, 13, 13, 1, 5}, + {29, 31, 29, 30, 11, 19, 24, 0, 0, 0, 0, 0, 0, 0, 13, 13, 7, 5}, + {26, 11, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 2, 1}, + {26, 28, 15, 29, 15, 30, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 1, 6}, + {33, 11, 32, 0, 25, 16, 16, 29, 15, 30, 0, 0, 0, 0, 13, 13, 1, 3}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; + +const uint8_t helpmap[4][9] = {{0, 1, 2, 3, 4, 5, 6, 9, 7}, + {0, 1, 2, 9, 4, 5, 6, 9, 7}, + {0, 1, 8, 3, 4, 5, 6, 9, 7}, + {0, 9, 2, 9, 9, 5, 6, 9, 7}}; + +const uint8_t SCREEN_XO = 8; +const uint8_t SCREEN_YO = 16; +const uint8_t SCREEN_XSPACE = 32; +const uint8_t SCREEN_YSPACE = 8; +const uint8_t SCREEN_PSTARTX = 24; +const uint8_t SCREEN_PSTARTY = 41; + +bool cursorEnable[4] = {1, 0, 0, 0}; +uint8_t cursorColumn; +uint8_t cursorRow[4]; +uint8_t cursorBigStartX[4]; +uint8_t cursorBigStartY[4]; +uint8_t cursorStartX[4]; +uint8_t cursorStartY[4]; +uint8_t cursorColumnLast; +uint8_t cursorRowMain; +bool shiftSelect; + +uint8_t updateDisplaySynthCounter; + +const uint8_t tableCursorLookup[4][9] = { + {0, 1, 2, 3, 4, 5, 6, 255, 24}, + {7, 8, 9, 255, 10, 11, 12, 255, 25}, + {13, 14, 15, 16, 17, 18, 19, 255, 26}, + {20, 255, 21, 255, 255, 22, 23, 255, 27}}; + +const uint8_t tableData[28][3] = { + {3, 5, 6}, {3, 6, 4}, {3, 7, 16}, {3, 8, 255}, + {3, 9, 49}, {3, 10, 2}, {3, 11, 4}, + + {7, 5, 6}, {7, 6, 4}, {7, 7, 16}, {7, 9, 49}, + {7, 10, 2}, {7, 11, 4}, + + {11, 5, 6}, {11, 6, 16}, {11, 7, 32}, {11, 8, 16}, + {11, 9, 49}, {11, 10, 2}, {11, 11, 4}, + + {15, 5, 6}, {15, 7, 16}, {15, 10, 2}, {15, 11, 4}, + + {3, 13, 16}, {7, 13, 16}, {11, 13, 16}, {15, 13, 16}, +}; + +const uint8_t octmap[6][2] = {{3, 65}, {2, 65}, {83, 83}, + {2, 64}, {3, 64}, {4, 64}}; + +const uint8_t panmap[4][2] = { + {37, 37}, + {37, 28}, + {22, 37}, + {22, 28}, +}; + +const uint8_t susmap[2][2] = { + {83, 0}, + {82, 0}, +}; + +const uint8_t markerMapTiles[4][4] = {{0x03, 0x02, 0x00, 0x5B}, + {0x07, 0x02, 0x00, 0x5B}, + {0x0B, 0x02, 0x00, 0x5B}, + {0x0F, 0x02, 0x00, 0x5B}}; + +void initMainScreen(void) { + for (j = 0; j != 4; j++) { + cursorBigStartX[j] = SCREEN_XO + SCREEN_PSTARTX + (j * SCREEN_XSPACE) - 1; + cursorBigStartY[j] = SCREEN_YO + SCREEN_PSTARTY - 8; + cursorStartX[j] = SCREEN_XO + SCREEN_PSTARTX + (j * SCREEN_XSPACE) - 8; + cursorStartY[j] = SCREEN_YO + SCREEN_PSTARTY; + cursorRow[j] = cursorStartY[j]; + } +} + +void showMainScreen(void) { + cls(); + currentScreen = 1; + bkg[0] = 66; + set_bkg_tiles(3, 3, 1, 1, bkg); + bkg[0] = 67; + set_bkg_tiles(7, 3, 1, 1, bkg); + bkg[0] = 68; + set_bkg_tiles(11, 3, 1, 1, bkg); + bkg[0] = 69; + set_bkg_tiles(15, 3, 1, 1, bkg); + + for (j = 0; j != 28; j++) { + bkg[0] = bkg[1] = 1; + set_bkg_tiles(tableData[j][0], tableData[j][1], 2, 1, bkg); + } + + updateDisplay(); + showCursor(); +} + +void toggleScreen(void) { + if (currentScreen == 0) { + DISPLAY_ON; + showMainScreen(); + } else { + currentScreen = 0; + DISPLAY_OFF; + } +} + +void mainScreen(void) { + if (currentScreen == 0) { + return; + }; + + updateDisplaySynthCounter = (updateDisplaySynthCounter + 1) & 3U; + + updateDisplaySynth(); + // printbyte(statusByte, addressByte, valueByte); + setPlayMarker(); +} + +void printversion(void) { set_bkg_tiles(1, 16, 10, 1, versionnumber); } + +void printhelp(void) { + j = helpmap[cursorColumn][cursorRowMain]; + set_bkg_tiles(1, 16, 18, 1, helpdata[j]); +} + +void updateDisplayValue(uint8_t p, uint8_t v) { + bkg[1] = 0; + switch (p) { + case 0U: + case 7U: + case 13U: + case 20U: + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, octmap[v]); + break; + case 1U: + case 8U: + bkg[0] = 44 + v; + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); + break; + case 2U: + case 9U: + case 21U: + if (!v) { + bkg[0] = 83; + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); + } else { + bkg[0] = 48 + v; + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); + } + break; + case 4U: + case 10U: + case 17U: + bkg[0] = 1 + (v >> 4); + bkg[1] = 1 + (0x0F & v); + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); + break; + case 5U: + case 11U: + case 18U: + case 22U: + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, susmap[v]); + break; + case 6U: + case 12U: + case 19U: + case 23U: + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, panmap[v]); + break; + case 14U: + if (v > 7U) { + bkg[1] = v - 7; + bkg[0] = 48; + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); + } else { + bkg[0] = 39 + v; + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); + } + break; + case 3U: + bkg[0] = 1 + (v >> 4); + bkg[1] = 1 + (0x0F & v); + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); + break; + case 15U: + bkg[0] = 1 + (v >> 4); + bkg[1] = 1 + (0x0F & v); + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); + break; + case 16U: + bkg[0] = 1 + v; + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); + break; + case 24U: + case 25U: + case 26U: + case 27U: + bkg[0] = 1 + (0x0F & v); + set_bkg_tiles(tableData[p][0], tableData[p][1], 2, 1, bkg); + break; + default: + break; + } +} + +void updateDisplaySynth(void) { + // printbyte(serialBufferPosition,serialBufferReadPosition,serialBuffer[serialBufferPosition]); + for (i = 0; i != 0x09U; i++) { + if (tableCursorLookup[updateDisplaySynthCounter][i] != 0xFFU) { + updateDisplayValue( + tableCursorLookup[updateDisplaySynthCounter][i], + dataSet[tableCursorLookup[updateDisplaySynthCounter][i]]); + } + } +} + +void updateDisplay(void) { + uint8_t x = 0; + for (j = 0; j != 0x04U; j++) { + for (i = 0; i != 0x09U; i++) { + if (tableCursorLookup[j][i] != 0xFFU) { + // updateValue(tableCursorLookup[j][i],dataSet[tableCursorLookup[j][i]]); + updateDisplayValue(tableCursorLookup[j][i], + dataSet[tableCursorLookup[j][i]]); + + // TODO: why is this needed here? + // updateValueSynth(tableCursorLookup[j][i]); + } + } + } +} + +void setCursor(void) { + if (cursorColumnLast != cursorColumn) { + if (cursorColumn > 0xF0U) + cursorColumn = 0x03U; + if (cursorColumn > 0x03U) + cursorColumn = 0U; + cursorEnable[cursorColumn] = 1U; + if (!joyState[6]) { + cursorEnable[cursorColumnLast] = 0U; + } + + // cursorRow[cursorColumn] = cursorRowMain; + cursorColumnLast = cursorColumn; + } + + for (j = 0; j != 4; j++) { + if (shiftSelect && !joyState[6] && cursorColumn != j) { + cursorEnable[j] = 0; + } + if (cursorEnable[j]) { + if (cursorRow[j] > 0xF0U) + cursorRow[j] = 0x08U; + if (cursorRow[j] > 0x08U) + cursorRow[j] = 0U; + move_sprite(SPRITE_ARRT_START, cursorBigStartX[cursorColumn], + cursorBigStartY[0]); + move_sprite(j + SPRITE_ARRL_START, cursorStartX[j], + (cursorRow[j] * SCREEN_YSPACE) + SCREEN_PSTARTY + SCREEN_YO); + if (j == cursorColumn) + cursorRowMain = cursorRow[j]; + } + } + for (j = 0; j != 4; j++) { + if (!cursorEnable[j]) { + cursorRow[j] = cursorRowMain; + move_sprite(j + SPRITE_ARRL_START, 0, 0); + } + } + if (!joyState[6]) { + shiftSelect = 0; + } else { + shiftSelect = 1; + } + printhelp(); +} + +void showCursor(void) { setCursor(); } + +void setPlayMarker(void) { + for (j = 0; j != 4; j++) { + bkg[0] = markerMapTiles[j][(2U + noteStatus[j].active)]; + set_bkg_tiles(markerMapTiles[j][0], markerMapTiles[j][1U], 1U, 1U, bkg); + } +} + +void clearParameterLocks(void) { + for (j = 0; j != 24; j++) + parameterLock[j] = 0; +} + +void setDataValue(void) { + bool up = 0; + uint8_t inc = 1; + systemIdle = 0; + + j = 0; + if (i & J_UP) { + j = 1; + up = 1; + inc = 16; + } else if (i & J_DOWN) { + j = 1; + inc = 16; + } else if (i & J_LEFT) { + j = 1; + } else if (i & J_RIGHT) { + up = 1; + j = 1; + } + if (j) { + for (j = 0; j != 4; j++) { + if (cursorEnable[j] && tableCursorLookup[j][cursorRow[j]] != 0xFFU) { + x = tableCursorLookup[j][cursorRow[j]]; + l = tableData[x][2]; + switch (x) { + case 6: + case 12: + case 19: + case 23: + if (i & J_DOWN) { + dataSet[x] = 0; + } else if (i & J_UP) { + dataSet[x] = 3; + } else if (i & J_LEFT) { + dataSet[x] = 2; + } else if (i & J_RIGHT) { + dataSet[x] = 1; + } + break; + case 0: + case 7: + case 13: + case 20: + inc = 1; + default: + if (up) { + dataSet[x] += inc; + if (dataSet[x] >= l) + dataSet[x] = (l - 1); + } else if (dataSet[x]) { + if (dataSet[x] > inc) { + dataSet[x] -= inc; + } else { + dataSet[x] = 0; + } + } + } + parameterLock[x] = 1; + updateValueSynth(x); + } + } + } +} + +// TODO: move the main pad handler out, split into screen level handlers +void getPad(void) { + i = joypad(); + if (i != lastPadRead) { + lastPadRead = i; + if (i) { + if ((i & J_A) && !joyState[0]) { + joyState[0] = 1; + if (i & J_SELECT) { + toggleScreen(); + } else { + setDataValue(); + } + return; + } else if (joyState[0]) { + joyState[0] = 0; + setDataValue(); + return; + } + if ((i & J_B) && !joyState[1]) { + joyState[1] = 1; + if (i & J_SELECT) { + recallMode = 0; + } else { + recallMode = 1; + } + snapRecall(); + return; + } else if (joyState[1]) { + joyState[1] = 0; + return; + } + if ((i & J_UP) && !joyState[2]) { + joyState[2] = 1; + cursorRow[cursorColumn]--; + setCursor(); + return; + } else if (joyState[2]) { + joyState[2] = 0; + return; + } + if ((i & J_RIGHT) && !joyState[5]) { + joyState[5] = 1; + cursorColumn++; + setCursor(); + return; + } else if (joyState[5]) { + joyState[5] = 0; + return; + } + if ((i & J_DOWN) && !joyState[3]) { + joyState[3] = 1; + cursorRow[cursorColumn]++; + setCursor(); + return; + } else if (joyState[3]) { + joyState[3] = 0; + return; + } + if ((i & J_LEFT) && !joyState[4]) { + joyState[4] = 1; + cursorColumn--; + setCursor(); + return; + } else if (joyState[4]) { + joyState[4] = 0; + return; + } + if ((i & J_SELECT) && !joyState[6]) { + joyState[6] = 1; + return; + } else if (joyState[6]) { + joyState[6] = 0; + return; + } + if ((i & J_START) && !joyState[7]) { + joyState[7] = 1; + rAUD1ENV = 0; + rAUD2ENV = 0; + rAUD3LEVEL = 0; + rAUD4ENV = 0; + pbWheelIn[0] = pbWheelIn[1] = pbWheelIn[2] = pbWheelIn[3] = + PBWHEEL_CENTER; + pu1State.sus = pu2State.sus = wavSus = 0; + + return; + } else if (joyState[7]) { + joyState[7] = 0; + return; + } + } else { + clearParameterLocks(); + for (j = 0; j != 8; j++) { + if (joyState[j]) { + joyState[j] = 0; + } + } + return; + } + } +} + +void printbyte(uint8_t v1, uint8_t v2, uint8_t v3) { + bkg[0] = (v1 >> 4) + 1; + bkg[1] = (0x0F & v1) + 1; + + bkg[2] = 0; + + bkg[3] = (v2 >> 4) + 1; + bkg[4] = (0x0F & v2) + 1; + + bkg[5] = 0; + + bkg[6] = (v3 >> 4) + 1; + bkg[7] = (0x0F & v3) + 1; + + bkg[8] = 0; + set_bkg_tiles(1, 16, 10, 1, bkg); +} + +void snapRecall(void) { + if (cursorRowMain == 0x08U) { + for (l = 0; l < 4; l++) { + if (cursorEnable[l]) { + if (!recallMode) { + saveDataSet(l); + } else { + loadDataSet(l); + updateSynth(l); + } + } + } + } else { + if (!recallMode) { + for (j = 0; j != 24; j++) + dataSetSnap[j] = dataSet[j]; + } else { + for (j = 0; j != 24; j++) + dataSet[j] = dataSetSnap[j]; + updateDisplay(); + } + } +} + +void updateSynth(uint8_t synth) { + for (i = 0; i != 0x09U; i++) { + if (tableCursorLookup[synth][i] != 0xFFU) { + // TODO: is this noop assign needed? + dataSet[tableCursorLookup[synth][i]] = + dataSet[tableCursorLookup[synth][i]]; + updateValueSynth(tableCursorLookup[synth][i]); + } + } +} diff --git a/Source/screen/main.h b/Source/screen/main.h new file mode 100644 index 0000000..eff550d --- /dev/null +++ b/Source/screen/main.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include + +extern bool recallMode; +extern uint8_t lastPadRead; +extern bool joyState[8]; + +// v 1.3.3 +extern const uint8_t versionnumber[10]; + +// TODO: can these be represented more clearly as text strings? +extern const uint8_t helpdata[10][18]; + +extern const uint8_t helpmap[4][9]; + +extern const uint8_t SCREEN_XO; +extern const uint8_t SCREEN_YO; +extern const uint8_t SCREEN_XSPACE; +extern const uint8_t SCREEN_YSPACE; +extern const uint8_t SCREEN_PSTARTX; +extern const uint8_t SCREEN_PSTARTY; + +extern bool cursorEnable[4]; +extern uint8_t cursorColumn; +extern uint8_t cursorRow[4]; +extern uint8_t cursorBigStartX[4]; +extern uint8_t cursorBigStartY[4]; +extern uint8_t cursorStartX[4]; +extern uint8_t cursorStartY[4]; +extern uint8_t cursorColumnLast; +extern uint8_t cursorRowMain; +extern bool shiftSelect; + +extern uint8_t updateDisplaySynthCounter; + +extern const uint8_t tableCursorLookup[4][9]; + +extern const uint8_t tableData[28][3]; + +extern const uint8_t octmap[6][2]; + +extern const uint8_t panmap[4][2]; + +extern const uint8_t susmap[2][2]; + +extern const uint8_t markerMapTiles[4][4]; + +void initMainScreen(void); +void updateDisplay(void); +void updateDisplaySynth(void); +void showCursor(void); +void setPlayMarker(void); +void snapRecall(void); +void updateSynth(uint8_t synth); +void mainScreen(void); +void showMainScreen(void); +void printversion(void); +void getPad(void); diff --git a/Source/screen/splash.c b/Source/screen/splash.c new file mode 100644 index 0000000..8ce0485 --- /dev/null +++ b/Source/screen/splash.c @@ -0,0 +1,13 @@ +#include "splash.h" +#include "main.h" +#include "utils.h" + +// TODO: more into res/logo.png and convert in build step +const uint8_t logo[] = {70, 72, 74, 0, 0, 0, 0, 0, + 71, 73, 75, 76, 77, 78, 79, 80}; + +void showSplashScreen(void) { + hideCursor(); + cls(); + set_bkg_tiles(6, 7, 8, 2, logo); +} diff --git a/Source/screen/splash.h b/Source/screen/splash.h new file mode 100644 index 0000000..dffd7c8 --- /dev/null +++ b/Source/screen/splash.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +// TODO: more into res/logo.png and convert in build step +extern const uint8_t logo[]; + +void showSplashScreen(void); diff --git a/Source/screen/utils.c b/Source/screen/utils.c new file mode 100644 index 0000000..8d40bd8 --- /dev/null +++ b/Source/screen/utils.c @@ -0,0 +1,192 @@ +#include "utils.h" +#include "../mGB.h" + +uint8_t bkg[20] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +uint8_t currentScreen; + +// TODO: generate from png +const uint8_t data_barrow[16] = {0x00, 0x00, 0xE7, 0xE7, 0x7E, 0x7E, + 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; + +// TODO: generate from png +const uint8_t data_larrow[16] = {0xC0, 0xC0, 0xE0, 0xE0, 0x70, 0x70, + 0xE0, 0xE0, 0xC0, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; + +// TODO: generate from png +const uint8_t data_font[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0xC6, 0xC6, 0xE6, 0xE6, 0xD6, 0xD6, + 0xCE, 0xCE, 0xC6, 0xC6, 0x7E, 0x7E, 0x00, 0x00, 0x38, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x08, 0x08, 0x00, 0x00, + 0xFC, 0xFC, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, + 0x7C, 0x7C, 0x00, 0x00, 0xFC, 0xFC, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x3E, + 0x06, 0x06, 0x06, 0x06, 0xFC, 0xFC, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, + 0xC6, 0xC6, 0x7E, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x02, 0x02, 0x00, 0x00, + 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, + 0xFE, 0xFE, 0x00, 0x00, 0x7E, 0x7E, 0xC0, 0xC0, 0xFE, 0xFE, 0xC6, 0xC6, + 0xC6, 0xC6, 0xC6, 0xC6, 0xFC, 0xFC, 0x00, 0x00, 0xFE, 0xFE, 0x06, 0x06, + 0x0E, 0x0E, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x08, 0x08, 0x00, 0x00, + 0xFC, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, + 0x7E, 0x7E, 0x00, 0x00, 0xFC, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xFE, + 0x06, 0x06, 0x06, 0x06, 0x0C, 0x0C, 0x00, 0x00, 0x7E, 0x7E, 0xC6, 0xC6, + 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x82, 0x82, 0x00, 0x00, + 0xFC, 0xFC, 0xC6, 0xC6, 0xFC, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, + 0xFC, 0xFC, 0x00, 0x00, 0x7E, 0x7E, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0xC0, 0xC0, 0xC0, 0xC0, 0x7E, 0x7E, 0x00, 0x00, 0xF8, 0xF8, 0xC6, 0xC6, + 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xF8, 0xF8, 0x00, 0x00, + 0x7E, 0x7E, 0xC0, 0xC0, 0xC0, 0xC0, 0xF8, 0xF8, 0xC0, 0xC0, 0xC0, 0xC0, + 0x7E, 0x7E, 0x00, 0x00, 0x7E, 0x7E, 0xC0, 0xC0, 0xC0, 0xC0, 0xF8, 0xF8, + 0xC0, 0xC0, 0xC0, 0xC0, 0x40, 0x40, 0x00, 0x00, 0x7C, 0x7C, 0xC0, 0xC0, + 0xCE, 0xCE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x7C, 0x00, 0x00, + 0xC4, 0xC4, 0xC6, 0xC6, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, + 0x46, 0x46, 0x00, 0x00, 0xFE, 0xFE, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0xFE, 0xFE, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xFC, 0xFC, 0x00, 0x00, + 0xC6, 0xC6, 0xCC, 0xCC, 0xF8, 0xF8, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, + 0x46, 0x46, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0xC0, 0xC0, 0xC0, 0xC0, 0x7E, 0x7E, 0x00, 0x00, 0xC6, 0xC6, 0xEE, 0xEE, + 0xD6, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x82, 0x82, 0x00, 0x00, + 0xFC, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, + 0x82, 0x82, 0x00, 0x00, 0x7C, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, + 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x7C, 0x00, 0x00, 0x7E, 0x7E, 0xC6, 0xC6, + 0xC6, 0xC6, 0xC6, 0xC6, 0xFC, 0xFC, 0xC0, 0xC0, 0x40, 0x40, 0x00, 0x00, + 0x7E, 0x7E, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x7E, 0x06, 0x06, + 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xF8, 0xF8, + 0xC6, 0xC6, 0xC6, 0xC6, 0x46, 0x46, 0x00, 0x00, 0x7E, 0x7E, 0xC0, 0xC0, + 0xC0, 0xC0, 0x7C, 0x7C, 0x06, 0x06, 0x06, 0x06, 0xFC, 0xFC, 0x00, 0x00, + 0xFE, 0xFE, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x08, 0x08, 0x00, 0x00, 0x46, 0x46, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, + 0xC6, 0xC6, 0xC6, 0xC6, 0xFC, 0xFC, 0x00, 0x00, 0x82, 0x82, 0xC6, 0xC6, + 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x6C, 0x10, 0x10, 0x00, 0x00, + 0x82, 0x82, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xEE, 0xEE, + 0x44, 0x44, 0x00, 0x00, 0xC6, 0xC6, 0xEE, 0xEE, 0x6C, 0x6C, 0x38, 0x38, + 0x6C, 0x6C, 0xEE, 0xEE, 0xC6, 0xC6, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, + 0xC6, 0xC6, 0x7E, 0x7E, 0x0C, 0x0C, 0x18, 0x18, 0x30, 0x30, 0x00, 0x00, + 0xFE, 0xFE, 0x0E, 0x0E, 0x1C, 0x1C, 0x38, 0x38, 0x70, 0x70, 0xE0, 0xE0, + 0xFE, 0xFE, 0x00, 0x00, 0x82, 0x82, 0x44, 0x44, 0x28, 0x28, 0x10, 0x10, + 0x28, 0x28, 0x44, 0x44, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, + 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x08, 0x14, 0x14, 0x22, 0x22, 0x41, 0x41, 0x80, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x24, 0x24, 0x24, 0x24, 0x42, 0x42, + 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x14, 0x14, + 0x24, 0x24, 0x44, 0x44, 0x87, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x03, 0x0D, 0x0D, 0x31, 0x31, 0xC1, 0xC1, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3F, 0x3F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x90, 0x90, 0x0D, 0x0D, 0x42, 0x42, 0xA9, 0xA9, 0x04, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0xFF, 0xFF, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0, 0xFF, 0xFF, 0x7F, 0x7F, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0, 0xE0, 0xE0, 0xFF, 0xFF, + 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xC0, 0xE0, 0xE0, + 0xF0, 0xF0, 0xFF, 0xFF, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, + 0xF0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xFF, 0xFF, 0x7F, 0x7F, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, + 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x3F, 0x3F, 0x7F, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, + 0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x07, 0x1F, 0x1F, 0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, + 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x0F, 0x0F, 0x3F, 0x3F, + 0x7F, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x03, 0x03, 0x0F, 0x0F, 0x3F, 0x3F, 0xFF, 0xFF, 0xFE, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x07, 0x1F, 0x1F, 0xFF, 0xFF, + 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, + 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6C, 0x6C, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, + 0x00, 0x08, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x06, 0x00, 0x06, 0x00, 0xFE, + 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x7E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x06, + 0x00, 0x06, 0x00, 0x3E, 0x00, 0x06, 0x00, 0x06, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xC6, 0x00, 0xC6, 0x00, 0xC6, 0x00, 0x7E, 0x00, 0x06, 0x00, 0x06, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0xF3, 0xF3, 0xAB, 0xAB, + 0xAB, 0xAB, 0x89, 0x89, 0x04, 0x04, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0xEF, 0xEF, 0x0C, 0x0C, 0x7F, 0x7F, 0x0C, 0x0C, 0xFF, 0xFF, + 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x20, 0x20, 0x90, 0x90, + 0xD1, 0xD1, 0xD1, 0xD1, 0xD0, 0xD0, 0x90, 0x90, 0x20, 0x20, 0xC0, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0xB4, 0xF7, 0xF7, 0xE4, 0xE4, 0x44, 0x44, + 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x76, 0x55, 0x55, + 0x67, 0x67, 0x55, 0x55, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x75, 0x75, 0x45, 0x45, 0x77, 0x77, 0x15, 0x15, 0x31, 0x31, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x05, 0x05, 0x77, 0x77, 0x05, 0x05, + 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x50, 0x50, + 0x50, 0x50, 0x50, 0x50, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, + 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0xF8, 0xF8, 0xF8, 0xF8, + 0xF8, 0xF8, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x50, 0x20, 0x20, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0F, + 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, + 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0xFF, 0x00, 0xFF, + 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x00, 0x70, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +const uint16_t bgpalette[] = {RGB_BLACK, RGB_BLACK, RGB_HAWT, RGB_WHITE}; + +const uint16_t spritepalette[] = {RGB_WHITE, RGB_LIGHTGRAY, RGB_LIGHTGRAY, + RGB_BLACK, RGB_HAWT, RGB_HAWT, + RGB_HAWT, RGB_HAWT}; + +void cls(void) { + for (j = 0; j != 20; j++) + bkg[j] = 0x00U; + for (j = 0; j != 18; j++) { + set_bkg_tiles(0, j, 20, 1, bkg); + } +} + +void hideCursor(void) { + for (j = 0; j != 4; j++) { + move_sprite(j + SPRITE_ARRL_START, 0, 0); + } + move_sprite(SPRITE_ARRT_START, 0, 0); +} + +void displaySetup(void) { + DISPLAY_OFF; + set_bkg_palette(0, 1, &bgpalette[0]); + + /* Initialize the background */ + set_bkg_data(0, 92, data_font); + // set_bkg_tiles(1,0, 20, 18, bgmap); + + set_sprite_palette(0, 2, &spritepalette[0]); + + SPRITES_8x8; + + set_sprite_data(SPRITE_ARRT, 0x01U, data_barrow); + set_sprite_data(SPRITE_ARRL, 0x01U, data_larrow); + + set_sprite_tile(SPRITE_ARRT_START, SPRITE_ARRT); + for (j = 0; j != 4; j++) + set_sprite_tile(j + SPRITE_ARRL_START, SPRITE_ARRL); + + for (j = 0; j != 4; j++) + set_sprite_prop(j + SPRITE_ARRT_START, 1); + for (j = 0; j != 4; j++) + set_sprite_prop(j + SPRITE_ARRL_START, 1); + + DISPLAY_ON; + + SHOW_BKG; + SHOW_SPRITES; +} diff --git a/Source/screen/utils.h b/Source/screen/utils.h new file mode 100644 index 0000000..89ffd35 --- /dev/null +++ b/Source/screen/utils.h @@ -0,0 +1,32 @@ +#pragma once + +#include + +#define RGB_LIGHT RGB(23, 29, 31) +#define RGB_DARK RGB(0, 0, 2) +#define RGB_HAWT RGB(31, 5, 31) +#define RGB_HAWTBLU RGB(0, 15, 31) +#define SPRITE_ARRL 0x79 +#define SPRITE_ARRT 0x80 +#define SPRITE_ARRT_START 26 +#define SPRITE_ARRL_START 27 +#define SPRITE_PUFREQ_LOW 1 + +void cls(void); +void hideCursor(void); +void displaySetup(void); + +extern uint8_t bkg[20]; +extern uint8_t currentScreen; + +// TODO: generate from png +extern const uint8_t data_barrow[16]; + +// TODO: generate from png +extern const uint8_t data_larrow[16]; + +// TODO: generate from png +extern const uint8_t data_font[1472]; + +extern const uint16_t bgpalette[4]; +extern const uint16_t spritepalette[8]; diff --git a/Source/synth/common.c b/Source/synth/common.c new file mode 100644 index 0000000..a881aba --- /dev/null +++ b/Source/synth/common.c @@ -0,0 +1,163 @@ +#include "common.h" +#include "../io/midi.h" +#include "../mGB.h" +#include "wav.h" + +const uint16_t freq[72] = { + 44, 156, 262, 363, 457, 547, 631, 710, 786, 854, 923, 986, + 1046, 1102, 1155, 1205, 1253, 1297, 1339, 1379, 1417, 1452, 1486, 1517, + 1546, 1575, 1602, 1627, 1650, 1673, 1694, 1714, 1732, 1750, 1767, 1783, + 1798, 1812, 1825, 1837, 1849, 1860, 1871, 1881, 1890, 1899, 1907, 1915, + 1923, 1930, 1936, 1943, 1949, 1954, 1959, 1964, 1969, 1974, 1978, 1982, + 1985, 1988, 1992, 1995, 1998, 2001, 2004, 2006, 2009, 2011, 2013, 2015}; + +note_status_t noteStatus[4]; + +uint16_t currentFreq; + +uint16_t currentFreqData[4]; + +bool pbWheelActive[4] = {0x00, 0x00, 0x00, 0x00}; +uint8_t pbWheelIn[4] = {PBWHEEL_CENTER, PBWHEEL_CENTER, PBWHEEL_CENTER, + PBWHEEL_CENTER}; +uint8_t pbWheelInLast[4] = {PBWHEEL_CENTER, PBWHEEL_CENTER, PBWHEEL_CENTER, + PBWHEEL_CENTER}; +uint8_t pbRange[4] = {2, 2, 2, 12}; + +pb_note_range pbNoteRange[4]; + +// Vibrato +uint8_t vibratoPosition[4] = {0, 0, 0, 0}; +uint8_t vibratoSpeed[4] = {1, 1, 1, 1}; +uint8_t vibratoDepth[4] = {0, 0, 0, 0}; +bool vibratoSlope[4] = {0, 0, 0, 0}; +uint8_t vibratoTimer[4]; + +// Pan +uint8_t outputSwitch[4] = {0x01, 0x02, 0x40, 0x80}; +uint8_t outputSwitchValue[4] = {3, 3, 3, 3}; + +void setPitchBendFrequencyOffset(uint8_t synth) { + uint16_t freqRange; + uint16_t f = freq[noteStatus[synth].note]; + systemIdle = 0; + if (pbWheelIn[synth] & PBWHEEL_CENTER) { + freqRange = freq[pbNoteRange[synth].high]; + currentFreq = (uint16_t)(pbWheelIn[synth] - 0x7F); + currentFreq <<= 6; + currentFreq /= 128; + currentFreq = currentFreq * (freqRange - f); + currentFreq = f + (currentFreq >> 6); + } else { + freqRange = freq[pbNoteRange[synth].low]; + currentFreq = (uint16_t)(PBWHEEL_CENTER - pbWheelIn[synth]); + currentFreq <<= 6; + currentFreq /= 128; + currentFreq = currentFreq * (f - freqRange); + currentFreq = f - (currentFreq >> 6); + } + switch (synth) { + case PU1: + rAUD1HIGH = (currentFreq >> 8U); + rAUD1LOW = currentFreq; + currentFreqData[synth] = currentFreq; + break; + case PU2: + rAUD2HIGH = (currentFreq >> 8U); + rAUD2LOW = currentFreq; + currentFreqData[synth] = currentFreq; + break; + default: + rAUD3HIGH = (currentFreq >> 8U); + rAUD3LOW = currentFreq; + currentFreqData[synth] = currentFreq; + } +} + +void addVibrato(uint8_t synth) { + if (vibratoDepth[synth]) { + currentFreq = currentFreqData[synth] + vibratoPosition[synth]; + pbWheelInLast[synth] = PBWHEEL_CENTER; + if (synth == PU1) { + rAUD1HIGH = (currentFreq >> 8U); + rAUD1LOW = currentFreq; + } else if (synth == PU2) { + rAUD2HIGH = (currentFreq >> 8U); + rAUD2LOW = currentFreq; + } else if (synth == WAV) { + rAUD3HIGH = (currentFreq >> 8U); + rAUD3LOW = currentFreq; + } else { + rAUD4POLY = currentFreq; + } + } +} + +void updateVibratoPosition(uint8_t synth) { + if (vibratoTimer[synth] == vibratoSpeed[synth]) { + vibratoTimer[synth] = 0x00; + if (vibratoSlope[synth] && vibratoPosition[synth] < vibratoDepth[synth]) { + vibratoPosition[synth] += 1; + } else { + vibratoSlope[synth] = 0; + if (vibratoPosition[synth]) { + vibratoPosition[synth] -= 1; + } else { + vibratoSlope[synth] = 1; + } + } + addVibrato(synth); + } + vibratoTimer[synth]++; +} + +void updateSynths(void) { + enable_interrupts(); + + if (vibratoDepth[PU1]) + updateVibratoPosition(PU1); + if (vibratoDepth[PU2]) + updateVibratoPosition(PU2); + if (vibratoDepth[WAV]) + updateVibratoPosition(WAV); + if (vibratoDepth[NOI]) + updateVibratoPosition(NOI); + + updateWavSweep(); +} + +inline void setOutputSwitch(void) { + rAUDTERM = + outputSwitch[0] + outputSwitch[1] + outputSwitch[2] + outputSwitch[3]; +} + +void setOutputPanBySynth(uint8_t synth, uint8_t value) { + outputSwitchValue[synth] = value; + + if (value == 3U) { + value = 0x11 << synth; + } else if (value == 2U) { + value = 0x10 << synth; + } else if (value == 1U) { + value = 0x01 << synth; + } else { + value = 0x00; + } + outputSwitch[synth] = value; + setOutputSwitch(); +} + +void setOutputPan(uint8_t synth, uint8_t value) { + if (value > 96U) { + value = 0x10U << synth; + outputSwitchValue[synth] = 2; + } else if (value > 32U) { + value = 0x11U << synth; + outputSwitchValue[synth] = 3; + } else { + value = 0x01U << synth; + outputSwitchValue[synth] = 1; + } + outputSwitch[synth] = value; + setOutputSwitch(); +} diff --git a/Source/synth/common.h b/Source/synth/common.h new file mode 100644 index 0000000..08bc1c1 --- /dev/null +++ b/Source/synth/common.h @@ -0,0 +1,54 @@ +#pragma once + +#include +#include + +#define PU1 0 +#define PU2 1 +#define WAV 2 +#define NOI 3 + +#define PBWHEEL_CENTER 0x80 + +extern const uint16_t freq[72]; + +typedef struct note_status_t { + bool active; + uint8_t note; +} note_status_t; + +extern note_status_t noteStatus[4]; + +// temp holder of current freq data, can be for any synth +extern uint16_t currentFreq; + +extern uint16_t currentFreqData[4]; + +// Pitch wheel +extern bool pbWheelActive[4]; +extern uint8_t pbWheelIn[4]; +extern uint8_t pbWheelInLast[4]; +extern uint8_t pbRange[4]; + +typedef struct pb_note_range { + uint8_t low; + uint8_t high; +} pb_note_range; + +extern pb_note_range pbNoteRange[4]; + +// Vibrato +extern uint8_t vibratoPosition[4]; +extern uint8_t vibratoSpeed[4]; +extern uint8_t vibratoDepth[4]; +extern bool vibratoSlope[4]; +extern uint8_t vibratoTimer[4]; + +// Pan +extern uint8_t outputSwitch[4]; +extern uint8_t outputSwitchValue[4]; + +void updateSynths(void); +void setOutputPanBySynth(uint8_t synth, uint8_t value); +void setOutputPan(uint8_t synth, uint8_t value); +void setPitchBendFrequencyOffset(uint8_t synth); diff --git a/Source/synth/data.c b/Source/synth/data.c new file mode 100644 index 0000000..191d82f --- /dev/null +++ b/Source/synth/data.c @@ -0,0 +1,135 @@ +#include "data.h" +#include "common.h" +#include "noi.h" +#include "pulse.h" +#include "wav.h" + +uint8_t dataSet[28] = { + 0x02, // 0 Transpose 0 - 6 + 0x00, // 1 Shape 0 - 3 + 0x06, // 2 Envelope 0 - F + 0x00, // 3 Sweep 0 - F + 0x02, // 4 PB Range 0 - 12 + 0x00, // 5 Sustain 0 - 1 + 0x03, // 6 Pan 0 - 3 + + 0x02, // 7 Transpose 0 - 6 + 0x00, // 8 Shape 0 - 3 + 0x06, // 9 Envelope 0 - F + 0x02, // 10 PB Range 0 - 12 + 0x00, // 11 Sustain 0 - 1 + 0x03, // 12 Pan 0 - 3 + + 0x02, // 13 Transpose 0 - 6 + 0x00, // 14 Shape 0 - F + 0x00, // 15 Offset 0 - F + 0x00, // 16 Sweep 0 - F + 0x02, // 17 PB Range 0 - 12 + 0x00, // 18 Sustain 0 - 1 + 0x03, // 19 Pan 0 - 3 + + 0x02, // 20 Transpose 0 - 6 + 0x06, // 21 Env 0 - F + 0x00, // 22 Sustain 0 - 1 + 0x03, // 23 Pan 0 - 3 + + 0x00, // 24 Save 0 + 0x00, // 25 Save 1 + 0x00, // 26 Save 2 + 0x00, // 27 Save 3 +}; + +uint8_t dataSetSnap[28]; + +bool parameterLock[24]; + +void updateValueSynth(Parameter p) { + switch (p) { + case PU1_Transpose: + pu1State.octave = dataSet[p]; + pu1State.octave = (pu1State.octave - 2U) * 12U; + break; + case PU1_Shape: + rAUD1LEN = ((dataSet[p] << 3) << 3) | 7; + break; + case PU1_Envelope: + pu1State.envelope = dataSet[p]; + break; + case PU1_Sweep: + NR10_REG = dataSet[p]; + break; + case PU1_PBRange: + pbRange[0] = dataSet[p]; + break; + case PU1_Sustain: + pu1State.sus = dataSet[p]; + if (!dataSet[p] && !noteStatus[PU1].active) + rAUD1ENV = 0U; + break; + case PU1_Pan: + setOutputPanBySynth(0U, dataSet[p]); + break; + case PU2_Transpose: + pu2State.octave = dataSet[p]; + pu2State.octave = (pu2State.octave - 2U) * 12U; + break; + case PU2_Shape: + NR21_REG = ((dataSet[p] << 3) << 3) | 7; + break; + case PU2_Envelope: + pu2State.envelope = dataSet[p]; + break; + case PU2_PBRange: + pbRange[PU2] = dataSet[p]; + break; + case PU2_Sustain: + pu2State.sus = dataSet[p]; + if (!dataSet[p] && !noteStatus[PU2].active) + rAUD2ENV = 0U; + break; + case PU2_Pan: + setOutputPanBySynth(PU2, dataSet[p]); + break; + case WAV_Transpose: + wavOct = dataSet[p]; + wavOct = (wavOct - 2U) * 12U; + break; + case WAV_Shape: + wavDataOffset = (dataSet[p] << 4) + dataSet[WAV_Offset]; + break; + case WAV_Offset: + wavDataOffset = (dataSet[WAV_Shape] << 4) + dataSet[p]; + break; + case WAV_Sweep: + wavSweepSpeed = dataSet[p]; + break; + case WAV_PBRange: + pbRange[WAV] = dataSet[p]; + break; + case WAV_Sustain: + wavSus = dataSet[p]; + if (!dataSet[p] && !noteStatus[WAV].active) + rAUD3LEVEL = 0U; + break; + case WAV_Pan: + setOutputPanBySynth(2, dataSet[p]); + break; + case NOI_Transpose: + noiOct = dataSet[p]; + noiOct = (noiOct - 2U) * 12U; + break; + case NOI_Env: + noiEnv = dataSet[p]; + break; + case NOI_Sustain: + noiSus = dataSet[p]; + if (!dataSet[p] && !noteStatus[NOI].active) + rAUD4ENV = 0U; + break; + case NOI_Pan: + setOutputPanBySynth(NOI, dataSet[p]); + break; + default: + break; + } +} diff --git a/Source/synth/data.h b/Source/synth/data.h new file mode 100644 index 0000000..a8b95e6 --- /dev/null +++ b/Source/synth/data.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +typedef enum Parameter { + PU1_Transpose = 0, + PU1_Shape = 1, + PU1_Envelope = 2, + PU1_Sweep = 3, + PU1_PBRange = 4, + PU1_Sustain = 5, + PU1_Pan = 6, + + PU2_Transpose = 7, + PU2_Shape = 8, + PU2_Envelope = 9, + PU2_PBRange = 10, + PU2_Sustain = 11, + PU2_Pan = 12, + + WAV_Transpose = 13, + WAV_Shape = 14, + WAV_Offset = 15, + WAV_Sweep = 16, + WAV_PBRange = 17, + WAV_Sustain = 18, + WAV_Pan = 19, + + NOI_Transpose = 20, + NOI_Env = 21, + NOI_Sustain = 22, + NOI_Pan = 23, + + PU1_Slot = 24, + PU2_Slot = 25, + WAV_Slot = 26, + NOI_Slot = 27, +} Parameter; + +extern uint8_t dataSet[28]; + +extern uint8_t dataSetSnap[28]; + +extern bool parameterLock[24]; + +void updateValueSynth(Parameter p); diff --git a/Source/synth/noi.c b/Source/synth/noi.c new file mode 100644 index 0000000..7eb0c85 --- /dev/null +++ b/Source/synth/noi.c @@ -0,0 +1,100 @@ +#include "noi.h" +#include "../io/midi.h" +#include "../mGB.h" +#include "common.h" + +uint8_t noiFreq[72] = { + 0x94, 0x87, 0x86, 0x85, 0x84, 0x77, 0x76, 0x75, 0x74, 0x67, 0x66, 0x65, + 0x64, 0x57, 0x56, 0x55, 0x54, 0x47, 0x46, 0x45, 0x44, 0x37, 0x36, 0x35, + 0x34, 0x27, 0x26, 0x25, 0x24, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x00, + 0x9C, 0x8F, 0x8E, 0x8D, 0x8C, 0x7F, 0x7E, 0x7D, 0x7C, 0x6F, 0x6E, 0x6D, + 0x6C, 0x5F, 0x5E, 0x5D, 0x5C, 0x4F, 0x4E, 0x4D, 0x4C, 0x3F, 0x3E, 0x3D, + 0x3C, 0x2F, 0x2E, 0x2D, 0x2C, 0x1F, 0x1E, 0x1D, 0x1C, 0x0F, 0x0E, 0x08}; + +uint8_t noiEnv; +uint8_t noiMode; +bool noiSus; + +bool noiNoteOffTrigger; +int8_t noiOct; + +void updateNoi(void) { + if (pbWheelIn[NOI] != PBWHEEL_CENTER) { + if (pbWheelIn[NOI] != pbWheelInLast[NOI]) { + pbWheelInLast[NOI] = pbWheelIn[NOI]; + pbWheelActive[NOI] = true; + setPitchBendFrequencyOffsetNoise(); + } else { + pbWheelActive[NOI] = true; + } + return; + } + if (pbWheelActive[NOI]) { + pbWheelActive[NOI] = 0x00; + pbWheelInLast[NOI] = 0x80; + + uint8_t freq = noiFreq[noteStatus[NOI].note]; + + rAUD4POLY = freq; + currentFreqData[NOI] = freq; + + rAUD4LEN = 0xFF; + + // The following line is commented out in the original assembly: + // rAUD4GO = 0x80; + } +} + +void playNoteNoi(void) { + uint8_t noteIndex = addressByte - 24U + noiOct; + + if (valueByte == 0) { + // Note off + if (noteStatus[NOI].note == noteIndex) { + noteStatus[NOI].active = 0; + + if (!noiSus) { + rAUD4ENV = 0x00; + } + } + return; + } + + // Note on + noteStatus[NOI].note = noteIndex; + + // Set envelope + uint8_t envelope = ((valueByte << 1) & 0xF0) | noiEnv; + rAUD4ENV = envelope; + + // Set frequency + uint8_t freq = noiFreq[noteIndex]; + rAUD4POLY = freq; + currentFreqData[NOI] = freq; + + // Set channel control + rAUD4LEN = 0xFF; + rAUD4GO = 0x80; + + // Reset vibrato and pitch bend + vibratoPosition[NOI] = 0; + pbWheelInLast[NOI] = PBWHEEL_CENTER; + + // Set note status + noteStatus[NOI].active = true; +} + +void setPitchBendFrequencyOffsetNoise(void) { + systemIdle = 0; + if (pbWheelIn[NOI] & PBWHEEL_CENTER) { + // noteStatus[NOI].note = noteStatus[NOI].note; + currentFreq = noiFreq[noteStatus[NOI].note + + ((pbWheelIn[NOI] - PBWHEEL_CENTER) >> 3)]; + } else { + // noteStatus[NOI].note = noteStatus[NOI].note; + currentFreq = noiFreq[noteStatus[NOI].note - + ((PBWHEEL_CENTER - pbWheelIn[NOI]) >> 3)]; + } + rAUD4POLY = currentFreq; + currentFreqData[NOI] = currentFreq; +} diff --git a/Source/synth/noi.h b/Source/synth/noi.h new file mode 100644 index 0000000..ce5149e --- /dev/null +++ b/Source/synth/noi.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +extern uint8_t noiFreq[72]; +extern uint8_t noiEnv; +extern uint8_t noiMode; +extern bool noiSus; + +extern bool noiNoteOffTrigger; +extern int8_t noiOct; + +void updateNoi(void); +void setPitchBendFrequencyOffsetNoise(void); diff --git a/Source/synth/poly.c b/Source/synth/poly.c new file mode 100644 index 0000000..e3bad56 --- /dev/null +++ b/Source/synth/poly.c @@ -0,0 +1,46 @@ +#include "poly.h" +#include "../io/midi.h" +#include "pulse.h" +#include "wav.h" + +uint8_t polyVoiceSelect; +uint8_t polyNoteState[3]; + +void playNotePoly(void) { + uint8_t note = addressByte; + uint8_t velocity = valueByte; + + if (velocity == 0) { + // Note off + if (polyNoteState[0] == note) { + playNotePu1(); + } + if (polyNoteState[1] == note) { + playNotePu2(); + } + if (polyNoteState[2] == note) { + playNoteWav(); + } + } else { + // Note on + polyVoiceSelect++; + if (polyVoiceSelect >= 3) { + polyVoiceSelect = 0; + } + + switch (polyVoiceSelect) { + case 0: + polyNoteState[0] = note; + playNotePu1(); + break; + case 1: + polyNoteState[1] = note; + playNotePu2(); + break; + case 2: + polyNoteState[2] = note; + playNoteWav(); + break; + } + } +} diff --git a/Source/synth/poly.h b/Source/synth/poly.h new file mode 100644 index 0000000..e37d6ce --- /dev/null +++ b/Source/synth/poly.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +extern uint8_t polyVoiceSelect; +extern uint8_t polyNoteState[3]; + +void playNotePoly(void); diff --git a/Source/synth/pulse.c b/Source/synth/pulse.c new file mode 100644 index 0000000..b0419fa --- /dev/null +++ b/Source/synth/pulse.c @@ -0,0 +1,107 @@ +#include "pulse.h" +#include "../io/midi.h" +#include "common.h" + +pulse_state pu1State = {.retrig = AUDHIGH_RESTART}; + +pulse_state pu2State = {.retrig = AUDHIGH_RESTART}; + +inline void updatePulse(uint8_t synth, pulse_state *state, uint8_t *rLOW, + uint8_t *rHIGH, uint8_t *rENV) { + if (state->noteOffTrigger) { + *rENV = 0x00; + state->noteOffTrigger = false; + return; + } + + if (pbWheelIn[synth] != PBWHEEL_CENTER) { + if (pbWheelIn[synth] != pbWheelInLast[synth]) { + pbWheelInLast[synth] = pbWheelIn[synth]; + pbWheelActive[synth] = true; + setPitchBendFrequencyOffset(synth); + } else { + pbWheelActive[synth] = true; + } + return; + } + + if (pbWheelActive[synth]) { + pbWheelActive[synth] = false; + pbWheelInLast[synth] = PBWHEEL_CENTER; + + const uint16_t f = currentFreqData[synth] = freq[noteStatus[synth].note]; + + *rLOW = f; + *rHIGH = f >> 8U; + } +} + +inline void playNotePulse(uint8_t synth, pulse_state *state, uint8_t *rLOW, + uint8_t *rHIGH, uint8_t *rENV) { + const uint8_t noteIndex = addressByte - 0x24 + state->octave; + + if (!valueByte) { + // Note off + if (noteStatus[synth].note == noteIndex) { + noteStatus[synth].active = false; + + if (!state->sus) { + state->noteOffTrigger = true; + } + } + return; + } + + uint8_t retrig = 0x00; + + // Note on + if (*rENV == 0x00 || valueByte != state->velocity || state->noteOffTrigger) { + retrig = AUDHIGH_RESTART; + state->velocity = valueByte; + *rENV = ((valueByte << 1) & 0xF0) | state->envelope; + } + + noteStatus[synth].note = noteIndex; + + const uint16_t f = currentFreqData[synth] = freq[noteIndex]; + + *rLOW = f; + *rHIGH = (f >> 8U) | retrig; + + vibratoPosition[synth] = 0; + pbWheelInLast[synth] = PBWHEEL_CENTER; + + pbNoteRange[synth].low = noteIndex - pbRange[synth]; + pbNoteRange[synth].high = noteIndex + pbRange[synth]; + + noteStatus[synth].active = true; + state->noteOffTrigger = false; +} + +// _asmUpdatePu1 was: 483/463 clock cycles, 100 bytes +// now: 428/407 clock cycles, 90 bytes +// = -55 cycles, 12.8% better +void updatePu1(void) { + updatePulse(PU1, &pu1State, &rAUD1LOW, &rAUD1HIGH, &rAUD1ENV); +} + +// _asmPlayNotePu1 was: 806/776 clock cycles, 180 bytes +// now: 822/802 clock cycles, 182 bytes +// = +22 cycles, 1.9% worse +void playNotePu1(void) { + playNotePulse(PU1, &pu1State, &rAUD1LOW, &rAUD1HIGH, &rAUD1ENV); +} + +// _asmUpdatePu2 was: 483/463 clock cycles, 100 bytes +// now: 431/410 clock cycles, 91 bytes +// = -52 cycles, 12.0% better +void updatePu2(void) { + updatePulse(PU2, &pu2State, &rAUD2LOW, &rAUD2HIGH, &rAUD2ENV); +} + +// _asmPlayNotePu2 was: 792/772 clock cycles, 181 bytes +// now: 822/802 clock cycles, 182 bytes +// = +30 cycles, 3.7% worse +void playNotePu2(void) { + playNotePulse(PU2, &pu2State, &rAUD2LOW, &rAUD2HIGH, &rAUD2ENV); +} diff --git a/Source/synth/pulse.h b/Source/synth/pulse.h new file mode 100644 index 0000000..912eb5a --- /dev/null +++ b/Source/synth/pulse.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +typedef struct pulse_state { + uint8_t envelope; + bool sus; + uint8_t retrig; + uint8_t velocity; + bool noteOffTrigger; + int8_t octave; +} pulse_state; + +extern pulse_state pu1State; + +extern pulse_state pu2State; + +void updatePu1(void); +void playNotePu1(void); + +void updatePu2(void); +void playNotePu2(void); diff --git a/Source/synth/wav.c b/Source/synth/wav.c new file mode 100644 index 0000000..6f8d453 --- /dev/null +++ b/Source/synth/wav.c @@ -0,0 +1,215 @@ +#include "wav.h" +#include "../io/midi.h" +#include "../mGB.h" +#include "common.h" +#include +#include + +uint16_t wavCurrentFreq; + +int8_t wavOct; +bool wavNoteOffTrigger; +bool wavSus; + +// current wav offset +uint8_t wavDataOffset; +// previous wav offset +uint8_t wavShapeLast; + +// manual sweep +uint8_t wavSweepSpeed; +uint16_t counterWav; +bool cueWavSweep; +uint8_t wavStepCounter; +uint8_t counterWavStart; +// initial waveforms +const uint8_t wavData[256] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + + 0x22, 0x55, 0x77, 0xAA, 0xBB, 0xDD, 0xEE, 0xFF, + 0xEE, 0xDD, 0xBB, 0xAA, 0x77, 0x66, 0x44, 0x00, + + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, + 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, + + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, + + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + + 0x16, 0x13, 0xAA, 0xB3, 0x25, 0x81, 0xE8, 0x2A, + 0x1B, 0xEB, 0xF8, 0x85, 0xE1, 0x28, 0xFF, 0xA4, + + 0x34, 0x09, 0x91, 0xA7, 0x63, 0xB8, 0x99, 0xA1, + 0x3F, 0xE4, 0xD0, 0x61, 0x66, 0x73, 0x59, 0x7C, + + 0x86, 0x04, 0x2F, 0xAC, 0x85, 0x17, 0xD6, 0xA1, + 0x03, 0xCF, 0x27, 0xE4, 0xF8, 0x27, 0x89, 0x2C, + + 0x30, 0x1B, 0xD4, 0x93, 0xD3, 0x6E, 0x35, 0x13, + 0x53, 0x05, 0x75, 0xB9, 0x79, 0xCF, 0x36, 0x00, + + 0xD4, 0x2C, 0xC6, 0x4E, 0x2C, 0x12, 0xE2, 0x15, + 0x8B, 0xAF, 0x3D, 0xEF, 0x6E, 0xF1, 0xBF, 0xD9, + + 0x43, 0x17, 0x2B, 0xF3, 0x12, 0xC2, 0xCB, 0x8C, + 0x3B, 0x43, 0xF2, 0xDF, 0x5D, 0xF9, 0xEF, 0x31, + + 0x6D, 0x46, 0xF6, 0x7A, 0xEE, 0x17, 0x35, 0xF4, + 0xDA, 0xFE, 0x7C, 0x28, 0xB8, 0x55, 0x12, 0x57, + + 0xFF, 0x82, 0xBB, 0x85, 0xEF, 0xD4, 0x7C, 0xA1, + 0x05, 0xB4, 0xFF, 0xC1, 0x95, 0x27, 0x30, 0x03}; + +// _asmUpdateWav was: 653/628 clock cycles, 134 bytes +// now: 684/658 clock cycles, 144 bytes +// = +31 cycles, 4.7% worse +void updateWav(void) { + + if (wavNoteOffTrigger) { + // Turn off wave channel + rAUD3LEVEL = 0; + wavNoteOffTrigger = false; + return; + } + + // Check if wave data needs to be updated + if (wavShapeLast != wavDataOffset) { + loadWav(wavDataOffset); + + pbWheelInLast[WAV] = PBWHEEL_CENTER; + return; + } + + if (pbWheelIn[WAV] != PBWHEEL_CENTER) { + if (pbWheelIn[WAV] != pbWheelInLast[WAV]) { + pbWheelInLast[WAV] = pbWheelIn[WAV]; + pbWheelActive[WAV] = true; + setPitchBendFrequencyOffset(WAV); + wavCurrentFreq = currentFreqData[WAV]; + return; + } else { + pbWheelActive[WAV] = true; + } + return; + } + + if (pbWheelActive[WAV]) { + // Reset pitch bend wheel + pbWheelInLast[WAV] = PBWHEEL_CENTER; + + wavCurrentFreq = freq[noteStatus[WAV].note]; + + currentFreqData[WAV] = wavCurrentFreq; + rAUD3LOW = wavCurrentFreq; + rAUD3HIGH = (wavCurrentFreq >> 8U) & ~AUDHIGH_RESTART; + } +} + +// _asmPlayNoteWav was: 842/827 clock cycles, 191 bytes +// now: 922/907 clock cycles, 205 bytes +// = +80 cycles, 9.5% worse +void playNoteWav(void) { + const uint8_t noteIndex = addressByte - WAV_OCTAVE_OFFSET + wavOct; + + if (!valueByte) { + // Note off + if (noteStatus[WAV].note == noteIndex) { + noteStatus[WAV].active = false; + + if (!wavSus) { + wavNoteOffTrigger = true; + } + } + return; + } + + // Note on + noteStatus[WAV].note = noteIndex; + + // channel volume louder = smaller value: + const uint8_t noteVelocity = valueByte & AUD3LEVEL_MASK; + if (noteVelocity == 0x60) { + rAUD3LEVEL = AUD3LEVEL_100; + } else if (noteVelocity == 0x40) { + rAUD3LEVEL = AUD3LEVEL_50; + } else { + rAUD3LEVEL = AUD3LEVEL_25; + } + + currentFreqData[WAV] = wavCurrentFreq = freq[noteIndex]; + + // rAUD3HIGH = 0x00; // was in ASM, probably not needed? + + rAUD3LOW = wavCurrentFreq; + rAUD3HIGH = wavCurrentFreq >> 8U; + + // Reset various counters and flags + vibratoPosition[WAV] = 0; + wavStepCounter = 0; + counterWav = 0; + counterWavStart = 0; + pbWheelInLast[WAV] = PBWHEEL_CENTER; + + // Set pitch bend range + pbNoteRange[WAV].low = noteIndex - pbRange[WAV]; + pbNoteRange[WAV].high = noteIndex + pbRange[WAV]; + + noteStatus[WAV].active = true; + cueWavSweep = 1; + wavNoteOffTrigger = false; +} + +/** Manual sweep on the WAV channel */ +void updateWavSweep(void) { + if (wavSweepSpeed) { + if (!wavStepCounter) { + counterWav++; + if (wavSweepSpeed && cueWavSweep) { + wavCurrentFreq = currentFreqData[WAV] - (counterWav << wavSweepSpeed); + if (!(wavSweepSpeed >> 3U) && (wavCurrentFreq > 0x898U)) { + wavCurrentFreq = 0U; + cueWavSweep = 0U; + } + rAUD3HIGH = wavCurrentFreq >> 8U; + rAUD3LOW = wavCurrentFreq; + } + } + wavStepCounter++; + if (wavStepCounter == 0x02U) + wavStepCounter = 0; + } +} + +// _asmLoadWav was: 697 clock cycles, 159 bytes +// now: 235 clock cycles, 53 bytes +// + _memcpy: 247/227 clock cycles, 44 bytes +// = total: 482/462 clock cycles, 97 bytes +// = -215 cycles, 44% better +void loadWav(uint8_t offset) { + wavShapeLast = offset; + + // Turn off wave channel + rAUD3ENA = AUDENA_OFF; + + memcpy(&_AUD3WAVERAM, &wavData[offset], 16U); + + // Turn on wave channel + rAUD3ENA = AUDENA_ON; + + // Set wave frequency registers + rAUD3LOW = wavCurrentFreq; + rAUD3HIGH = (wavCurrentFreq >> 8U) | AUDHIGH_RESTART; + + systemIdle = 0; +} diff --git a/Source/synth/wav.h b/Source/synth/wav.h new file mode 100644 index 0000000..a086a21 --- /dev/null +++ b/Source/synth/wav.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +// NR32_REG (0xFF1C) volume ctrl: +// 0b-VV----- +#define AUD3LEVEL_25 0b01100000 +#define AUD3LEVEL_50 0b01000000 +#define AUD3LEVEL_100 0b0100000 + +// The mask which represents the Chan 3 output level +#define AUD3LEVEL_MASK 0b01100000 + +// The WAV oscilator is 2 octaves higher +#define WAV_OCTAVE_OFFSET 24U + +extern uint16_t wavCurrentFreq; + +extern int8_t wavOct; +extern bool wavNoteOffTrigger; +extern bool wavSus; + +// current wav offset +extern uint8_t wavDataOffset; + +// previous wav offset +extern uint8_t wavShapeLast; + +// manual sweep +extern uint8_t wavSweepSpeed; +extern uint16_t counterWav; +extern bool cueWavSweep; +extern uint8_t wavStepCounter; +extern uint8_t counterWavStart; + +// initial waveforms +extern const uint8_t wavData[256]; + +void updateWav(void); +void loadWav(uint8_t offset); +void playNoteWav(void); +void updateWavSweep(void);