vsm.c (2833B)
1 #include <u.h> 2 #include <libc.h> 3 4 #include "vsm.h" 5 6 /* Instructions */ 7 void i_NOP(void) 8 { 9 } 10 11 /* ALU: */ 12 void i_ADD(void) 13 { 14 *(dsp - 1) += *dsp; 15 dsp--; 16 } 17 18 void i_SUB(void) 19 { 20 *(dsp - 1) -= *dsp; 21 dsp--; 22 } 23 24 void i_AND(void) 25 { 26 *(dsp - 1) &= *dsp; 27 dsp++; 28 } 29 30 void i_OR(void) 31 { 32 *(dsp - 1) |= *dsp; 33 dsp++; 34 } 35 36 void i_XOR(void) 37 { 38 *(dsp - 1) ^= *dsp; 39 dsp++; 40 } 41 42 43 /* Stack Manipulation: */ 44 void i_DROP(void) 45 { 46 dsp--; 47 } 48 49 void i_DUP(void) 50 { 51 *(dsp + 1) = *dsp; 52 dsp++; 53 } 54 55 void i_OVER(void) 56 { 57 *(dsp + 1) = *(dsp - 1); 58 dsp++; 59 } 60 61 void i_SWAP(void) 62 { 63 *(rsp + 1) = *dsp; 64 *dsp = *(dsp - 1); 65 *(dsp - 1) = *(rsp + 1); 66 } 67 68 void i_TOR(void) 69 { 70 *(rsp + 1) = *dsp; 71 rsp++; 72 dsp--; 73 } 74 75 void i_FROMR(void) 76 { 77 *(dsp + 1) = *rsp; 78 rsp--; 79 dsp++; 80 } 81 82 /* Memory Management: */ 83 void i_STORE(void) 84 { 85 mapset(*dsp, dsp - 1); 86 dsp -= 2; 87 } 88 89 void i_FETCH(void) 90 { 91 CELL *r; 92 r = mapget(*dsp); 93 if (r != nil) *dsp = *r; 94 else *dsp = 0; 95 } 96 97 /* Literals: */ 98 void i_LIT(void) 99 { 100 CELL *r; 101 r = mapget(pc + 1); 102 if (r != nil) *(dsp + 1) = *r; 103 else { 104 *(dsp + 1) = 0; 105 } 106 dsp++; 107 pc++; 108 } 109 110 /* Conditional Branching: */ 111 void i_IF(void) 112 { 113 if (*dsp == 0) pc = *(dsp - 1) - 1; 114 dsp -= 2; 115 } 116 117 /* Subroutine Calls: */ 118 void i_CALL(void) 119 { 120 *(rsp + 1) = pc; 121 rsp++; 122 pc = *dsp; 123 dsp--; 124 } 125 126 void i_EXIT(void) 127 { 128 pc = *rsp; 129 rsp--; 130 } 131 132 /* "Hardware" IO */ 133 134 void i_PUTC(void) 135 { 136 write(1, dsp--, 1); 137 } 138 139 void i_GETC(void) 140 { 141 read(0, ++dsp, 1); 142 } 143 144 instruction instructions[128] = { 145 [VSM_NOP] i_NOP, 146 [VSM_ADD] i_ADD, 147 [VSM_SUB] i_SUB, 148 [VSM_AND] i_AND, 149 [VSM_OR] i_OR, 150 [VSM_XOR] i_XOR, 151 [VSM_DROP] i_DROP, 152 [VSM_DUP] i_DUP, 153 [VSM_OVER] i_OVER, 154 [VSM_SWAP] i_SWAP, 155 [VSM_TOR] i_TOR, 156 [VSM_FROMR] i_FROMR, 157 [VSM_STORE] i_STORE, 158 [VSM_FETCH] i_FETCH, 159 [VSM_LIT] i_LIT, 160 [VSM_IF] i_IF, 161 [VSM_CALL] i_CALL, 162 [VSM_EXIT] i_EXIT, 163 [VSM_PUTC] i_PUTC, 164 [VSM_GETC] i_GETC, 165 }; 166 167 /* VMS Control */ 168 169 void 170 vsm_reset(void) 171 { 172 pc = 0; 173 dsp = dstack; 174 rsp = rstack; 175 } 176 177 void 178 vsm_exec(CELL op) 179 { 180 instructions[op](); 181 pc++; 182 } 183 184 185 void 186 vsm_run(void) 187 { 188 CELL op; 189 for (;;) { 190 /* TODO: put more sanity checks here */ 191 if (dsp < dstack) { 192 fprint(2, "dstack underflow\n"); 193 return; 194 } 195 if (rsp < rstack) { 196 fprint(2, "rstack underflow\n"); 197 return; 198 } 199 if (pc >= IMAGE_SIZE) { 200 fprint(2, "pc reached end of the image\n"); 201 return; 202 } 203 204 op = ram[pc]; 205 206 207 if (op >= NUM_OPS) { 208 fprint(2, "invalid op == %d\n", op); 209 return; 210 } 211 vsm_exec(op); 212 } 213 } 214 215 int 216 vsm_readimage(char *path) 217 { 218 char buf[64]; 219 CELL n; 220 CELL *mp; 221 int fd; 222 fd = open(path, OREAD); 223 if (fd <= 0) return -1; 224 mp = ram; 225 while((n = read(fd, buf, 64)) > 0){ 226 if (mp + n/sizeof(CELL) >= ram + IMAGE_SIZE) 227 sysfatal("file bigger than image size"); 228 229 memcpy(mp, buf, n); 230 mp += n/sizeof(CELL); 231 } 232 close(fd); 233 234 int i; 235 for (i = 0; i < IMAGE_SIZE; i++) { 236 if (ram[i] == 0) break; 237 mapset(i, ram + i); 238 } 239 240 return 0; 241 }