neuttower/fakelib.c

51 lines
1.3 KiB
C
Raw Normal View History

2020-04-19 15:37:08 +00:00
#include "fakelib.h"
#include "timer.h"
void fakelib_shutup() {
outportb(0x61, inportb(0x61) & 0xfc);
}
void fakelib_init() {
atexit(fakelib_shutup);
}
static unsigned int remaining_ticks;
static unsigned int last_tick;
static unsigned int fnumlow;
void fakelib_write(int reg, int val) {
if (reg == 0xa0) { // writing a new frequency to voice 0
fnumlow = (val & 0xff);
} else if (reg == 0xb0) {
if (val & 0x20) {
unsigned long fnum = ((val & 0x03) << 8) | fnumlow;
unsigned int oct = (val & 0x1c) >> 2;
unsigned long div = (24L << (20 - oct)) / fnum;
unsigned char tmp;
outportb(0x43, 0xb6);
outportb(0x42, div & 0xff);
outportb(0x42, (div >> 8) & 0xff);
outportb(0x61, inportb(0x61) | 0x03);
// todo: guess at duration based on instrument decay
remaining_ticks = 2;
last_tick = timer_counter;
} else {
fakelib_shutup();
remaining_ticks = 0;
}
}
}
void fakelib_tick() {
if (remaining_ticks > 0) {
unsigned int tickdiff = timer_counter - last_tick;
if (tickdiff >= remaining_ticks) {
fakelib_shutup();
remaining_ticks = 0;
} else {
remaining_ticks -= tickdiff;
}
}
last_tick = timer_counter;
}