vsm2

exeprimental virtual stack machine for *nix
Log | Files | Refs

mem.c (1608B)


      1 #include <stdlib.h>
      2 #include <stdio.h>
      3 #include <string.h>
      4 
      5 #include "cell.h"
      6 #include "bus.h"
      7 #include "mem.h"
      8 
      9 Mem *
     10 createmem(Bus *bus)
     11 {
     12 	Mem *new = calloc(sizeof(Mem), 1);
     13 	new->bus = bus;
     14 	return new;
     15 }
     16 
     17 int
     18 memstep(void *v)
     19 {
     20 	Mem *mem = (Mem *)v;
     21 	Msg *ret, *msg = buspull(mem->bus, ChMem);
     22 	Cell *ram, *cell;
     23 
     24 	if (msg == NULL) return 1;
     25 
     26 	if ((msg->dat == NULL)
     27 	  || (msg->dat->n < sizeof(MemCmd))) {
     28 		freemsg(msg);
     29 		fprintf(stderr, "mem: cmd too short\n");
     30 		return 0;
     31 	}
     32 	MemCmd *cmd = (MemCmd *)msg->dat->p;
     33 	if ((cmd->addr < 0) || (cmd->addr >= MaxRAM)) {
     34 		fprintf(stderr, "mem: invalid addr: %x\n",
     35 		  cmd->addr);
     36 	} else switch (cmd->op) {
     37 	case '!': //fetch
     38 		ram = &mem->ram[cmd->addr];
     39 		cell = celldup(ram);
     40 		ret = createmsg(ChMem, msg->src, cell);
     41 		buspush(mem->bus, ret);
     42 		break;
     43 	case '@': //store
     44 		ram = &mem->ram[cmd->addr];
     45 		ram->n = msg->dat->n - sizeof(MemCmd);
     46 		ram->p = realloc(ram->p, ram->n);
     47 		memcpy(ram->p, msg->dat->p + sizeof(MemCmd),
     48 		  ram->n);
     49 		break;
     50 	default:
     51 		fprintf(stderr, "mem: invalid op: %c\n", cmd->op);
     52 	}
     53 	freemsg(msg);
     54 	return 0;
     55 }
     56 
     57 void
     58 memfetch(int src, Mem *mem, int n)
     59 {
     60 	MemCmd *f = malloc(sizeof(MemCmd));
     61 	f->op = '!';
     62 	f->addr = n;
     63 	Cell *c = createcell(sizeof(MemCmd), f);
     64 	Msg *msg = createmsg(src, ChMem, c);
     65 	buspush(mem->bus, msg);
     66 }
     67 
     68 void
     69 memstore(int src, Mem *mem, int n, Cell *c)
     70 {
     71 	MemCmd *s = malloc(sizeof(MemCmd) + c->n);
     72 	s->op = '@';
     73 	s->addr = n;
     74 	memcpy((char *)s + sizeof(MemCmd), c->p, c->n);
     75 	Cell *cell = createcell(sizeof(MemCmd) + c->n, s);
     76 	Msg *msg = createmsg(src, ChMem, cell);
     77 	buspush(mem->bus, msg);
     78 }
     79