gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit f1c1c824016c901e7bb0b41c7ff317895b58e1d8 parent 9efcb69e38c22ae08bb570e604ad41c8b2c48c35 Author: Toxa <untoxa@mail.ru> Date: Wed, 20 Jan 2021 17:15:55 +0300 Merge branch 'develop' of https://github.com/Zal0/gbdk-2020 into develop Diffstat:
| A | gbdk-lib/examples/gb/sound/readme.md | 13 | +++++++++++++ |
| M | gbdk-lib/examples/gb/sound/sound.c | 1050 | ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
2 files changed, 646 insertions(+), 417 deletions(-)
diff --git a/gbdk-lib/examples/gb/sound/readme.md b/gbdk-lib/examples/gb/sound/readme.md @@ -0,0 +1,13 @@ +Updated version of the original Sound Sample that merges +in changes made at: https://github.com/Zal0/GBSoundDemo + +Keys: +- Select: change current channel menu +- Start: play current Sound +- Start + A: play a song +- Arrows: navigate throught options +- Arrows + A: Increments/Decrements current value by 10 +- Arrows + B: Increments/Decrements current value by 100 +- Arrows + A + B: set Min/Max value to current option +- Select + A: Dump Registers + diff --git a/gbdk-lib/examples/gb/sound/sound.c b/gbdk-lib/examples/gb/sound/sound.c @@ -2,7 +2,7 @@ #include <stdio.h> #include <gb/console.h> -#define ARROW_CHAR 3 +#define ARROW_CHAR '>' #define SPACE_CHAR ' ' #define ARROW_X 0 @@ -19,6 +19,45 @@ #define NB_MODES 5 +#define UNSIGNED 0 + +UBYTE previous_keys = 0; +BYTE keys = 0; +#define UPDATE_KEYS() previous_keys = keys; keys = joypad() +#define KEY_PRESSED(K) (keys & (K)) +#define KEY_TICKED(K) ((keys & (K)) && !(previous_keys & (K))) + +void show_register_channel(UBYTE mode); + +void clss() { + UINT8 i = 0; + for(i = 0; i < 18; ++i) { + gotoxy(0, i); + printf(" "); + } +} + +void print(const char* str) { + printf("%s", str); +} + +const char hex[] = "0123456789ABCDEF"; +void printn(UWORD n, UINT8 base, UINT8 sign) { + (void) sign; + if(base == 16u) { + printf("%c", hex[0x000Fu & (n >> 4u)]); + printf("%c", hex[0x000Fu & (n)]); + } else { + printf("%d", n); + } +} + + +void println(UWORD n, UINT8 base, UINT8 sign) { + printn(n, base, sign); + printf("\n"); +} + enum notes { C0, Cd0, D0, Dd0, E0, F0, Fd0, G0, Gd0, A0, Ad0, B0, C1, Cd1, D1, Dd1, E1, F1, Fd1, G1, Gd1, A1, Ad1, B1, @@ -133,250 +172,365 @@ const struct Params *params_array[] = { params_4, }; -struct Params *params; +const struct Params *params; struct SoundReg { struct { - /* 0xFF10 */ - UBYTE sweepShifts : 3; - UBYTE sweepMode : 1; - UBYTE sweepTime : 3; - UBYTE unused_1 : 1; - - /* 0xFF11 */ - UBYTE soundLength : 6; - UBYTE patternDuty : 2; - - /* 0xFF12 */ - UBYTE envNbSweep : 3; - UBYTE envMode : 1; - UBYTE envInitialValue : 4; - - /* 0xFF13 */ - UBYTE frequencyLow; - - /* 0xFF14 */ - UBYTE frequencyHigh : 3; - UBYTE unused_2 : 3; - UBYTE counter_ConsSel : 1; - UBYTE restart : 1; + //NR10 0xFF10 + UINT16 sweepShifts ;//: 3; + UINT16 sweepMode ;//: 1; + UINT16 sweepTime ;//: 3; + UINT16 unused_1 ;//: 1; + + //NR11 0xFF11 + UINT16 soundLength ;//: 6; + UINT16 patternDuty ;//: 2; + + //NR12 0xFF12 + UINT16 envNbSweep ;//: 3; + UINT16 envMode ;//: 1; + UINT16 envInitialValue ;//: 4; + + //NR13 0xFF13 + UINT16 frequencyLow; + + //NR14 0xFF14 + UINT16 frequencyHigh ;//: 3; + UINT16 unused_2 ;//: 3; + UINT16 counter_ConsSel ;//: 1; + UINT16 restart ;//: 1; } mode1; struct { - /* 0xFF15 */ - UBYTE unused_1; - - /* 0xFF16 */ - UBYTE soundLength : 6; - UBYTE patternDuty : 2; - - /* 0xFF17 */ - UBYTE envNbStep : 3; - UBYTE envMode : 1; - UBYTE envInitialValue : 4; - - /* 0xFF18 */ - UBYTE frequencyLow; - - /* 0xFF19 */ - UBYTE frequencyHigh : 3; - UBYTE unused_2 : 3; - UBYTE counter_ConsSel : 1; - UBYTE restart : 1; + //NR20 0xFF15 + UINT16 unused_1; + + //NR21 0xFF16 + UINT16 soundLength ;//: 6; + UINT16 patternDuty ;//: 2; + + //NR22 0xFF17 + UINT16 envNbStep ;//: 3; + UINT16 envMode ;//: 1; + UINT16 envInitialValue ;//: 4; + + //NR23 0xFF18 + UINT16 frequencyLow; + + //NR24 0xFF19 + UINT16 frequencyHigh ;//: 3; + UINT16 unused_2 ;//: 3; + UINT16 counter_ConsSel ;//: 1; + UINT16 restart ;//: 1; } mode2; struct { - /* 0xFF1A */ - UBYTE unused_1 : 7; - UBYTE on_Off : 1; - - /* 0xFF1B */ - UBYTE soundLength; - - /* 0xFF1C */ - UBYTE unused_2 : 5; - UBYTE selOutputLevel : 2; - UBYTE unused_3 : 1; - - /* 0xFF1D */ - UBYTE frequencyLow; - - /* 0xFF1E */ - UBYTE frequencyHigh : 3; - UBYTE unused_4 : 3; - UBYTE counter_ConsSel : 1; - UBYTE restart : 1; + //NR30 0xFF1A + UINT16 unused_1 ;//: 7; + UINT16 on_Off ;//: 1; + + //NR31 0xFF1B + UINT16 soundLength; + + //NR32 0xFF1C + UINT16 unused_2 ;//: 5; + UINT16 selOutputLevel ;//: 2; + UINT16 unused_3 ;//: 1; + + //NR33 0xFF1D + UINT16 frequencyLow; + + //NR34 0xFF1E + UINT16 frequencyHigh ;//: 3; + UINT16 unused_4 ;//: 3; + UINT16 counter_ConsSel ;//: 1; + UINT16 restart ;//: 1; } mode3; struct { - /* 0xFF1F */ - UBYTE unused_1; - - /* 0xFF20 */ - UBYTE soundLength : 6; - UBYTE unused_2 : 2; - - /* 0xFF21 */ - UBYTE envNbStep : 3; - UBYTE envMode : 1; - UBYTE envInitialValue : 4; - - /* 0xFF22 */ - UBYTE polyCounterDiv : 3; - UBYTE polyCounterStep : 1; - UBYTE polyCounterFreq : 4; - - /* 0xFF23 */ - UBYTE unused_3 : 6; - UBYTE counter_ConsSel : 1; - UBYTE restart : 1; + //NR40 0xFF1F + UINT16 unused_1; + + //NR41 0xFF20 + UINT16 soundLength ;//: 6; + UINT16 unused_2 ;//: 2; + + //NR42 0xFF21 + UINT16 envNbStep ;//: 3; + UINT16 envMode ;//: 1; + UINT16 envInitialValue ;//: 4; + + //NR43 0xFF22 + UINT16 polyCounterDiv ;//: 3; + UINT16 polyCounterStep ;//: 1; + UINT16 polyCounterFreq ;//: 4; + + //NR44 0xFF23 + UINT16 unused_3 ;//: 6; + UINT16 counter_ConsSel ;//: 1; + UINT16 restart ;//: 1; } mode4; struct { - /* 0xFF24 */ - UBYTE SO1_OutputLevel : 3; - UBYTE Vin_SO1 : 1; - UBYTE SO2_OutputLevel : 3; - UBYTE Vin_SO2 : 1; - - /* 0xFF25 */ - UBYTE Sound1_To_SO1 : 1; - UBYTE Sound2_To_SO1 : 1; - UBYTE Sound3_To_SO1 : 1; - UBYTE Sound4_To_SO1 : 1; - UBYTE Sound1_To_SO2 : 1; - UBYTE Sound2_To_SO2 : 1; - UBYTE Sound3_To_SO2 : 1; - UBYTE Sound4_To_SO2 : 1; - - /* 0xFF26 */ - UBYTE Sound1_On_Off : 1; - UBYTE Sound2_On_Off : 1; - UBYTE Sound3_On_Off : 1; - UBYTE Sound4_On_Off : 1; - UBYTE unused_1 : 3; - UBYTE global_On_Off : 1; + // NR50 0xFF24 + UINT16 SO1_OutputLevel ;//: 3; + UINT16 Vin_SO1 ;//: 1; + UINT16 SO2_OutputLevel ;//: 3; + UINT16 Vin_SO2 ;//: 1; + + // NR51 0xFF25 + UINT16 Sound1_To_SO1 ;//: 1; + UINT16 Sound2_To_SO1 ;//: 1; + UINT16 Sound3_To_SO1 ;//: 1; + UINT16 Sound4_To_SO1 ;//: 1; + UINT16 Sound1_To_SO2 ;//: 1; + UINT16 Sound2_To_SO2 ;//: 1; + UINT16 Sound3_To_SO2 ;//: 1; + UINT16 Sound4_To_SO2 ;//: 1; + + // NR52 0xFF26 + UINT16 Sound1_On_Off ;//: 1; + UINT16 Sound2_On_Off ;//: 1; + UINT16 Sound3_On_Off ;//: 1; + UINT16 Sound4_On_Off ;//: 1; + UINT16 unused_1 ;//: 3; + UINT16 global_On_Off ;//: 1; } control; }; struct SoundReg *soundReg; +struct SoundReg s = { + { 0u, 0u, 0u, 0u, + 1, 2, + 3, 0, 4, + 0x73U, + 6, 0, 0, 0 }, + { 0, + 1, 2, + 4, 0, 8, + 0xD7U, + 6, 0, 0, 0 }, + { 0, 1, + 0, + 0, 3, 0, + 0xD6U, + 6, 0, 1, 0 }, + { 0, + 58, 0, + 1, 0, 10, + 0, 0, 0, + 0, 1, 0 }, + { 7, 0, 7, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 1 } +}; + +UBYTE NR10() { + return soundReg->mode1.sweepShifts | (soundReg->mode1.sweepMode << 3) | (soundReg->mode1.sweepTime << 4); +} + +UBYTE NR11() { + return soundReg->mode1.soundLength | (soundReg->mode1.patternDuty << 6); +} + +UBYTE NR12() { + return soundReg->mode1.envNbSweep | (soundReg->mode1.envMode << 3) | (soundReg->mode1.envInitialValue << 4); +} + +UBYTE NR13() { + return soundReg->mode1.frequencyLow; +} + +UBYTE NR14() { + return soundReg->mode1.frequencyHigh | (soundReg->mode1.counter_ConsSel << 6) | (soundReg->mode1.restart << 7); +} + +//-------------------------- +UBYTE NR21() { + return soundReg->mode2.soundLength | (soundReg->mode2.patternDuty << 6); +} + +UBYTE NR22() { + return soundReg->mode2.envNbStep | (soundReg->mode2.envMode << 3) | (soundReg->mode2.envInitialValue << 4); +} + +UBYTE NR23() { + return soundReg->mode2.frequencyLow; +} + +UBYTE NR24() { + return soundReg->mode2.frequencyHigh | (soundReg->mode2.counter_ConsSel << 6) | (soundReg->mode2.restart << 7); +} + +//------------------------------- +UBYTE NR30() { + return soundReg->mode3.on_Off << 7; +} + +UBYTE NR31() { + return soundReg->mode3.soundLength; +} + +UBYTE NR32() { + return soundReg->mode3.selOutputLevel << 5; +} + +UBYTE NR33() { + return soundReg->mode3.frequencyLow; +} + +UBYTE NR34() { + return soundReg->mode3.frequencyHigh | (soundReg->mode3.counter_ConsSel << 6) | (soundReg->mode3.restart << 7); +} + +//------------------------------- +UBYTE NR41() { + return soundReg->mode4.soundLength; +} + +UBYTE NR42() { + return soundReg->mode4.envNbStep | (soundReg->mode4.envMode << 3) | (soundReg->mode4.envInitialValue << 4); +} + +UBYTE NR43() { + return soundReg->mode4.polyCounterDiv | (soundReg->mode4.polyCounterStep << 3) | (soundReg->mode4.polyCounterFreq << 4); +} + +UBYTE NR44() { + return (soundReg->mode4.counter_ConsSel << 6) | (soundReg->mode4.restart << 7); +} + +//------------------------------- +UBYTE NR50() { + return soundReg->control.SO1_OutputLevel | (soundReg->control.Vin_SO1 << 3u) | (soundReg->control.SO2_OutputLevel << 4u) | + (soundReg->control.Vin_SO2 << 7u); +} + +UBYTE NR51() { + return soundReg->control.Sound1_To_SO1 | (soundReg->control.Sound2_To_SO1 << 1) | (soundReg->control.Sound3_To_SO1 << 2) | + (soundReg->control.Sound4_To_SO1 << 3) | (soundReg->control.Sound1_To_SO2 << 4) | (soundReg->control.Sound2_To_SO2 << 5) | + (soundReg->control.Sound3_To_SO2 << 6)| (soundReg->control.Sound4_To_SO2 << 7); +} + +UBYTE NR52() { + return soundReg->control.global_On_Off << 7; +} + +//--------------------------------------------------------------------------------- UWORD current_value(UBYTE mode, UBYTE line) { if(mode == 0) { switch(line) { - case 0: /* global_On_Off */ + case 0: // global_On_Off return soundReg->control.global_On_Off; - case 1: /* Vin_SO1 */ + case 1: // Vin_SO1 return soundReg->control.Vin_SO1; - case 2: /* Vin_SO2 */ + case 2: // Vin_SO2 return soundReg->control.Vin_SO2; - case 3: /* SO1_OutputLevel */ + case 3: // SO1_OutputLevel return soundReg->control.SO1_OutputLevel; - case 4: /* SO2_OutputLevel */ + case 4: // SO2_OutputLevel return soundReg->control.SO2_OutputLevel; } } else if(mode == 1) { switch(line) { - case 0: /* sweepTime */ + case 0: // sweepTime return soundReg->mode1.sweepTime; - case 1: /* sweepMode */ + case 1: // sweepMode return soundReg->mode1.sweepMode; - case 2: /* sweepShifts */ + case 2: // sweepShifts return soundReg->mode1.sweepShifts; - case 3: /* patternDuty */ + case 3: // patternDuty return soundReg->mode1.patternDuty; - case 4: /* soundLength */ + case 4: // soundLength return soundReg->mode1.soundLength; - case 5: /* envInitialValue */ + case 5: // envInitialValue return soundReg->mode1.envInitialValue; - case 6: /* envMode */ + case 6: // envMode return soundReg->mode1.envMode; - case 7: /* envNbSweep */ + case 7: // envNbSweep return soundReg->mode1.envNbSweep; - case 8: /* frequency */ + case 8: // frequency case FREQUENCY: - return ((UWORD)soundReg->mode1.frequencyHigh << 8) + - (UWORD)soundReg->mode1.frequencyLow; - case 9: /* counter_ConsSel */ + return (soundReg->mode1.frequencyHigh << 8) | soundReg->mode1.frequencyLow; + case 9: // counter_ConsSel return soundReg->mode1.counter_ConsSel; - case 10: /* Sound1_To_SO1 */ + case 10: // Sound1_To_SO1 return soundReg->control.Sound1_To_SO1; - case 11: /* Sound1_To_SO2 */ + case 11: // Sound1_To_SO2 return soundReg->control.Sound1_To_SO2; - case 12: /* Sound1_On_Off */ + case 12: // Sound1_On_Off return soundReg->control.Sound1_On_Off; } } else if(mode == 2) { switch(line) { - case 0: /* patternDuty */ + case 0: // patternDuty return soundReg->mode2.patternDuty; - case 1: /* soundLength */ + case 1: // soundLength return soundReg->mode2.soundLength; - case 2: /* envInitialValue */ + case 2: // envInitialValue return soundReg->mode2.envInitialValue; - case 3: /* envMode */ + case 3: // envMode return soundReg->mode2.envMode; - case 4: /* envNbStep */ + case 4: // envNbStep return soundReg->mode2.envNbStep; - case 5: /* frequency */ + case 5: // frequency case FREQUENCY: - return ((UWORD)soundReg->mode2.frequencyHigh << 8) + - (UWORD)soundReg->mode2.frequencyLow; - case 6: /* counter_ConsSel */ + return (soundReg->mode2.frequencyHigh << 8) | soundReg->mode2.frequencyLow; + case 6: // counter_ConsSel return soundReg->mode2.counter_ConsSel; - case 7: /* Sound2_To_SO1 */ + case 7: // Sound2_To_SO1 return soundReg->control.Sound2_To_SO1; - case 8: /* Sound2_To_SO2 */ + case 8: // Sound2_To_SO2 return soundReg->control.Sound2_To_SO2; - case 9: /* Sound2_On_Off */ + case 9: // Sound2_On_Off return soundReg->control.Sound2_On_Off; } } else if(mode == 3) { switch(line) { - case 0: /* on_Off */ + case 0: // on_Off return soundReg->mode3.on_Off; - case 1: /* soundLength */ + case 1: // soundLength return soundReg->mode3.soundLength; - case 2: /* selOutputLevel */ + case 2: // selOutputLevel return soundReg->mode3.selOutputLevel; - case 3: /* frequency */ + case 3: // frequency case FREQUENCY: - return ((UWORD)soundReg->mode3.frequencyHigh << 8) + - (UWORD)soundReg->mode3.frequencyLow; - case 4: /* counter_ConsSel */ + return (soundReg->mode3.frequencyHigh << 8) | soundReg->mode3.frequencyLow; + case 4: // counter_ConsSel return soundReg->mode3.counter_ConsSel; - case 5: /* Sound3_To_SO1 */ + case 5: // Sound3_To_SO1 return soundReg->control.Sound3_To_SO1; - case 6: /* Sound3_To_SO2 */ + case 6: // Sound3_To_SO2 return soundReg->control.Sound3_To_SO2; - case 7: /* Sound3_On_Off */ + case 7: // Sound3_On_Off return soundReg->control.Sound3_On_Off; } } else if(mode == 4) { switch(line) { - case 0: /* soundLength */ + case 0: // soundLength return soundReg->mode4.soundLength; - case 1: /* envInitialValue */ + case 1: // envInitialValue return soundReg->mode4.envInitialValue; - case 2: /* envMode */ + case 2: // envMode return soundReg->mode4.envMode; - case 3: /* envNbStep */ + case 3: // envNbStep return soundReg->mode4.envNbStep; - case 4: /* polyCounterFreq */ + case 4: // polyCounterFreq return soundReg->mode4.polyCounterFreq; - case 5: /* polyCounterStep */ + case 5: // polyCounterStep return soundReg->mode4.polyCounterStep; - case 6: /* polyCounterDiv */ + case 6: // polyCounterDiv return soundReg->mode4.polyCounterDiv; - case 7: /* counter_ConsSel */ + case 7: // counter_ConsSel return soundReg->mode4.counter_ConsSel; - case 8: /* Sound4_To_SO1 */ + case 8: // Sound4_To_SO1 return soundReg->control.Sound4_To_SO1; - case 9: /* Sound4_To_SO2 */ + case 9: // Sound4_To_SO2 return soundReg->control.Sound4_To_SO2; - case 10: /* Sound4_On_Off */ + case 10: // Sound4_On_Off return soundReg->control.Sound4_On_Off; } } @@ -388,32 +542,32 @@ void update_value(UBYTE mode, UBYTE line, UWORD value) if(mode == 0) { switch(line) { - case 0: /* global_On_Off */ + case 0: // global_On_Off soundReg->control.global_On_Off = value; - NR52_REG = ((UBYTE *)soundReg)[0x16]; + NR52_REG = NR52(); break; - case 1: /* Vin_SO1 */ + case 1: // Vin_SO1 soundReg->control.Vin_SO1 = value; - NR50_REG = ((UBYTE *)soundReg)[0x14]; + NR50_REG = NR50(); break; - case 2: /* Vin_SO2 */ + case 2: // Vin_SO2 soundReg->control.Vin_SO2 = value; - NR50_REG = ((UBYTE *)soundReg)[0x14]; + NR50_REG = NR50(); break; - case 3: /* SO1_OutputLevel */ + case 3: // SO1_OutputLevel soundReg->control.SO1_OutputLevel = value; - NR50_REG = ((UBYTE *)soundReg)[0x14]; + NR50_REG = NR50(); break; - case 4: /* SO2_OutputLevel */ + case 4: // SO2_OutputLevel soundReg->control.SO2_OutputLevel = value; - NR50_REG = ((UBYTE *)soundReg)[0x14]; + NR50_REG = NR50(); break; case FREQUENCY: update_value(1, FREQUENCY, value); update_value(2, FREQUENCY, value); update_value(3, FREQUENCY, value); break; - case PLAY: /* restart */ + case PLAY: // restart update_value(1, FREQUENCY, current_value(1, FREQUENCY)); update_value(2, FREQUENCY, current_value(2, FREQUENCY)); update_value(3, FREQUENCY, current_value(3, FREQUENCY)); @@ -421,10 +575,10 @@ void update_value(UBYTE mode, UBYTE line, UWORD value) soundReg->mode2.restart = value; soundReg->mode3.restart = value; soundReg->mode4.restart = value; - NR14_REG = ((UBYTE *)soundReg)[0x04]; - NR24_REG = ((UBYTE *)soundReg)[0x09]; - NR34_REG = ((UBYTE *)soundReg)[0x0E]; - NR44_REG = ((UBYTE *)soundReg)[0x13]; + NR14_REG = NR14(); + NR24_REG = NR24(); + NR34_REG = NR34(); + NR44_REG = NR44(); soundReg->mode1.restart = 0; soundReg->mode2.restart = 0; soundReg->mode3.restart = 0; @@ -434,216 +588,216 @@ void update_value(UBYTE mode, UBYTE line, UWORD value) } else if(mode == 1) { switch(line) { - case 0: /* sweepTime */ + case 0: // sweepTime soundReg->mode1.sweepTime = value; - NR10_REG = ((UBYTE *)soundReg)[0x00]; + NR10_REG = NR10(); break; - case 1: /* sweepMode */ + case 1: // sweepMode soundReg->mode1.sweepMode = value; - NR10_REG = ((UBYTE *)soundReg)[0x00]; + NR10_REG = NR10(); break; - case 2: /* sweepShifts */ + case 2: // sweepShifts soundReg->mode1.sweepShifts = value; - NR10_REG = ((UBYTE *)soundReg)[0x00]; + NR10_REG = NR10(); break; - case 3: /* patternDuty */ + case 3: // patternDuty soundReg->mode1.patternDuty = value; - NR11_REG = ((UBYTE *)soundReg)[0x01]; + NR11_REG = NR11(); break; - case 4: /* soundLength */ + case 4: // soundLength soundReg->mode1.soundLength = value; - NR11_REG = ((UBYTE *)soundReg)[0x01]; + NR11_REG = NR11(); break; - case 5: /* envInitialValue */ + case 5: // envInitialValue soundReg->mode1.envInitialValue = value; - NR12_REG = ((UBYTE *)soundReg)[0x02]; + NR12_REG = NR12(); break; - case 6: /* envMode */ + case 6: // envMode soundReg->mode1.envMode = value; - NR12_REG = ((UBYTE *)soundReg)[0x02]; + NR12_REG = NR12(); break; - case 7: /* envNbSweep */ + case 7: // envNbSweep soundReg->mode1.envNbSweep = value; - NR12_REG = ((UBYTE *)soundReg)[0x02]; + NR12_REG = NR12(); break; - case 8: /* frequency */ + case 8: // frequency case FREQUENCY: soundReg->mode1.frequencyHigh = value >> 8; - soundReg->mode1.frequencyLow = value; - NR13_REG = ((UBYTE *)soundReg)[0x03]; - NR14_REG = ((UBYTE *)soundReg)[0x04]; + soundReg->mode1.frequencyLow = 0xFF & value; + NR13_REG = NR13(); + NR14_REG = NR14(); break; - case 9: /* counter_ConsSel */ + case 9: // counter_ConsSel soundReg->mode1.counter_ConsSel = value; - NR14_REG = ((UBYTE *)soundReg)[0x04]; + NR14_REG = NR14(); break; - case 10: /* Sound1_To_SO1 */ + case 10: // Sound1_To_SO1 soundReg->control.Sound1_To_SO1 = value; - NR51_REG = ((UBYTE *)soundReg)[0x15]; + NR51_REG = NR51(); break; - case 11: /* Sound1_To_SO2 */ + case 11: // Sound1_To_SO2 soundReg->control.Sound1_To_SO2 = value; - NR51_REG = ((UBYTE *)soundReg)[0x15]; + NR51_REG = NR51(); break; - case 12: /* Sound1_On_Off */ + case 12: // Sound1_On_Off soundReg->control.Sound1_On_Off = value; - NR52_REG = ((UBYTE *)soundReg)[0x16]; + NR52_REG = NR52(); break; - case PLAY: /* restart */ + case PLAY: // restart update_value(mode, FREQUENCY, current_value(mode, FREQUENCY)); soundReg->mode1.restart = value; - NR14_REG = ((UBYTE *)soundReg)[0x04]; + NR14_REG = NR14(); soundReg->mode1.restart = 0; break; } } else if(mode == 2) { switch(line) { - case 0: /* patternDuty */ + case 0: // patternDuty soundReg->mode2.patternDuty = value; - NR21_REG = ((UBYTE *)soundReg)[0x06]; + NR21_REG = NR21(); break; - case 1: /* soundLength */ + case 1: // soundLength soundReg->mode2.soundLength = value; - NR21_REG = ((UBYTE *)soundReg)[0x06]; + NR21_REG = NR21(); break; - case 2: /* envInitialValue */ + case 2: // envInitialValue soundReg->mode2.envInitialValue = value; - NR22_REG = ((UBYTE *)soundReg)[0x07]; + NR22_REG = NR22(); break; - case 3: /* envMode */ + case 3: // envMode soundReg->mode2.envMode = value; - NR22_REG = ((UBYTE *)soundReg)[0x07]; + NR22_REG = NR22(); break; - case 4: /* envNbStep */ + case 4: // envNbStep soundReg->mode2.envNbStep = value; - NR22_REG = ((UBYTE *)soundReg)[0x07]; + NR22_REG = NR22(); break; - case 5: /* frequency */ + case 5: // frequency case FREQUENCY: soundReg->mode2.frequencyHigh = value >> 8; - soundReg->mode2.frequencyLow = value; - NR23_REG = ((UBYTE *)soundReg)[0x08]; - NR24_REG = ((UBYTE *)soundReg)[0x09]; + soundReg->mode2.frequencyLow = 0xFF & value; + NR23_REG = NR23(); + NR24_REG = NR24(); break; - case 6: /* counter_ConsSel */ + case 6: // counter_ConsSel soundReg->mode2.counter_ConsSel = value; - NR24_REG = ((UBYTE *)soundReg)[0x09]; + NR24_REG = NR24(); break; - case 7: /* Sound2_To_SO1 */ + case 7: // Sound2_To_SO1 soundReg->control.Sound2_To_SO1 = value; - NR51_REG = ((UBYTE *)soundReg)[0x15]; + NR51_REG = NR51(); break; - case 8: /* Sound2_To_SO2 */ + case 8: // Sound2_To_SO2 soundReg->control.Sound2_To_SO2 = value; - NR51_REG = ((UBYTE *)soundReg)[0x15]; + NR51_REG = NR51(); break; - case 9: /* Sound2_On_Off */ + case 9: // Sound2_On_Off soundReg->control.Sound2_On_Off = value; - NR52_REG = ((UBYTE *)soundReg)[0x16]; + NR52_REG = NR52(); break; - case PLAY: /* restart */ + case PLAY: // restart update_value(mode, FREQUENCY, current_value(mode, FREQUENCY)); soundReg->mode2.restart = value; - NR24_REG = ((UBYTE *)soundReg)[0x09]; + NR24_REG = NR24(); soundReg->mode2.restart = 0; break; } } else if(mode == 3) { switch(line) { - case 0: /* on_Off */ + case 0: // on_Off soundReg->mode3.on_Off = value; - NR30_REG = ((UBYTE *)soundReg)[0x0A]; + NR30_REG = NR30(); break; - case 1: /* soundLength */ + case 1: // soundLength soundReg->mode3.soundLength = value; - NR31_REG = ((UBYTE *)soundReg)[0x0B]; + NR31_REG = NR31(); break; - case 2: /* selOutputLevel */ + case 2: // selOutputLevel soundReg->mode3.selOutputLevel = value; - NR32_REG = ((UBYTE *)soundReg)[0x0C]; + NR32_REG = NR32(); break; - case 3: /* frequency */ + case 3: // frequency case FREQUENCY: soundReg->mode3.frequencyHigh = value >> 8; - soundReg->mode3.frequencyLow = value; - NR33_REG = ((UBYTE *)soundReg)[0x0D]; - NR34_REG = ((UBYTE *)soundReg)[0x0E]; + soundReg->mode3.frequencyLow = 0xFF & value; + NR33_REG = NR33(); + NR34_REG = NR34(); break; - case 4: /* counter_ConsSel */ + case 4: // counter_ConsSel soundReg->mode3.counter_ConsSel = value; - NR34_REG = ((UBYTE *)soundReg)[0x0E]; + NR34_REG = NR34(); break; - case 5: /* Sound3_To_SO1 */ + case 5: // Sound3_To_SO1 soundReg->control.Sound3_To_SO1 = value; - NR51_REG = ((UBYTE *)soundReg)[0x15]; + NR51_REG = NR51(); break; - case 6: /* Sound3_To_SO2 */ + case 6: // Sound3_To_SO2 soundReg->control.Sound3_To_SO2 = value; - NR51_REG = ((UBYTE *)soundReg)[0x15]; + NR51_REG = NR51(); break; - case 7: /* Sound3_On_Off */ + case 7: // Sound3_On_Off soundReg->control.Sound3_On_Off = value; - NR52_REG = ((UBYTE *)soundReg)[0x16]; + NR52_REG = NR52(); break; - case PLAY: /* restart */ + case PLAY: // restart update_value(mode, FREQUENCY, current_value(mode, FREQUENCY)); soundReg->mode3.restart = value; - NR34_REG = ((UBYTE *)soundReg)[0x0E]; + NR34_REG = NR34(); soundReg->mode3.restart = 0; break; } } else if(mode == 4) { switch(line) { - case 0: /* soundLength */ + case 0: // soundLength soundReg->mode4.soundLength = value; - NR41_REG = ((UBYTE *)soundReg)[0x10]; + NR41_REG = NR41(); break; - case 1: /* envInitialValue */ + case 1: // envInitialValue soundReg->mode4.envInitialValue = value; - NR42_REG = ((UBYTE *)soundReg)[0x11]; + NR42_REG = NR42(); break; - case 2: /* envMode */ + case 2: // envMode soundReg->mode4.envMode = value; - NR42_REG = ((UBYTE *)soundReg)[0x11]; + NR42_REG = NR42(); break; - case 3: /* envNbStep */ + case 3: // envNbStep soundReg->mode4.envNbStep = value; - NR42_REG = ((UBYTE *)soundReg)[0x11]; + NR42_REG = NR42(); break; - case 4: /* polyCounterFreq */ + case 4: // polyCounterFreq soundReg->mode4.polyCounterFreq = value; - NR43_REG = ((UBYTE *)soundReg)[0x12]; + NR43_REG = NR43(); break; - case 5: /* polyCounterStep */ + case 5: // polyCounterStep soundReg->mode4.polyCounterStep = value; - NR43_REG = ((UBYTE *)soundReg)[0x12]; + NR43_REG = NR43(); break; - case 6: /* polyCounterDiv */ + case 6: // polyCounterDiv soundReg->mode4.polyCounterDiv = value; - NR43_REG = ((UBYTE *)soundReg)[0x12]; + NR43_REG = NR43(); break; - case 7: /* counter_ConsSel */ + case 7: // counter_ConsSel soundReg->mode4.counter_ConsSel = value; - NR44_REG = ((UBYTE *)soundReg)[0x13]; + NR44_REG = NR44(); break; - case 8: /* Sound4_To_SO1 */ + case 8: // Sound4_To_SO1 soundReg->control.Sound4_To_SO1 = value; - NR51_REG = ((UBYTE *)soundReg)[0x15]; + NR51_REG = NR51(); break; - case 9: /* Sound4_To_SO2 */ + case 9: // Sound4_To_SO2 soundReg->control.Sound4_To_SO2 = value; - NR51_REG = ((UBYTE *)soundReg)[0x15]; + NR51_REG = NR51(); break; - case 10: /* Sound4_On_Off */ + case 10: // Sound4_On_Off soundReg->control.Sound4_On_Off = value; - NR52_REG = ((UBYTE *)soundReg)[0x16]; + NR52_REG = NR52(); break; - case PLAY: /* restart */ + case PLAY: // restart soundReg->mode4.restart = value; - NR44_REG = ((UBYTE *)soundReg)[0x13]; + NR44_REG = NR44(); soundReg->mode4.restart = 0; break; } @@ -654,16 +808,17 @@ UBYTE draw_screen(UBYTE mode) { UBYTE i; - cls(); + clss(); gotoxy(FIRST_X, TITLE_Y); - printf("%s", params[0].name); + print(params[0].name); for(i = 0; params[i+1].name; i++) { gotoxy(FIRST_X, FIRST_Y+i); - printf("%s", params[i+1].name); + print(params[i+1].name); gotoxy(VAL_X, FIRST_Y+i); - printf("%d", current_value(mode, i)); + println(current_value(mode, i), 10, UNSIGNED); } + return i-1; } @@ -682,42 +837,105 @@ void play_music(UBYTE mode) } } + +void show_register_channel(UBYTE mode) { + + switch (mode) { + case 1: + gotoxy(0, 16); + print("NR10-14:"); + + gotoxy(1, 17); // Last line + printn(NR10(), 16, UNSIGNED); print(", "); + printn(NR11(), 16, UNSIGNED); print(", "); + printn(NR12(), 16, UNSIGNED); print(", "); + printn(NR13(), 16, UNSIGNED); print(", "); + printn(0x80 | NR14(), 16, UNSIGNED); + + break; + + case 2: + gotoxy(0, 16); + print("NR21-24:"); + + gotoxy(1, 17); // Last line + printn(NR21(), 16, UNSIGNED); print(", "); + printn(NR22(), 16, UNSIGNED); print(", "); + printn(NR23(), 16, UNSIGNED); print(", "); + printn(0x80 | NR24(), 16, UNSIGNED); + + break; + + case 3: + gotoxy(0, 16); + print("NR30-34:"); + + gotoxy(1, 17); // Last line + printn(NR30(), 16, UNSIGNED); print(", "); + printn(NR31(), 16, UNSIGNED); print(", "); + printn(NR32(), 16, UNSIGNED); print(", "); + printn(NR33(), 16, UNSIGNED); print(", "); + printn(0x80 | NR34(), 16, UNSIGNED); + + break; + + case 4: + gotoxy(0, 16); + print("NR41-44:"); + + gotoxy(1, 17); // Last line + printn(NR41(), 16, UNSIGNED); print(", "); + printn(NR42(), 16, UNSIGNED); print(", "); + printn(NR43(), 16, UNSIGNED); print(", "); + printn(0x80 | NR44(), 16, UNSIGNED); + + break; + + case 0: + gotoxy(0, 16); + print("NR50-52:"); + + gotoxy(1, 17); // Last line + printn(NR50(), 16, UNSIGNED); print(", "); + printn(NR51(), 16, UNSIGNED); print(", "); + printn(NR52(), 16, UNSIGNED); print(", "); + + break; + + } +} + + void dump_registers() { - UBYTE reg; - UBYTE i, j; + clss(); + gotoxy(FIRST_X, TITLE_Y); + print("Register Dump\n\n"); - cls(); - gotoxy(FIRST_X, TITLE_Y); - printf("Register Dump"); - - for(i = 0, j = 0; i <= 0x16; i++, j++) { - if(i == 0x05 || i == 0x0F) - i++; - if(j%2 == 0) { - gotoxy(FIRST_X, FIRST_Y+j/2); - printf("0xFF"); - } else { - gotoxy(FIRST_X+6, FIRST_Y+j/2); - putchar('-'); - } - printf("%ux", (UBYTE)(i+0x10)); - if(j%2 == 0) { - gotoxy(VAL_X, FIRST_Y+j/2); - } else { - gotoxy(VAL_X+2, FIRST_Y+j/2); - putchar('-'); - } - reg = ((UBYTE *)soundReg)[i]; - if(!(reg & 0xF0U)) putchar('0'); - printf("%ux", reg); - } + print("NR10:");println(NR10(), 16, UNSIGNED); + print("NR11:");printn(NR11(), 16, UNSIGNED); print(" NR21:");println(NR21(), 16, UNSIGNED); + print("NR12:");printn(NR12(), 16, UNSIGNED); print(" NR22:");println(NR22(), 16, UNSIGNED); + print("NR13:");printn(NR13(), 16, UNSIGNED); print(" NR23:");println(NR23(), 16, UNSIGNED); + print("NR14:");printn(0x80 | NR14(), 16, UNSIGNED); print(" NR24:");println(0x80 | NR24(), 16, UNSIGNED); + printf("\n"); + + print("NR30:");println(NR30(), 16, UNSIGNED); + print("NR31:");printn(NR31(), 16, UNSIGNED); print(" NR41:");println(NR41(), 16, UNSIGNED); + print("NR32:");printn(NR32(), 16, UNSIGNED); print(" NR42:");println(NR42(), 16, UNSIGNED); + print("NR33:");printn(NR33(), 16, UNSIGNED); print(" NR43:");println(NR43(), 16, UNSIGNED); + print("NR34:");printn(0x80 | NR34(), 16, UNSIGNED); print(" NR44:");println(0x80 | NR44(), 16, UNSIGNED); + printf("\n"); + + print("NR50:");println(NR50(), 16, UNSIGNED); + print("NR51:");println(NR51(), 16, UNSIGNED); + print("NR52:");println(NR52(), 16, UNSIGNED); } void wait_event(UBYTE mode) { - UBYTE input, y, last_y; - UWORD l; + UBYTE y, last_y; + UWORD l = 0; + UWORD m = 0; while(1) { params = params_array[mode]; @@ -726,125 +944,123 @@ void wait_event(UBYTE mode) gotoxy(ARROW_X, y); setchar(ARROW_CHAR); + show_register_channel(mode); + while(1) { - input = joypad(); - if(input & J_UP) { - gotoxy(ARROW_X, y); setchar(SPACE_CHAR); - if(--y < FIRST_Y) - y = last_y; - gotoxy(ARROW_X, y); setchar(ARROW_CHAR); - } else if(input & J_DOWN) { - gotoxy(ARROW_X, y); setchar(SPACE_CHAR); - if(++y > last_y) - y = FIRST_Y; - gotoxy(ARROW_X, y); setchar(ARROW_CHAR); - } else if(input & J_LEFT) { - l = current_value(mode, y-FIRST_Y); - if(l > 0) { - if(input & J_A) - l = MAX(l, 10) - 10; - else if(input & J_B) - l = 0; - else - l--; - update_value(mode, y-FIRST_Y, l); - gotoxy(VAL_X, y); printf(" "); - gotoxy(VAL_X, y); printf("%d", l); - } - } else if(input & J_RIGHT) { - l = current_value(mode, y-FIRST_Y); - if(l < params[y-(FIRST_Y-1)].max) { - if(input & J_A) - l = MIN(l + 10, params[y-(FIRST_Y-1)].max); - else if(input & J_B) - l = params[y-(FIRST_Y-1)].max; - else - l++; - update_value(mode, y-FIRST_Y, l); - gotoxy(VAL_X, y); printf(" "); - gotoxy(VAL_X, y); printf("%d", l); - } - } else if(input & J_START) { - if(input & J_A) - play_music(mode); - else - update_value(mode, PLAY, 1); - waitpadup(); - } else if(input & J_SELECT) { - if(input & J_A) - dump_registers(); - else - mode = (mode+1) % NB_MODES; - waitpadup(); - break; - } - delay(250); + if(KEY_TICKED(J_UP)) { + gotoxy(ARROW_X, y); setchar(SPACE_CHAR); + if(--y < FIRST_Y) + y = last_y; + gotoxy(ARROW_X, y); setchar(ARROW_CHAR); + + } else if(KEY_TICKED(J_DOWN)) { + gotoxy(ARROW_X, y); setchar(SPACE_CHAR); + if(++y > last_y) + y = FIRST_Y; + gotoxy(ARROW_X, y); setchar(ARROW_CHAR); + + } else if(KEY_TICKED(J_LEFT)) { + l = current_value(mode, y-FIRST_Y); + if(l != 0) { + if(KEY_PRESSED(J_A) && KEY_PRESSED(J_B)) + l = 0; + else if(KEY_PRESSED(J_A)) + l = (l > 10) ? (l - 10) : 0; + else if(KEY_PRESSED(J_B)) + l = (l > 100) ? (l - 100) : 0; + else + l--; + update_value(mode, y-FIRST_Y, l); + } + gotoxy(VAL_X, y); print(" "); + gotoxy(VAL_X, y); println(l, 10, UNSIGNED); + + show_register_channel(mode); + + } else if(KEY_TICKED(J_RIGHT)) { + l = current_value(mode, y-FIRST_Y); + m = params[y-(FIRST_Y-1)].max; + if(l != m) { + if(KEY_PRESSED(J_A) && KEY_PRESSED(J_B)) { + l = m; + } + else if(KEY_PRESSED(J_A)) { + l += 10; + if(l > m) + l = m; + } else if(KEY_PRESSED(J_B)) { + l += 100; + if(l > m) + l = m; + } + else + l++; + update_value(mode, y-FIRST_Y, l); + } + gotoxy(VAL_X, y); print(" "); + gotoxy(VAL_X, y); println(l, 10, UNSIGNED); + + show_register_channel(mode); + + } else if(KEY_TICKED(J_START)) { + if (KEY_PRESSED(J_A)) + play_music(mode); + else + update_value(mode, PLAY, 1); + + } else if(KEY_PRESSED(J_SELECT)) { + if(KEY_PRESSED(J_A)) + dump_registers(); + else { + mode = (mode+1) % NB_MODES; + } + waitpadup(); + keys = 0; + break; + } + wait_vbl_done(); + UPDATE_KEYS(); } } } void main() { - struct SoundReg s = { - { 0, 0, 0, 0, - 1, 2, - 3, 0, 4, - 0x73U, - 6, 0, 0, 0 }, - { 0, - 1, 2, - 4, 0, 8, - 0xD7U, - 6, 0, 0, 0 }, - { 0, 1, - 0, - 0, 1, 0, - 0xD6U, - 6, 0, 0, 0 }, - { 0, - 58, 0, - 1, 0, 10, - 0, 0, 0, - 0, 1, 0 }, - { 7, 0, 7, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 1 } - }; - - /* - * Before modifying any sound register, sound must be turned on! - * (it is turned off by default to save batteries) - */ + // + // Before modifying any sound register, sound must be turned on! + // (it is turned off by default to save batteries) + // NR52_REG = 0x80; soundReg = &s; - NR10_REG = ((UBYTE *)soundReg)[0x00]; - NR11_REG = ((UBYTE *)soundReg)[0x01]; - NR12_REG = ((UBYTE *)soundReg)[0x02]; - NR13_REG = ((UBYTE *)soundReg)[0x03]; - NR14_REG = ((UBYTE *)soundReg)[0x04]; - - NR21_REG = ((UBYTE *)soundReg)[0x06]; - NR22_REG = ((UBYTE *)soundReg)[0x07]; - NR23_REG = ((UBYTE *)soundReg)[0x08]; - NR24_REG = ((UBYTE *)soundReg)[0x09]; - - NR30_REG = ((UBYTE *)soundReg)[0x0A]; - NR31_REG = ((UBYTE *)soundReg)[0x0B]; - NR32_REG = ((UBYTE *)soundReg)[0x0C]; - NR33_REG = ((UBYTE *)soundReg)[0x0D]; - NR34_REG = ((UBYTE *)soundReg)[0x0E]; - - NR41_REG = ((UBYTE *)soundReg)[0x10]; - NR42_REG = ((UBYTE *)soundReg)[0x11]; - NR43_REG = ((UBYTE *)soundReg)[0x12]; - NR44_REG = ((UBYTE *)soundReg)[0x13]; - - NR50_REG = ((UBYTE *)soundReg)[0x14]; - NR51_REG = ((UBYTE *)soundReg)[0x15]; - NR52_REG = ((UBYTE *)soundReg)[0x16]; - - cls(); + NR10_REG = NR10(); + NR11_REG = NR11(); + NR12_REG = NR12(); + NR13_REG = NR13(); + NR14_REG = NR14(); + + NR21_REG = NR21(); + NR22_REG = NR22(); + NR23_REG = NR23(); + NR24_REG = NR24(); + + NR30_REG = NR30(); + NR31_REG = NR31(); + NR32_REG = NR32(); + NR33_REG = NR33(); + NR34_REG = NR34(); + + NR41_REG = NR41(); + NR42_REG = NR42(); + NR43_REG = NR43(); + NR44_REG = NR44(); + + NR50_REG = NR50(); + NR51_REG = NR51(); + NR52_REG = NR52(); + + clss(); wait_event(1); } +
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.