commit 5546160a531d4245ff1defba20c565f7ffbc6c55
parent a2acd5f1c8acbcab54a64c00fddbda89b52c2e85
Author: prenev <an2qzavok@gmail.com>
Date: Sat, 10 Apr 2021 16:09:57 +0300
rework machine into array from struct
Diffstat:
M | machine.c | | | 164 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
M | machine.h | | | 32 | ++++++++++++++++---------------- |
M | usynth.c | | | 22 | +++++++++++++--------- |
3 files changed, 111 insertions(+), 107 deletions(-)
diff --git a/machine.c b/machine.c
@@ -2,28 +2,33 @@
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
+#include <string.h>
#include "wavetable.h"
#include "machine.h"
#include "tune.h"
-typedef void (*instruction)(VM*, uint8_t);
-
-void vm_fatal(VM*, char*);
-void vm_adsr(VM*);
-
-void i_halt(VM*, uint8_t);
-void i_lit(VM*, uint8_t);
-void i_fetch(VM*, uint8_t);
-void i_op(VM*, uint8_t);
-void i_adsr(VM*, uint8_t);
-void i_wave(VM*, uint8_t);
-void i_note(VM*, uint8_t);
-void i_2dt(VM*, uint8_t);
-void i_dup(VM*, uint8_t);
-void i_drop(VM*, uint8_t);
-void i_swap(VM*, uint8_t);
-void i_add(VM*, uint8_t);
-void i_comb(VM*, uint8_t);
+#define TOS(x) (x[VM_STACK + x[VM_SP] - 1])
+#define STOS(x) (x[VM_STACK + x[VM_SP] - 2])
+#define DATA(x) (x[x[VM_PC]])
+
+typedef void (*instruction)(int16_t*, uint8_t);
+
+void vm_fatal(int16_t*, char*);
+void vm_adsr(int16_t*);
+
+void i_halt(int16_t*, uint8_t);
+void i_lit(int16_t*, uint8_t);
+void i_fetch(int16_t*, uint8_t);
+void i_op(int16_t*, uint8_t);
+void i_adsr(int16_t*, uint8_t);
+void i_wave(int16_t*, uint8_t);
+void i_note(int16_t*, uint8_t);
+void i_2dt(int16_t*, uint8_t);
+void i_dup(int16_t*, uint8_t);
+void i_drop(int16_t*, uint8_t);
+void i_swap(int16_t*, uint8_t);
+void i_add(int16_t*, uint8_t);
+void i_comb(int16_t*, uint8_t);
instruction instructions[128] = {
[I_HALT] = i_halt,
@@ -43,7 +48,7 @@ instruction instructions[128] = {
/*** simple hard-coded program ***/
-int16_t sprog[] = {
+int16_t sprog[1024*3] = {
I_NOTE,
I_2DT,
I_OP|0x0000,
@@ -60,141 +65,136 @@ int16_t sprog[] = {
};
void
-vm_set(VM *vm)
+vm_set(int16_t *vm)
{
- vm->prog = sprog;
- vm->active = 0;
+ memcpy(&vm[VM_PROG_START], sprog, 1024 * 3);
+ vm[VM_ACTIVE] = 0;
}
int16_t
-vm_run(VM *vm)
+vm_run(int16_t *vm)
{
instruction inst;
- if (vm->prog == 0) return 0;
- if (vm->active == 0) return 0;
- vm->halted = 0;
- vm->pc = 0;
- vm->sp = 0;
- vm_adsr(vm);
- while (vm->halted == 0) {
- inst = instructions[0xff & vm->prog[vm->pc]];
+ if (vm[VM_ACTIVE] == 0) return 0;
+ vm[VM_PC] = VM_PROG_START;
+ vm[VM_HALTED] = 0;
+ vm[VM_SP] = 0;
+ //vm_adsr(vm);
+ while (vm[VM_HALTED] == 0) {
+ inst = instructions[0xff & DATA(vm)];
if (inst == 0) vm_fatal(vm, "illegal instruction");
- vm->pc++;
- inst(vm, vm->prog[vm->pc]>>8);
+ vm[VM_PC]++;
+ inst(vm, DATA(vm)>>8);
}
- return vm->stack[vm->sp-1];
+ return TOS(vm);
}
void
-vm_adsr(VM *vm)
+vm_adsr(int16_t *vm)
{
- int i;
- for (i=0; i<16; i++) {
- vm->adsr[i] = vm->status * 0x7fff;
- }
+ //int i;
+ //for (i=0; i<16; i++) {
+ // vm->adsr[i] = vm->status * 0x7fff;
+ //}
}
void
-vm_fatal(VM* vm, char *errstr)
+vm_fatal(int16_t* vm, char *errstr)
{
- dprintf(2, "VM FATAL: %s\n", errstr);
- dprintf(2, "pc = %d\n", vm->pc);
+ dprintf(2, "int16_t FATAL: %s\n", errstr);
+ dprintf(2, "pc = %d\n", vm[VM_PC]);
exit(-1);
}
void
-i_halt(VM *vm, uint8_t arg)
+i_halt(int16_t *vm, uint8_t arg)
{
- vm->halted = 1;
+ vm[VM_HALTED] = 1;
}
void
-i_lit(VM *vm, uint8_t arg)
+i_lit(int16_t *vm, uint8_t arg)
{
- vm->stack[vm->sp] = vm->prog[vm->pc];
- vm->sp++;
- vm->pc++;
+ vm[VM_SP]++;
+ vm[VM_PC]++;
+ TOS(vm) = DATA(vm);
}
void
-i_fetch(VM *vm, uint8_t arg)
+i_fetch(int16_t *vm, uint8_t arg)
{
- vm->stack[vm->sp-1] = vm->prog[vm->stack[vm->sp-1]];
+ TOS(vm) = vm[TOS(vm)];
}
void
-i_op(VM *vm, uint8_t arg)
+i_op(int16_t *vm, uint8_t arg)
{
- vm->op[arg] += vm->stack[vm->sp-1];
- vm->stack[vm->sp-1] = vm->op[arg];
+ vm[VM_OPERATORS + arg] += TOS(vm);
+ TOS(vm) = vm[VM_OPERATORS + arg];
}
void
-i_adsr(VM *vm, uint8_t arg)
+i_adsr(int16_t *vm, uint8_t arg)
{
- vm->stack[vm->sp] = vm->adsr[arg];
- vm->sp++;
}
void
-i_wave(VM *vm, uint8_t arg)
+i_wave(int16_t *vm, uint8_t arg)
{
uint16_t d;
- d = ((uint16_t)vm->stack[vm->sp-1]) / WT_LENGTH;
+ d = ((uint16_t)TOS(vm)) / WT_LENGTH;
d = d%WT_LENGTH;
- vm->stack[vm->sp-1] = wavetable[arg][d];
+ TOS(vm) = wavetable[arg][d];
}
void
-i_note(VM *vm, uint8_t arg)
+i_note(int16_t *vm, uint8_t arg)
{
- vm->stack[vm->sp] = vm->key;
- vm->sp++;
+ vm[VM_SP]++;
+ TOS(vm) = vm[VM_KEY];
}
void
-i_2dt(VM *vm, uint8_t arg)
+i_2dt(int16_t *vm, uint8_t arg)
{
- uint8_t note = vm->stack[vm->sp-1];
+ uint8_t note = TOS(vm);
int16_t dt = tune[note%12] * (1 << (note/12));
- vm->stack[vm->sp-1] = dt;
+ TOS(vm) = dt;
}
void
-i_dup(VM *vm, uint8_t arg)
+i_dup(int16_t *vm, uint8_t arg)
{
- vm->stack[vm->sp] = vm->stack[vm->sp-1];
- vm->sp++;
+ vm[VM_SP]++;
+ TOS(vm) = STOS(vm);
}
void
-i_drop(VM *vm, uint8_t arg)
+i_drop(int16_t *vm, uint8_t arg)
{
- vm->sp--;
+ vm[VM_SP]--;
}
void
-i_swap(VM *vm, uint8_t arg)
+i_swap(int16_t *vm, uint8_t arg)
{
int16_t b;
- b = vm->stack[vm->sp-1];
- vm->stack[vm->sp-1] = vm->stack[vm->sp-2];
- vm->stack[vm->sp-2] = b;
+ b = TOS(vm);
+ TOS(vm) = STOS(vm);
+ STOS(vm) = b;
}
void
-i_add(VM *vm, uint8_t arg)
+i_add(int16_t *vm, uint8_t arg)
{
- vm->stack[vm->sp-2] += vm->stack[vm->sp-2];
- vm->sp--;
+ STOS(vm) += TOS(vm);
+ vm[VM_SP]--;
}
void
-i_comb(VM *vm, uint8_t arg)
+i_comb(int16_t *vm, uint8_t arg)
{
- vm->stack[vm->sp-2] =
- vm->stack[vm->sp-1] * vm->stack[vm->sp-2]
- / 0x7fff;
- vm->sp--;
+ STOS(vm) = TOS(vm) * STOS(vm) / 0x7fff;
+ vm[VM_SP]--;
}
diff --git a/machine.h b/machine.h
@@ -1,3 +1,4 @@
+/* VM's instructions */
enum {
I_HALT = 0,
/* * * * * */
@@ -17,22 +18,21 @@ enum {
I_COMB,
};
-#define SDEPTH 256
-
-typedef struct VM VM;
-struct VM {
- int active;
- int halted;
- int status;
- uint8_t key;
- int16_t stack[SDEPTH];
- int16_t op[16];
- int16_t adsr[16];
- int16_t sp;
- int16_t *prog;
- int16_t pc;
+/* VM's memory state */
+enum {
+ VM_PC,
+ VM_ACTIVE,
+ VM_HALTED,
+ VM_KEY,
+ VM_KEY_ON,
+ VM_OPERATORS = 128,
+ VM_SP,
+ VM_STACK = 256,
+ VM_PROG_START = 1024,
+ VM_MEM_END = 4096,
};
-void vm_set(VM*);
-int16_t vm_run(VM*);
+int16_t* vm_malloc(void);
+void vm_set(int16_t*);
+int16_t vm_run(int16_t*);
diff --git a/usynth.c b/usynth.c
@@ -11,7 +11,7 @@
struct sio_hdl *sh;
size_t bs;
int16_t *sbuf;
-VM vm;
+int16_t* vm;
void note_on(uint8_t*);
void note_off(uint8_t*);
@@ -45,11 +45,10 @@ main(void)
m_init("midithru/0");
m_vector.note_on = note_on;
m_vector.note_off = note_off;
- vm_set(&vm);
- //vm.active = 1;
- //vm.status = 1;
- //vm.key = 45;
+ vm = malloc(4096);
+
+ vm_set(vm);
while (1){
size_t n;
@@ -62,14 +61,19 @@ main(void)
void
note_on(uint8_t *m)
{
- vm.active = 1;
- vm.status = 1;
- vm.key = m[2];
+ vm[VM_ACTIVE] = 1;
+ vm[VM_KEY] = m[2];
+ vm[VM_KEY_ON] = 1;
}
void
note_off(uint8_t *m)
{
+ if (vm[VM_KEY] == m[2]) {
+ // temporary
+ vm[VM_KEY_ON] = 0;
+ vm[VM_ACTIVE] = 0;
+ }
}
void
@@ -77,6 +81,6 @@ fillbuf(int16_t* buf, size_t n)
{
size_t i;
for (i=0; i < n; i+=2) {
- buf[i] = buf[i+1] = vm_run(&vm);
+ buf[i] = buf[i+1] = vm_run(vm);
}
}