From ccc649bfc14de5858cf227ada5478bdc08effd4c Mon Sep 17 00:00:00 2001 From: Jorj Bauer Date: Wed, 31 May 2017 18:17:25 -0400 Subject: [PATCH] working on mockingboard interrupts --- apple/applevm.cpp | 4 +++- apple/sy6522.cpp | 35 +++++++++++++++++++++++++++++++++-- apple/sy6522.h | 13 +++++++++++++ cpu.cpp | 10 ++++++++++ cpu.h | 4 ++++ sdl/sdl-speaker.cpp | 7 ++++++- 6 files changed, 69 insertions(+), 4 deletions(-) diff --git a/apple/applevm.cpp b/apple/applevm.cpp index ffdfc6c..85cfa7f 100644 --- a/apple/applevm.cpp +++ b/apple/applevm.cpp @@ -23,8 +23,10 @@ AppleVM::AppleVM() parallel = new ParallelCard(); ((AppleMMU *)mmu)->setSlot(1, parallel); + mockingboard = NULL; + /* mockingboard = new Mockingboard(); - ((AppleMMU *)mmu)->setSlot(4, mockingboard); + ((AppleMMU *)mmu)->setSlot(4, mockingboard);*/ #ifdef TEENSYDUINO teensyClock = new TeensyClock((AppleMMU *)mmu); diff --git a/apple/sy6522.cpp b/apple/sy6522.cpp index 059ca25..39f4022 100644 --- a/apple/sy6522.cpp +++ b/apple/sy6522.cpp @@ -1,6 +1,8 @@ #include "sy6522.h" #include +#include "globals.h" + SY6522::SY6522() { ORB = ORA = 0; @@ -25,7 +27,7 @@ uint8_t SY6522::read(uint8_t address) case SY_DDRA: return DDRA; case SY_TMR1L: - // FIXME: also updates IFR? + IFR &= ~SY_IR_TIMER1; return (T1_CTR & 0xFF); case SY_TMR1H: return (T1_CTR >> 8); @@ -34,7 +36,7 @@ uint8_t SY6522::read(uint8_t address) case SY_TMR1HL: return (T1_CTR_LATCH >> 8); case SY_TMR2L: - // FIXME: alos udpates IFR? + IFR &= ~SY_IR_TIMER2; return (T2_CTR & 0xFF); case SY_TMR2H: return (T2_CTR >> 8); @@ -82,6 +84,15 @@ uint8_t SY6522::read(uint8_t address) return; case SY_TMR1H: + IFR &= SY_IR_TIMER1; + + // Update IFR? + IFR &= 0x7F; + if (IFR & IER) { + // an interrupt is happening; keep the IE flag on + IFR |= 0x80; + } + // FIXME: clear interrupt flag T1_CTR_LATCH = (T1_CTR_LATCH & 0x00FF) | (val << 8); T1_CTR = T1_CTR_LATCH; @@ -145,6 +156,26 @@ uint8_t SY6522::read(uint8_t address) void SY6522::update(uint32_t cycles) { + /* Update 6522 timers */ + + // ... + /* + SY_IR_CA2 = 1, + SY_IR_CA1 = 2, + SY_IR_SHIFTREG = 4, + SY_IR_CB2 = 8, + SY_IR_CB1 = 16, + SY_IR_TIMER2 = 32, + SY_IR_TIMER1 = 64, + SY_IER_SETCLEAR = 128, + SY_IFR_IRQ = 128 + */ + /* Check for 6522 interrupts */ + if (IFR & 0x80) { + g_cpu->stageIRQ(); + } + + /* Update the attached 8910 chip(s) */ ay8910[0].update(cycles); } diff --git a/apple/sy6522.h b/apple/sy6522.h index 74b83f8..46107c9 100644 --- a/apple/sy6522.h +++ b/apple/sy6522.h @@ -25,6 +25,19 @@ enum { SY_ORANOHS = 0x0f // ORA_NO_HS }; +// IFR and IER share the names of all but the high bit +enum { + SY_IR_CA2 = 1, + SY_IR_CA1 = 2, + SY_IR_SHIFTREG = 4, + SY_IR_CB2 = 8, + SY_IR_CB1 = 16, + SY_IR_TIMER2 = 32, + SY_IR_TIMER1 = 64, + SY_IER_SETCLEAR = 128, + SY_IFR_IRQ = 128 +}; + class SY6522 { public: SY6522(); diff --git a/cpu.cpp b/cpu.cpp index f3802c3..b81f9cf 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -407,6 +407,7 @@ void Cpu::Reset() x = 0; y = 0; flags = F_Z | F_UNK; // FIXME: is that F_UNK flag right here? + irqPending = false; if (mmu) { pc = readmem(0xFFFC) | (readmem(0xFFFD) << 8); @@ -495,6 +496,11 @@ uint8_t Cpu::Run(uint8_t numSteps) uint8_t Cpu::step() { + if (irqPending) { + irqPending = false; + irq(); + } + uint8_t m = readmem(pc++); optype_t opcode = opcodes[m]; @@ -1050,3 +1056,7 @@ uint16_t Cpu::popS16() return (msb << 8) | lsb; } +void Cpu::stageIRQ() +{ + irqPending = true; +} diff --git a/cpu.h b/cpu.h index 00b87cc..29877fb 100644 --- a/cpu.h +++ b/cpu.h @@ -45,6 +45,8 @@ class Cpu { uint8_t SP(); uint8_t P(); + void stageIRQ(); + protected: // Stack manipulation void pushS8(uint8_t b); @@ -64,6 +66,8 @@ class Cpu { uint8_t flags; uint32_t cycles; + + bool irqPending; MMU *mmu; }; diff --git a/sdl/sdl-speaker.cpp b/sdl/sdl-speaker.cpp index 54ab85f..2308610 100644 --- a/sdl/sdl-speaker.cpp +++ b/sdl/sdl-speaker.cpp @@ -133,14 +133,19 @@ void SDLSpeaker::maintainSpeaker(uint32_t c) // The "terribad" audio gets two shares. THis means we've got 8 total // "voices" -- 6 from the mockingboard and 2 from the built-in. 8 is // a great number for dividing. :) - mixerValue += (toggleState ? 0xFF : 0x00); + mixerValue += (toggleState ? 0x1FF : 0x00); numMixed += 2; +#if 0 if (numMixed != 8) { printf("SPEAKER FAIL - should always be 8\n"); } mixerValue >>= 3; // divide by 8 +#else + mixerValue /= numMixed; +#endif + // FIXME: g_volume