text: #include <neonix/neonix.h>
  #include <neonix/io.h>
  #include <neonix/interrupt.h>
  #include <neonix/assert.h>
  #include <neonix/debug.h>
  #include <neonix/task.h>
  
  #define PIT_CHAN0_REG 0X40
  #define PIT_CHAN2_REG 0X42
  #define PIT_CTRL_REG 0X43
  
  #define HZ 100
  #define OSCILLATOR 1193182
  #define CLOCK_COUNTER (OSCILLATOR / HZ)
  #define JIFFY (1000 / HZ)
  
  #define SPEAKER_REG 0x61
  // 440HZ是国际标准音高,432HZ比较符合黄金分割
  #define BEEP_HZ 432
  #define BEEP_COUNTER (OSCILLATOR / BEEP_HZ)
  
  u32 volatile jiffies = 0;  // 全局时间片
  u32 jiffy = JIFFY;
  
  u32 volatile beeping = 0;
  
  void start_beep()
  {
    if (!beeping)
    {
      outb(SPEAKER_REG, inb(SPEAKER_REG) | 0b11);
    }
    beeping = jiffies + 5;
  }
  
  void stop_beep()
  {
    if (beeping && jiffies > beeping)
    {
      outb(SPEAKER_REG, inb(SPEAKER_REG) & 0xfc);
      beeping = 0;
    }
  }
  
  void clock_handler(int vector)
  {
    assert(vector == 0x20);
    send_eoi(vector); // 发送中断处理结束
  
    stop_beep();   // 检测并停止蜂鸣器
    task_wakeup(); // 唤醒睡眠结束的任务
  
    jiffies++;
    //DEBUGK("clock jiffies %d ...\n", jiffies);
  
    task_t *task = running_task();
    assert(task->magic == NEONIX_MAGIC);
  
    task->jiffies = jiffies;
    task->ticks--;
    if (!task->ticks)
    {
      schedule();
    }
  }
  
  void pit_init()
  {
    // 配置计数器 0 时钟
    outb(PIT_CTRL_REG, 0b00110100);
    outb(PIT_CHAN0_REG, CLOCK_COUNTER & 0xff);
    outb(PIT_CHAN0_REG, (CLOCK_COUNTER >> 8) & 0xff);
  
    // 配置计数器 2 蜂鸣器
    outb(PIT_CTRL_REG, 0b10110110);
    outb(PIT_CHAN2_REG, (u8)BEEP_COUNTER);
    outb(PIT_CHAN2_REG, (u8)(BEEP_COUNTER >> 8));
  }
  
  void clock_init()
  {
    pit_init();
    set_interrupt_handler(IRQ_CLOCK, clock_handler);
    set_interrupt_mask(IRQ_CLOCK, true);
  }
  