#include "speaker.h" #include "timer.h" // Теперь здесь виден extern uint32_t system_ticks #include "../kernel/io.h" void sleep_ms(uint32_t ms) { // 1 тик = 10 мс на частоте 100 Гц uint32_t ticks_to_wait = ms / 10; if (ticks_to_wait == 0) ticks_to_wait = 1; // Защита от слишком маленького интервала uint32_t start_ticks = system_ticks; // Ждем, пока разница тиков не достигнет нужного значения while ((system_ticks - start_ticks) < ticks_to_wait) { // Аппаратно засыпаем до следующего прерывания PIT __asm__ __volatile__("hlt"); } } void speaker_play(uint32_t frequency) { if (frequency == 0) return; uint32_t divisor = 1193182 / frequency; // Настраиваем Канал 2 PIT (порт 0x43, режим 0xB6) outb(0x43, 0xB6); // Передаем делитель в порт данных Канала 2 (0x42) outb(0x42, (uint8_t)(divisor & 0xFF)); outb(0x42, (uint8_t)((divisor >> 8) & 0xFF)); // Подключаем PIT к динамику через порт управления системными функциями uint8_t speaker_state = inb(0x61); if ((speaker_state & 3) != 3) { outb(0x61, speaker_state | 3); } } void speaker_stop(void) { // Отключаем динамик, сбрасывая 0 и 1 биты uint8_t speaker_state = inb(0x61) & 0xFC; outb(0x61, speaker_state); } void speaker_beep(uint32_t frequency, uint32_t duration_ms) { speaker_play(frequency); sleep_ms(duration_ms); // Наш халяльный sleep по прерываниям speaker_stop(); }