2019-06-02 02:09:45 +00:00
|
|
|
|
|
|
|
#pragma opt_code_speed
|
|
|
|
|
2019-06-02 14:53:39 +00:00
|
|
|
#include "bios.h"
|
2019-06-02 02:09:45 +00:00
|
|
|
|
|
|
|
extern byte* MUZPC; // music PC
|
|
|
|
extern byte* MUZSP; // music SP
|
|
|
|
extern byte PVOLAB; // channels A and B volume
|
|
|
|
extern byte PVOLMC; // channel C volume and noise mask
|
|
|
|
extern byte VOICES; // voices mmask
|
|
|
|
extern byte DURAT; // note duration
|
|
|
|
|
|
|
|
__sfr __at(0x10) hw_tonmo;
|
|
|
|
__sfr __at(0x11) hw_tonea;
|
|
|
|
__sfr __at(0x12) hw_toneb;
|
|
|
|
__sfr __at(0x13) hw_tonec;
|
|
|
|
__sfr __at(0x14) hw_vibra;
|
|
|
|
__sfr __at(0x15) hw_volc;
|
|
|
|
__sfr __at(0x16) hw_volab;
|
|
|
|
__sfr __at(0x17) hw_voln;
|
|
|
|
__sfr __at(0x18) hw_sndbx;
|
|
|
|
|
|
|
|
extern void portOut(word portVal) __z88dk_fastcall;
|
|
|
|
|
|
|
|
static byte NEXT(void) {
|
|
|
|
return *MUZPC++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void PUSH(byte b) {
|
|
|
|
*++MUZSP = b;
|
|
|
|
}
|
|
|
|
|
|
|
|
static byte POP() {
|
|
|
|
return *MUZSP--;
|
|
|
|
}
|
|
|
|
|
|
|
|
static byte DECTOP() {
|
|
|
|
return --(*MUZSP);
|
|
|
|
}
|
|
|
|
|
|
|
|
void music_update(void) {
|
|
|
|
byte op = NEXT();
|
|
|
|
if (op < 0x80) {
|
|
|
|
DURAT = op;
|
|
|
|
op = VOICES;
|
|
|
|
if (op & 0x01) hw_voln = NEXT();
|
|
|
|
if (op & 0x02) hw_vibra = NEXT();
|
|
|
|
if (op & 0x04 && (hw_tonec = *MUZPC)) {
|
|
|
|
hw_volc = PVOLMC;
|
|
|
|
}
|
|
|
|
if (op & 0x08) MUZPC++;
|
|
|
|
if (op & 0x10) {
|
|
|
|
if (!(hw_toneb = *MUZPC))
|
|
|
|
op ^= 0x10;
|
|
|
|
}
|
|
|
|
if (op & 0x20) MUZPC++;
|
|
|
|
if (op & 0x40) {
|
|
|
|
if (!(hw_tonea = *MUZPC))
|
|
|
|
op ^= 0x40;
|
|
|
|
}
|
|
|
|
if (op & 0x80) MUZPC++;
|
|
|
|
hw_volab =
|
|
|
|
((op & 0x40) ? (PVOLAB & 0x0f) : 0) |
|
|
|
|
((op & 0x10) ? (PVOLAB & 0xf0) : 0);
|
|
|
|
} else if (op < 0x88) {
|
|
|
|
portOut( NEXT() | ((op-0x70)<<8) );
|
|
|
|
} else if (op == 0x88) {
|
2019-06-02 14:53:39 +00:00
|
|
|
for (byte i=0; i<8; i++) {
|
2019-06-02 02:09:45 +00:00
|
|
|
portOut( NEXT() | (0x17-i) );
|
2019-06-02 14:53:39 +00:00
|
|
|
}
|
2019-06-02 02:09:45 +00:00
|
|
|
} else switch (op & 0xf0) {
|
|
|
|
case 0x90:
|
|
|
|
VOICES = NEXT();
|
|
|
|
break;
|
|
|
|
case 0xa0:
|
|
|
|
PUSH(op - 0x9f);
|
|
|
|
break;
|
|
|
|
case 0xb0:
|
|
|
|
PVOLAB = NEXT();
|
|
|
|
PVOLMC = NEXT();
|
|
|
|
break;
|
|
|
|
case 0xc0:
|
|
|
|
if (DECTOP()) {
|
|
|
|
MUZPC = (byte*)*(word*)MUZPC;
|
|
|
|
} else {
|
|
|
|
MUZPC += 2;
|
|
|
|
POP();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0xd0:
|
|
|
|
MUZPC += op & 0xf;
|
|
|
|
break;
|
|
|
|
case 0xe0:
|
|
|
|
// REST
|
|
|
|
if (op == 0xe1) {
|
|
|
|
hw_volab = hw_volc = 0;
|
|
|
|
DURAT = *MUZPC++;
|
|
|
|
} else {
|
|
|
|
// TODO: legatto/stacatto
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0xf0:
|
|
|
|
hw_volab = hw_volc = 0;
|
|
|
|
VOICES = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|