diff --git a/pong/pong.cpp b/pong/pong.cpp index bfede80d..49030f22 100644 --- a/pong/pong.cpp +++ b/pong/pong.cpp @@ -198,7 +198,17 @@ int main(int argc, char* argv[]) ReadInput(); Update(); UpdateUI(); - Thread::USleep(50 * 1000); + const unsigned sleepms = 50; + Thread::USleep(sleepms * 1000); + if ( soundleft < 0 ) { continue; } + if ( soundleft <= 50 ) + { + System::Sound::SetFrequency(0); + } + else + { + soundleft -= sleepms; + } } return 0; diff --git a/sortix/isr.cpp b/sortix/isr.cpp index c09676fb..c01c72b8 100644 --- a/sortix/isr.cpp +++ b/sortix/isr.cpp @@ -58,10 +58,12 @@ const char* exceptions[] = { "Divide by zero", "Debug", "Non maskable interrupt" //Sortix::Log::PrintF("IRQ eax=%u, int_no=%u, err_code=%u, eip=0x%x!\n", Regs->eax, Regs->int_no, Regs->err_code, Regs->eip); } - if ( Regs->int_no < 32 || 48 < Regs->int_no ) { Sortix::PanicF("IRQ eax=%u, int_no=%u, err_code=%u, eip=%u!", Regs->eax, Regs->int_no, Regs->err_code, Regs->eip); } - // TODO! IRQ 7 and 15 might be spurious and might need to be ignored. // See http://wiki.osdev.org/PIC for details (section Spurious IRQs). + if ( Regs->int_no == 32 + 7 || Regs->int_no == 32 + 15 ) { return; } + + if ( Regs->int_no < 32 || 48 < Regs->int_no ) { Sortix::PanicF("IRQ eax=%u, int_no=%u, err_code=%u, eip=%u!", Regs->eax, Regs->int_no, Regs->err_code, Regs->eip); } + // Send an EOI (end of interrupt) signal to the PICs. if (Regs->int_no >= 40) { Sortix::X86::OutPortB(0xA0, 0x20); } // Send reset signal to slave if this interrupt involved the slave. diff --git a/sortix/scheduler.cpp b/sortix/scheduler.cpp index f94e20bc..e411e83a 100644 --- a/sortix/scheduler.cpp +++ b/sortix/scheduler.cpp @@ -34,6 +34,8 @@ #include "iprintable.h" #include "log.h" +#include "sound.h" // HACK + namespace Sortix { const bool LOG_SWITCHING = false; @@ -68,6 +70,7 @@ namespace Sortix _prevThread = this; _nextThread = this; _inThisList = NULL; + _nextSleepingThread = NULL; } Thread::~Thread() @@ -145,6 +148,7 @@ namespace Sortix { if ( miliseconds == 0 ) { return; } + _nextSleepingThread = NULL; Thread* Thread = Scheduler::firstSleeping; if ( Thread == NULL ) @@ -336,9 +340,11 @@ namespace Sortix void Switch(CPU::InterruptRegisters* R, uintmax_t TimePassed) { //Log::PrintF("Scheduling while at eip=0x%p...", R->eip); + //Log::Print("\n"); if ( currentThread != NoopThread && currentThread->GetProcess() && sigintpending ) { + Sound::Mute(); const char* programname = "sh"; R->ebx = (uint32_t) programname; SysExecute(R); @@ -438,7 +444,7 @@ namespace Sortix void WakeSleeping(uintmax_t TimePassed) { while ( firstSleeping != NULL ) - { + { if ( TimePassed < firstSleeping->_sleepMilisecondsLeft ) { firstSleeping->_sleepMilisecondsLeft -= TimePassed; break; } TimePassed -= firstSleeping->_sleepMilisecondsLeft; @@ -446,7 +452,7 @@ namespace Sortix firstSleeping->SetState(Thread::State::RUNNABLE); Thread* Next = firstSleeping->_nextSleepingThread; firstSleeping->_nextSleepingThread = NULL; - firstSleeping = Next; + firstSleeping = Next; } } diff --git a/sortix/time.cpp b/sortix/time.cpp index 4d88cd2d..2486b936 100644 --- a/sortix/time.cpp +++ b/sortix/time.cpp @@ -33,9 +33,6 @@ #include "iprintable.h" #include "log.h" -#include "pong.h" -#include "conway.h" - #if !defined(PLATFORM_X86_FAMILY) #error No time subsystem is available for this CPU #endif @@ -59,16 +56,8 @@ namespace Sortix #endif } - void Init() + void RequestIQR0() { - // Initialize our variables. - Ticks = 0; - Miliseconds = 0; - - // First, register our timer callback. - register_interrupt_handler(IRQ0, &OnIRQ0); - register_interrupt_handler(177, &OnInt177); - // The value we send to the PIT is the value to divide it's input clock // (1193180 Hz) by, to get our required frequency. Important to note is // that the divisor must be small enough to fit into 16-bits. @@ -86,19 +75,35 @@ namespace Sortix CPU::OutPortB(0x40, H); } + bool didUglyIRQ0Hack; + + void Init() + { + // Initialize our variables. + Ticks = 0; + Miliseconds = 0; + + // First, register our timer callback. + register_interrupt_handler(IRQ0, &OnIRQ0); + register_interrupt_handler(177, &OnInt177); + + didUglyIRQ0Hack = false; + + RequestIQR0(); + } + void OnIRQ0(CPU::InterruptRegisters* Regs) { Ticks++; -#ifdef PONG - Pong::OnFuture(); return; -#elif defined(CONWAY) - Conway::OnFuture(); return; -#endif - // Let the scheduler switch to the next task. // TODO: Let the scheduler know how long has passed. Scheduler::Switch(Regs, 1000/Frequency); + + // TODO: There is a horrible bug that causes Sortix to only receive + // one IRQ0 on my laptop, but it works in virtual machines. But + // re-requesting an addtional time seems to work. Hacky and ugly. + if ( !didUglyIRQ0Hack ) { RequestIQR0(); didUglyIRQ0Hack = true; } } // TODO: Implement all the other useful functions regarding tiem.