X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=platform%2Fgp2x%2Fcode940%2F940.c;h=0df19453db952452f7a61cc2f54f8954413e7984;hb=e4fb433cd685d06ddbf0ec367c19a38b75d6ac68;hp=18d282cb782bad33df14b6ffac7617c7dd04af9a;hpb=7a93adeb29f01f5867ff36606cd73a382b6ee0e3;p=picodrive.git diff --git a/platform/gp2x/code940/940.c b/platform/gp2x/code940/940.c index 18d282c..0df1945 100644 --- a/platform/gp2x/code940/940.c +++ b/platform/gp2x/code940/940.c @@ -1,19 +1,25 @@ +// The top-level functions for the ARM940 +// (c) Copyright 2006-2007, Grazvydas "notaz" Ignotas + #include "940shared.h" static _940_data_t *shared_data = (_940_data_t *) 0x00100000; static _940_ctl_t *shared_ctl = (_940_ctl_t *) 0x00200000; -static unsigned char *mp3_data = (unsigned char *) 0x01000000; +static unsigned char *mp3_data = (unsigned char *) 0x00400000; YM2612 *ym2612_940; // from init.s -void wait_irq(void); +int wait_get_job(int oldjob); void spend_cycles(int c); -void cache_clean(void); -void cache_clean_flush(void); +void dcache_clean(void); +void dcache_clean_flush(void); +void drain_wb(void); // this should help to resolve race confition where shared var // is changed by other core just before we update it void set_if_not_changed(int *val, int oldval, int newval); +void _memcpy(void *dst, const void *src, int count); + // asm volatile ("mov r0, #0" ::: "r0"); // asm volatile ("mcr p15, 0, r0, c7, c6, 0" ::: "r0"); /* flush dcache */ // asm volatile ("mcr p15, 0, r0, c7, c10, 4" ::: "r0"); /* drain write buffer */ @@ -41,7 +47,6 @@ static void mp3_decode(void) shared_data->mp3_buffer[shared_ctl->mp3_buffsel], 0); if (err) { if (err == ERR_MP3_INDATA_UNDERFLOW) { - shared_ctl->mp3_offs = shared_ctl->mp3_len; // EOF set_if_not_changed(&shared_ctl->mp3_offs, mp3_offs, shared_ctl->mp3_len); return; } else if (err <= -6 && err >= -12) { @@ -55,98 +60,139 @@ static void mp3_decode(void) set_if_not_changed(&shared_ctl->mp3_offs, mp3_offs, readPtr - mp3_data); } - -void Main940(int startvector, int pc_at_irq) +static void ym_flush_writes(void) { - int mix_buffer = shared_data->mix_buffer; - ym2612_940 = &shared_data->ym2612; + UINT16 *wbuff; + int i; - // debug - shared_ctl->vstarts[startvector]++; - shared_ctl->last_irq_pc = pc_at_irq; - // asm volatile ("mcr p15, 0, r0, c7, c10, 4" ::: "r0"); + if (shared_ctl->writebuffsel == 1) { + wbuff = shared_ctl->writebuff1; + } else { + wbuff = shared_ctl->writebuff0; + } + /* playback all writes */ + for (i = 2048; i > 0; i--) { + UINT16 d = *wbuff++; + if (d == 0xffff) break; + if (d == 0xfffe) continue; + YM2612Write_(d >> 8, d); + } +} -// for (;;) +static void ym_update(int *ym_buffer) +{ + int i, dw; + int two_upds = 0; + UINT16 *wbuff; + + if (shared_ctl->writebuffsel == 1) { + wbuff = shared_ctl->writebuff1; + } else { + wbuff = shared_ctl->writebuff0; + } + + /* playback all writes */ + for (i = 2048/2; i > 0; i--) { + UINT16 d; + dw = *(int *)wbuff; + d = dw; + wbuff++; + if (d == 0xffff) break; + if (d == 0xfffe) { two_upds=1; break; } + YM2612Write_(d >> 8, d); + d = (dw>>16); + wbuff++; + if (d == 0xffff) break; + if (d == 0xfffe) { two_upds=1; break; } + YM2612Write_(d >> 8, d); + } + + if (two_upds) { - int job_num = 0; -/* - while (!shared_ctl->busy) - { - //shared_ctl->waitc++; - spend_cycles(8*1024); - } -*/ -/* - if (!shared_ctl->busy) - { - wait_irq(); + int len1 = shared_ctl->length / 2; + shared_ctl->ym_active_chs = + YM2612UpdateOne_(ym_buffer, len1, shared_ctl->stereo, 1); + + for (i *= 2; i > 0; i--) { + UINT16 d = *wbuff++; + if (d == 0xffff) break; + YM2612Write_(d >> 8, d); } - shared_ctl->lastbusy = shared_ctl->busy; -*/ - for (job_num = 0; job_num < MAX_940JOBS; job_num++) - { - shared_ctl->lastjob = (job_num << 8) | shared_ctl->jobs[job_num]; - - switch (shared_ctl->jobs[job_num]) - { - case JOB940_INITALL: - /* ym2612 */ - shared_ctl->writebuff0[0] = shared_ctl->writebuff1[0] = 0xffff; - YM2612Init_(shared_ctl->baseclock, shared_ctl->rate); - /* Helix mp3 decoder */ - shared_data->mp3dec = MP3InitDecoder(); - break; - - case JOB940_YM2612RESETCHIP: - YM2612ResetChip_(); - break; - - case JOB940_PICOSTATELOAD: - YM2612PicoStateLoad_(); - break; - - case JOB940_YM2612UPDATEONE: { - int i, dw, *wbuff; - if (shared_ctl->writebuffsel == 1) { - wbuff = (int *) shared_ctl->writebuff1; - } else { - wbuff = (int *) shared_ctl->writebuff0; - } - - /* playback all writes */ - for (i = 2048/2; i > 0; i--) { - UINT16 d; - dw = *wbuff++; - d = dw; - if (d == 0xffff) break; - YM2612Write_(d >> 8, d); - d = (dw>>16); - if (d == 0xffff) break; - YM2612Write_(d >> 8, d); - } - - YM2612UpdateOne_(mix_buffer, shared_ctl->length, shared_ctl->stereo, 1); - break; - } - - case JOB940_MP3DECODE: - mp3_decode(); - break; - } - } + ym_buffer += shared_ctl->stereo ? len1*2 : len1; + len1 = shared_ctl->length - len1; + + shared_ctl->ym_active_chs = + YM2612UpdateOne_(ym_buffer, len1, shared_ctl->stereo, 1); + } else { + shared_ctl->ym_active_chs = + YM2612UpdateOne_(ym_buffer, shared_ctl->length, shared_ctl->stereo, 1); + } +} - cache_clean(); -// asm volatile ("mov r0, #0" ::: "r0"); -// asm volatile ("mcr p15, 0, r0, c7, c10, 4" ::: "r0"); /* drain write buffer, should be done on nonbuffered write */ -// cache_clean_flush(); - shared_ctl->loopc++; +void Main940(void) +{ + int *ym_buffer = shared_data->ym_buffer; + int job = 0; + ym2612_940 = &shared_data->ym2612; -// // shared_ctl->busy = 0; // shared mem is not reliable? - wait_irq(); + for (;;) + { + job = wait_get_job(job); + + shared_ctl->lastjob = job; + + switch (job) + { + case JOB940_INITALL: + /* ym2612 */ + shared_ctl->writebuff0[0] = shared_ctl->writebuff1[0] = 0xffff; + YM2612Init_(shared_ctl->baseclock, shared_ctl->rate); + /* Helix mp3 decoder */ + shared_data->mp3dec = MP3InitDecoder(); + break; + + case JOB940_INVALIDATE_DCACHE: + drain_wb(); + dcache_clean_flush(); + break; + + case JOB940_YM2612RESETCHIP: + YM2612ResetChip_(); + break; + + case JOB940_PICOSTATELOAD: + YM2612PicoStateLoad_(); + break; + + case JOB940_PICOSTATESAVE2: + YM2612PicoStateSave2(0, 0); + _memcpy(shared_ctl->writebuff0, ym2612_940->REGS, 0x200); + break; + + case JOB940_PICOSTATELOAD2_PREP: + ym_flush_writes(); + break; + + case JOB940_PICOSTATELOAD2: + _memcpy(ym2612_940->REGS, shared_ctl->writebuff0, 0x200); + YM2612PicoStateLoad2(0, 0); + break; + + case JOB940_YM2612UPDATEONE: + ym_update(ym_buffer); + break; + + case JOB940_MP3DECODE: + mp3_decode(); + break; + } + + shared_ctl->loopc++; + dcache_clean(); } }