PC speaker support

This commit is contained in:
Jeremy Penner 2020-04-19 11:37:08 -04:00
parent 5b5ad34c90
commit 88d2d8e786
29 changed files with 90 additions and 4 deletions

22
adlib.c
View file

@ -1,5 +1,6 @@
#include "adlib.h"
int adlib_present;
static void adlib_wait(int delay) {
int i;
for (i = 0; i < delay; i ++) adlib_read();
@ -20,7 +21,22 @@ void adlib_reset() {
}
}
void adlib_init() {
adlib_reset();
atexit(adlib_reset);
void adlib_detect() {
int status1, status2;
adlib_write(4, 0x60);
adlib_write(4, 0x80);
status1 = adlib_read();
adlib_write(2, 0xff);
adlib_write(4, 0x21);
adlib_wait(160);
status2 = adlib_read();
adlib_present = (status1 & 0xe0) == 0 && (status2 & 0xe0) == 0xc0;
}
void adlib_init() {
adlib_detect();
if (adlib_present) {
adlib_reset();
atexit(adlib_reset);
}
}

View file

@ -1,5 +1,6 @@
#include <dos.h>
extern int adlib_present;
void adlib_init();
#define adlib_read() inp(0x388)
void adlib_write(int reg, int val);

BIN
boot.jim

Binary file not shown.

BIN
debug.jim

Binary file not shown.

BIN
defs.jim

Binary file not shown.

BIN
end.jim

Binary file not shown.

Binary file not shown.

51
fakelib.c Executable file
View file

@ -0,0 +1,51 @@
#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;
}

3
fakelib.h Executable file
View file

@ -0,0 +1,3 @@
void fakelib_init();
void fakelib_write(int reg, int val);
void fakelib_tick();

Binary file not shown.

BIN
game.jim

Binary file not shown.

BIN
input.jim

Binary file not shown.

BIN
jiles.jim

Binary file not shown.

BIN
job.jim

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
level.jim

Binary file not shown.

BIN
map.jim

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sound.jim

Binary file not shown.

BIN
state.jim

Binary file not shown.

View file

@ -18,6 +18,7 @@
#include "jorth.h"
#include "egamap.h"
#include "adlib.h"
#include "fakelib.h"
/*** T E X T ***/
char far *font = NULL;
@ -270,6 +271,8 @@ void game_init() {
timer_init(TIMER_30HZ);
text_init();
adlib_init();
fakelib_init();
timer_setcallback(fakelib_tick);
loadscr("title");
/* f = fopen("TITLE.TIF", "rb");
@ -407,11 +410,20 @@ void f_drawportrait() {
DROP(1);
}
int use_adlib;
void f_adlib() {
adlib_write(TOP().u, ST1().u);
if (use_adlib) {
adlib_write(TOP().u, ST1().u);
} else {
fakelib_write(TOP().u, ST1().u);
}
DROP(2);
}
void f_adlib_present() {
PUSHI(adlib_present);
}
cell f_atexit;
void f_cleanup() {
f_execcp(f_atexit);
@ -827,6 +839,9 @@ void game_f_init(char *exe, char *bootjor) {
CDEF("boss", f_showboss);
CDEF("system", f_system);
CDEF("adlib!", f_adlib);
CDEF("adlib?", f_adlib_present);
PCONST("use-adlib", &use_adlib);
use_adlib = adlib_present;
CDEF("mouseshow", f_mouseshow);
CDEF("mousehide", f_mousehide);

BIN
timer.jim

Binary file not shown.

BIN
title.jim

Binary file not shown.