X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fjerry.cpp;h=27c3cab25d8c381b43216ec87932a2e6a533bc7c;hb=2f2984007c9a7097057cadd683ee399db2c7433e;hp=1aff37fc390ffe1596abe09baacba4b4eb4cebe4;hpb=fa566a2c8ec532eb5325b4d5a663fb2a7d72adc6;p=virtualjaguar diff --git a/src/jerry.cpp b/src/jerry.cpp index 1aff37f..27c3cab 100644 --- a/src/jerry.cpp +++ b/src/jerry.cpp @@ -160,36 +160,50 @@ static int32 jerry_timer_1_counter; static int32 jerry_timer_2_counter; static uint32 jerry_i2s_interrupt_divide = 8; -static int32 jerry_i2s_interrupt_timer = -1; -static int32 jerry_i2s_interrupt_cycles_per_scanline = 0; - +static int32 jerry_i2s_interrupt_timer = -1; +uint32 jerryI2SCycles; +uint32 jerryIntPending; +//This approach is probably wrong, since the timer is continuously counting down, though +//it might only be a problem if the # of interrupts generated is greater than 1--the M68K's +//timeslice should be running during that phase... (The DSP needs to be aware of this!) void jerry_i2s_exec(uint32 cycles) { + extern uint16 serialMode; // From DAC.CPP + if (!(serialMode & 0x01)) // INTERNAL flag + return; + + // Why is it called this? Instead of SCLK? Shouldn't this be read from DAC.CPP??? +//Yes, it should. !!! FIX !!! jerry_i2s_interrupt_divide &= 0xFF; if (jerry_i2s_interrupt_timer == -1) { - uint32 jerry_i2s_int_freq = (26591000 / 64) / (jerry_i2s_interrupt_divide + 1); - jerry_i2s_interrupt_cycles_per_scanline = 13300000 / jerry_i2s_int_freq; - jerry_i2s_interrupt_timer = jerry_i2s_interrupt_cycles_per_scanline; - //WriteLog("jerry: i2s interrupt rate set to %i hz (every %i cpu clock cycles) jerry_i2s_interrupt_divide=%i\n",jerry_i2s_int_freq,jerry_i2s_interrupt_cycles_per_scanline,jerry_i2s_interrupt_divide); - pcm_set_sample_rate(jerry_i2s_int_freq); + // We don't have to divide the RISC clock rate by this--the reason is a bit + // convoluted. Will put explanation here later... +// What's needed here is to find the ratio of the frequency to the number of clock cycles +// in one second. For example, if the sample rate is 44100, we divide the clock rate by +// this: 26590906 / 44100 = 602 cycles. +// Which means, every 602 cycles that go by we have to generate an interrupt. + jerryI2SCycles = 32 * (2 * (jerry_i2s_interrupt_divide + 1)); } + jerry_i2s_interrupt_timer -= cycles; - // note : commented since the sound doesn't work properly else - if (1)//jerry_i2s_interrupt_timer<=0) + if (jerry_i2s_interrupt_timer <= 0) { - // i2s interrupt - dsp_check_if_i2s_interrupt_needed(); - //WriteLog("jerry_i2s_interrupt_timer=%i, generating an i2s interrupt\n",jerry_i2s_interrupt_timer); - jerry_i2s_interrupt_timer += jerry_i2s_interrupt_cycles_per_scanline; + DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE); + jerry_i2s_interrupt_timer += jerryI2SCycles; +#ifdef JERRY_DEBUG + if (jerry_i2s_interrupt_timer < 0) + WriteLog("JERRY: Missed generating an interrupt (missed %u)!\n", (-jerry_i2s_interrupt_timer / jerryI2SCycles) + 1); +#endif } } void jerry_reset_i2s_timer(void) { //WriteLog("i2s: reseting\n"); +//This is really SCLK... !!! FIX !!! jerry_i2s_interrupt_divide = 8; jerry_i2s_interrupt_timer = -1; } @@ -219,14 +233,14 @@ void jerry_reset_timer_2(void) // WriteLog("jerry: reseting timer 2 to 0x%.8x (%i)\n",jerry_timer_2_counter,jerry_timer_2_counter); } -void jerry_pit_exec(uint32 cycles) +void JERRYExecPIT(uint32 cycles) { if (jerry_timer_1_counter) jerry_timer_1_counter -= cycles; if (jerry_timer_1_counter <= 0) { - dsp_set_irq_line(2, 1); + DSPSetIRQLine(DSPIRQ_TIMER0, ASSERT_LINE); jerry_reset_timer_1(); } @@ -235,7 +249,7 @@ void jerry_pit_exec(uint32 cycles) if (jerry_timer_2_counter <= 0) { - dsp_set_irq_line(3, 1); + DSPSetIRQLine(DSPIRQ_TIMER1, ASSERT_LINE); jerry_reset_timer_2(); } } @@ -245,58 +259,66 @@ void jerry_init(void) clock_init(); anajoy_init(); joystick_init(); + DACInit(); //This should be handled with the cart initialization... // eeprom_init(); memory_malloc_secure((void **)&jerry_ram_8, 0x10000, "JERRY RAM/ROM"); memcpy(&jerry_ram_8[0xD000], wave_table, 0x1000); - -/*for(int i=0; i<0x1000; i++) - WriteLog("WT byte, JERRY byte: %02X, %02X\n", wave_table[i], jerry_ram_8[0xD000+i]);//*/ } void jerry_reset(void) { - //WriteLog("jerry_reset()\n"); clock_reset(); anajoy_reset(); joystick_reset(); eeprom_reset(); jerry_reset_i2s_timer(); + DACReset(); memset(jerry_ram_8, 0x00, 0xD000); // Don't clear out the Wavetable ROM...! - jerry_ram_8[JERRY_CONFIG+1] |= 0x10; // NTSC (bit 4) jerry_timer_1_prescaler = 0xFFFF; jerry_timer_2_prescaler = 0xFFFF; jerry_timer_1_divider = 0xFFFF; jerry_timer_2_divider = 0xFFFF; jerry_timer_1_counter = 0; jerry_timer_2_counter = 0; - } void jerry_done(void) { - //WriteLog("jerry_done()\n"); + WriteLog("JERRY: M68K Interrupt control ($F10020) = %04X\n", GET16(jerry_ram_8, 0x20)); memory_free(jerry_ram_8); clock_done(); anajoy_done(); joystick_done(); + DACDone(); eeprom_done(); } +bool JERRYIRQEnabled(int irq) +{ + // Read the word @ $F10020 + return jerry_ram_8[0x21] & (1 << irq); +} + +void JERRYSetPendingIRQ(int irq) +{ + // This is the shadow of INT (it's a split RO/WO register) + jerryIntPending |= (1 << irq); +} + // // JERRY byte access (read) // - -unsigned jerry_byte_read(unsigned int offset) +uint8 JERRYReadByte(uint32 offset, uint32 who/*=UNKNOWN*/) { #ifdef JERRY_DEBUG WriteLog("JERRY: Reading byte at %06X\n", offset); #endif if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) - return dsp_byte_read(offset); + return DSPReadByte(offset, who); else if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) - return dsp_byte_read(offset); + return DSPReadByte(offset, who); else if (offset >= 0xF10000 && offset <= 0xF10007) { switch(offset & 0x07) @@ -319,7 +341,7 @@ unsigned jerry_byte_read(unsigned int offset) return jerry_timer_2_divider & 0xFF; } } - else if (offset >= 0xF10010 && offset <= 0xf10015) + else if (offset >= 0xF10010 && offset <= 0xF10015) return clock_byte_read(offset); else if (offset >= 0xF17C00 && offset <= 0xF17C01) return anajoy_byte_read(offset); @@ -336,17 +358,16 @@ unsigned jerry_byte_read(unsigned int offset) // // JERRY word access (read) // - -unsigned jerry_word_read(unsigned int offset) +uint16 JERRYReadWord(uint32 offset, uint32 who/*=UNKNOWN*/) { #ifdef JERRY_DEBUG WriteLog("JERRY: Reading word at %06X\n", offset); #endif if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) - return dsp_word_read(offset); - else if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) - return dsp_word_read(offset); + return DSPReadWord(offset, who); + else if (offset >= DSP_WORK_RAM_BASE && offset <= DSP_WORK_RAM_BASE + 0x1FFF) + return DSPReadWord(offset, who); else if ((offset >= 0xF10000) && (offset <= 0xF10007)) { switch(offset & 0x07) @@ -365,7 +386,7 @@ unsigned jerry_word_read(unsigned int offset) else if ((offset >= 0xF10010) && (offset <= 0xF10015)) return clock_word_read(offset); else if (offset == 0xF10020) - return 0x00; + return jerryIntPending; else if ((offset >= 0xF17C00) && (offset <= 0xF17C01)) return anajoy_word_read(offset); else if (offset == 0xF14000) @@ -378,11 +399,6 @@ unsigned jerry_word_read(unsigned int offset) else if ((offset >= 0xF14000) && (offset <= 0xF1A0FF)) return eeprom_word_read(offset); -// This is never executed! -/* offset &= 0xFFFF; - if (offset==0x4002) - return(0xffff);*/ - /*if (offset >= 0xF1D000) WriteLog("JERRY: Reading word at %08X [%04X]...\n", offset, ((uint16)jerry_ram_8[(offset+0)&0xFFFF] << 8) | jerry_ram_8[(offset+1)&0xFFFF]);//*/ @@ -393,25 +409,25 @@ unsigned jerry_word_read(unsigned int offset) // // JERRY byte access (write) // - -void jerry_byte_write(unsigned offset, unsigned data) +void JERRYWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/) { #ifdef JERRY_DEBUG WriteLog("jerry: writing byte %.2x at 0x%.6x\n",data,offset); #endif if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) { - dsp_byte_write(offset, data); + DSPWriteByte(offset, data, who); return; } else if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) { - dsp_byte_write(offset, data); + DSPWriteByte(offset, data, who); return; } + // SCLK ($F1A150--8 bits wide) else if ((offset >= 0xF1A152) && (offset <= 0xF1A153)) { -// WriteLog("i2s: writing 0x%.2x to SCLK\n",data); +// WriteLog("JERRY: Writing %02X to SCLK...\n", data); if ((offset & 0x03) == 2) jerry_i2s_interrupt_divide = (jerry_i2s_interrupt_divide & 0x00FF) | ((uint32)data << 8); else @@ -419,17 +435,26 @@ void jerry_byte_write(unsigned offset, unsigned data) jerry_i2s_interrupt_timer = -1; jerry_i2s_exec(0); - return; +// return; } - else if ((offset >= 0xF10000) && (offset <= 0xF10007)) + // LTXD/RTXD/SCLK/SMODE $F1A148/4C/50/54 (really 16-bit registers...) + else if (offset >= 0xF1A148 && offset <= 0xF1A157) + { + DACWriteByte(offset, data); + return; + } + else if (offset >= 0xF10000 && offset <= 0xF10007) { - switch(offset & 0x07) + switch (offset & 0x07) { case 0: jerry_timer_1_prescaler = (jerry_timer_1_prescaler & 0x00FF) | (data << 8); jerry_reset_timer_1(); break; - case 1: { jerry_timer_1_prescaler=(jerry_timer_1_prescaler&0xff00)|(data); jerry_reset_timer_1(); return; } + case 1: + jerry_timer_1_prescaler = (jerry_timer_1_prescaler & 0xFF00) | (data); + jerry_reset_timer_1(); + break; case 2: { jerry_timer_1_divider=(jerry_timer_1_divider&0x00ff)|(data<<8); jerry_reset_timer_1(); return; } case 3: { jerry_timer_1_divider=(jerry_timer_1_divider&0xff00)|(data); jerry_reset_timer_1(); return; } case 4: { jerry_timer_2_prescaler=(jerry_timer_2_prescaler&0x00ff)|(data<<8); jerry_reset_timer_2(); return; } @@ -471,8 +496,7 @@ void jerry_byte_write(unsigned offset, unsigned data) // // JERRY word access (write) // - -void jerry_word_write(unsigned offset, unsigned data) +void JERRYWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/) { #ifdef JERRY_DEBUG WriteLog( "JERRY: Writing word %04X at %06X\n", data, offset); @@ -480,20 +504,29 @@ void jerry_word_write(unsigned offset, unsigned data) if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) { - dsp_word_write(offset, data); + DSPWriteWord(offset, data, who); return; } else if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) { - dsp_word_write(offset, data); + DSPWriteWord(offset, data, who); return; } - else if (offset == 0xF1A152) + else if (offset == 0xF1A152) // Bottom half of SCLK ($F1A150) { -// WriteLog("i2s: writing 0x%.4x to SCLK\n",data); - jerry_i2s_interrupt_divide = data & 0xFF; + WriteLog("JERRY: Writing %04X to SCLK (by %s)...\n", data, whoName[who]); + jerry_i2s_interrupt_divide = (uint8)data; jerry_i2s_interrupt_timer = -1; jerry_i2s_exec(0); + + DACWriteWord(offset, data); + return; + } + // LTXD/RTXD/SCLK/SMODE $F1A148/4C/50/54 (really 16-bit registers...) + else if (offset >= 0xF1A148 && offset <= 0xF1A156) + { + DACWriteWord(offset, data); + return; } else if ((offset >= 0xF10000) && (offset <= 0xF10007)) { @@ -518,18 +551,18 @@ void jerry_word_write(unsigned offset, unsigned data) // Need to handle (unaligned) cases??? return; } - else if ((offset >= 0xF1A148) && (offset < 0xF1A150)) - { - pcm_word_write(offset - 0xF1A148, data); - return; - } else if ((offset >= 0xF10010) && (offset < 0xF10016)) { clock_word_write(offset, data); return; } + // JERRY -> 68K interrupt enables/latches (need to be handled!) + else if (offset >= 0xF10020 && offset <= 0xF10022) + { + } else if ((offset >= 0xF17C00) && (offset < 0xF17C02)) { +//I think this was removed from the Jaguar. If so, then we don't need this...! anajoy_word_write(offset, data); return; }