diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/config.c | 9 | ||||
-rw-r--r-- | source/main.c | 9 | ||||
-rw-r--r-- | source/spec.c | 49 | ||||
-rw-r--r-- | source/z80.c | 16 |
4 files changed, 77 insertions, 6 deletions
diff --git a/source/config.c b/source/config.c index 8198290..b16f1b3 100644 --- a/source/config.c +++ b/source/config.c @@ -40,7 +40,8 @@ const char *conf_filename = "SPEC48.CFG"; const char *conf_entry[DSSPEC_NUM_CONFIG_ITEMS]= { "sticky_shift", - "load_default_snapshot" + "load_default_snapshot", + "sound" }; @@ -49,7 +50,8 @@ const char *conf_entry[DSSPEC_NUM_CONFIG_ITEMS]= int DSSPEC_Config[DSSPEC_NUM_CONFIG_ITEMS]= { TRUE, - FALSE + FALSE, + TRUE }; @@ -126,6 +128,9 @@ const char *ConfigDesc(DSSPEC_ConfigItem item) case DSSPEC_LOAD_DEFAULT_SNAPSHOT: return "LOAD DEFAULT SNAPSHOT"; + case DSSPEC_SOUND: + return "SOUND"; + default: return "UNKNOWN"; } diff --git a/source/main.c b/source/main.c index 46eccfe..b7d3318 100644 --- a/source/main.c +++ b/source/main.c @@ -235,8 +235,16 @@ int main(int argc, char *argv[]) { Z80 *z80; int quit = FALSE; + float mix[12] = {1.0, 1.0}; gfxInit(GSP_RGB565_OES, GSP_RGB565_OES, FALSE); + ndspInit(); + + ndspSetOutputMode(NDSP_OUTPUT_MONO); + ndspChnSetInterp(0, NDSP_INTERP_NONE); + ndspChnSetRate(0, SAMPLE_RATE); + ndspChnSetFormat(0, NDSP_FORMAT_MONO_PCM8); + ndspChnSetMix(0, mix); FB_Init(); @@ -352,6 +360,7 @@ int main(int argc, char *argv[]) } } + ndspExit(); gfxExit(); return 0; diff --git a/source/spec.c b/source/spec.c index 6cdc7c6..ef132d4 100644 --- a/source/spec.c +++ b/source/spec.c @@ -59,6 +59,7 @@ #define ED_LOAD 0xf1 #define SCAN_CYCLES 224 +#define FRAME_CYCLES 69888 /* The 3DS screen */ @@ -153,6 +154,17 @@ static struct {7,0x10}, {7,0x08}, {7,0x04}, {7,0x02}, {7,0x01} /* B - SPACE */ }; +/* Sound +*/ +#define SAMPLE_BUFF_SZ (SAMPLE_RATE/60) + +#define SAMPLE_CYCLE (FRAME_CYCLES/SAMPLE_BUFF_SZ) + +static u8 *sample[2]; +static int sound_buffer; +static u8 sound_level; +static int sound_ptr; +static ndspWaveBuf wave_buff[2]; /* ---------------------------------------- PRIVATE FUNCTIONS */ @@ -160,7 +172,7 @@ static void RomPatch(void) { static const Z80Byte save[]= { - 0xed, ED_SAVE, /* (SAVE) */ + 0xed, ED_SAVE, /* (SAVE) */ 0xc9, /* RET */ 0xff /* End of patch */ }; @@ -263,6 +275,13 @@ static int CheckTimers(Z80 *z80, Z80Val val) { int ret = TRUE; + if (DSSPEC_Config[DSSPEC_SOUND] && + Z80GetTimer(z80, Z80_TIMER_1) >= SAMPLE_CYCLE) + { + Z80SetTimer(z80, Z80_TIMER_1, 0); + sample[sound_buffer][sound_ptr++] = sound_level; + } + if (val > SCAN_CYCLES) { int y; @@ -287,6 +306,15 @@ static int CheckTimers(Z80 *z80, Z80Val val) Z80Interrupt(z80,0xff); + if (DSSPEC_Config[DSSPEC_SOUND]) + { + ndspChnWaveBufAdd(0, wave_buff + sound_buffer); + sound_buffer = !sound_buffer; + memset(sample[sound_buffer], 0, SAMPLE_BUFF_SZ); + sound_ptr = 0; + Z80SetTimer(z80, Z80_TIMER_1, 0); + } + ret = FALSE; } @@ -298,8 +326,6 @@ static int CheckTimers(Z80 *z80, Z80Val val) { DrawScanline(y, scanline); } - - /* TODO: Process sound emulation */ } return ret; @@ -361,6 +387,18 @@ void SPECInit(Z80 *z80) Z80LodgeCallback(z80,eZ80_EDHook,EDCallback); Z80LodgeCallback(z80,eZ80_Instruction,CheckTimers); + /* Create sound buffers and wave vars + */ + sample[0] = linearAlloc(SAMPLE_BUFF_SZ); + sample[1] = linearAlloc(SAMPLE_BUFF_SZ); + + wave_buff[0].data_vaddr = sample[0]; + wave_buff[0].nsamples = SAMPLE_BUFF_SZ; + wave_buff[1].data_vaddr = sample[1]; + wave_buff[1].nsamples = SAMPLE_BUFF_SZ; + + sound_buffer = 0; + SPECReset(z80); } @@ -465,6 +503,7 @@ void SPECWritePort(Z80 *z80, Z80Word port, Z80Byte val) { case 0xfe: /* ULA */ border = val & 0x07; + sound_level = val & 0x10 ? 128:0; break; case 0xfb: /* ZX Printer */ @@ -486,11 +525,13 @@ void SPECReset(Z80 *z80) matrix[f]=0x1f; Z80Reset(z80); - Z80ResetCycles(z80,0); border = 0; scanline = 0; + sound_buffer = 0; + sound_ptr = 0; + /* Set up screen */ c=0; diff --git a/source/z80.c b/source/z80.c index e5f6c92..790aeec 100644 --- a/source/z80.c +++ b/source/z80.c @@ -170,6 +170,10 @@ Z80 *Z80Init(Z80ReadMemory read_memory, void Z80Reset(Z80 *cpu) { PRIV->cycle=0; + PRIV->timer[Z80_TIMER_1]=0; + PRIV->timer[Z80_TIMER_2]=0; + PRIV->timer[Z80_TIMER_3]=0; + cpu->PC=0; cpu->AF.w=0xffff; @@ -209,6 +213,18 @@ void Z80ResetCycles(Z80 *cpu, Z80Val cycles) } +Z80Val Z80GetTimer(Z80 *cpu, Z80Timer timer) +{ + return PRIV->timer[timer]; +} + + +void Z80SetTimer(Z80 *cpu, Z80Timer timer, Z80Val cycles) +{ + PRIV->timer[timer] = cycles; +} + + int Z80LodgeCallback(Z80 *cpu, Z80CallbackReason reason, Z80Callback callback) { int f; |