usynth

simple midi synth for sndio
git clone git://nsmpr.xyz/usynth.git
Log | Files | Refs

machine.c (2640B)


      1 #include <stdlib.h>
      2 #include <assert.h>
      3 #include <stdio.h>
      4 #include <stdint.h>
      5 #include <string.h>
      6 #include "wavetable.h"
      7 #include "machine.h"
      8 #include "tune.h"
      9 
     10 #define TOS(x)  (x[VM_STACK + x[VM_SP] - 1])
     11 #define STOS(x) (x[VM_STACK + x[VM_SP] - 2])
     12 #define DATA(x) (x[x[VM_PC]])
     13 
     14 struct Iset vm_iset[] = {
     15         [I_HALT]  = { i_halt,  "halt"  },
     16         [I_LIT]   = { i_lit,   "lit"   },
     17         [I_FETCH] = { i_fetch, "fetch" },
     18         [I_OP]    = { i_op,    "op"    },
     19         [I_ADSR]  = { i_adsr,  "adsr"  },
     20         [I_WAVE]  = { i_wave,  "wave"  },
     21         [I_2DT]   = { i_2dt,   "2dt"   },
     22         [I_DUP]   = { i_dup,   "dup"   },
     23         [I_DROP]  = { i_drop,  "drop"  },
     24         [I_SWAP]  = { i_swap,  "swap"  },
     25         [I_ADD]   = { i_add,   "add"   },
     26         [I_COMB]  = { i_comb,  "comb"  },
     27 	            { NULL,    NULL    },
     28 };
     29 
     30 
     31 
     32 void vm_fatal(int16_t*, char*);
     33 void vm_adsr(int16_t*);
     34 
     35 int16_t
     36 vm_run(int16_t *vm)
     37 {
     38 	void (*inst)(int16_t*, uint8_t);
     39 	if (vm[VM_ACTIVE] == 0) return 0;
     40 	vm[VM_PC] = VM_PROG_START;
     41 	vm[VM_HALTED] = 0;
     42 	vm[VM_SP] = 0;
     43 	//vm_adsr(vm);
     44 	while (vm[VM_HALTED] == 0) {
     45 		inst = vm_iset[0xff & DATA(vm)].instr;
     46 		if (inst == 0) vm_fatal(vm, "illegal instruction");
     47 		vm[VM_PC]++;
     48 		inst(vm, 0);
     49 	}
     50 	return TOS(vm);
     51 }
     52 
     53 void
     54 vm_adsr(int16_t *vm)
     55 {
     56 	//int i;
     57 	//for (i=0; i<16; i++) {
     58 	//	vm->adsr[i] = vm->status * 0x7fff;
     59 	//}
     60 }
     61 
     62 void
     63 vm_fatal(int16_t* vm, char *errstr)
     64 {
     65 	dprintf(2, "int16_t FATAL: %s\n", errstr);
     66 	dprintf(2, "pc  = %hd\n", vm[VM_PC]);
     67 	dprintf(2, "mem = %hd\n", vm[vm[VM_PC]]);
     68 	exit(-1);
     69 }
     70 
     71 void
     72 i_halt(int16_t *vm, uint8_t arg)
     73 {
     74 	vm[VM_HALTED] = 1;
     75 }
     76 
     77 void
     78 i_lit(int16_t *vm, uint8_t arg)
     79 {
     80 	vm[VM_SP]++;
     81 	TOS(vm) = vm[vm[VM_PC]];
     82 	vm[VM_PC]++;
     83 }
     84 
     85 void
     86 i_fetch(int16_t *vm, uint8_t arg)
     87 {
     88 	TOS(vm) = vm[TOS(vm)];
     89 }
     90 
     91 void
     92 i_op(int16_t *vm, uint8_t arg)
     93 {
     94 	vm[VM_OPERATORS + arg] += TOS(vm);
     95 	TOS(vm) = vm[VM_OPERATORS + arg];
     96 }
     97 
     98 void
     99 i_adsr(int16_t *vm, uint8_t arg)
    100 {
    101 }
    102 
    103 void
    104 i_wave(int16_t *vm, uint8_t arg)
    105 {
    106 	uint16_t d;
    107 	d = ((uint16_t)TOS(vm)) * WT_LENGTH / 0xffff;
    108 	d = d%WT_LENGTH;
    109 	TOS(vm) = wavetable[arg][d];
    110 }
    111 
    112 void
    113 i_2dt(int16_t *vm, uint8_t arg)
    114 {
    115 	uint8_t note = TOS(vm);
    116 	int16_t dt = tune[note%12] * (1 << (note/12));
    117 	TOS(vm) = dt;
    118 }
    119 
    120 void
    121 i_dup(int16_t *vm, uint8_t arg)
    122 {
    123 	vm[VM_SP]++;
    124 	TOS(vm) = STOS(vm);
    125 }
    126 
    127 void
    128 i_drop(int16_t *vm, uint8_t arg)
    129 {
    130 	vm[VM_SP]--;
    131 }
    132 
    133 void
    134 i_swap(int16_t *vm, uint8_t arg)
    135 {
    136 	int16_t b;
    137 	b = TOS(vm);
    138 	TOS(vm) = STOS(vm);
    139 	STOS(vm) = b;
    140 }
    141 
    142 void
    143 i_add(int16_t *vm, uint8_t arg)
    144 {
    145 	STOS(vm) += TOS(vm);
    146 	vm[VM_SP]--;
    147 }
    148 
    149 void
    150 i_comb(int16_t *vm, uint8_t arg)
    151 {
    152 	STOS(vm) = TOS(vm) * STOS(vm) / 0x7fff;
    153 	vm[VM_SP]--;
    154 }
    155