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