Abbreviated code for implementing the CPU cycle of the Tierra Simulator.
void main(void)
{ get_soup();
life();
write_soup();
}
void life(void) /* doles out time slices and death */
{ while(inst_exec_c < alive) /* control the length of the run */
{ time_slice(this_slice); /* this_slice is current cell in queue */
incr_slice_queue(); /* increment this_slice to next cell in queue */
while(free_mem_current < free_mem_prop * soup_size)
reaper(); /* if memory is full to threshold, reap some cells */
}
}
void time_slice(int ci)
{ Pcells ce; /* pointer to the array of cell structures */
char i; /* instruction from soup */
int di; /* decoded instruction */
int j, size_slice;
ce = cells + ci;
for(j = 0; j < size_slice; j++)
{ i = fetch(ce->c.ip); /* fetch instruction from soup, at address ip */
di = decode(i); /* decode the fetched instruction */
execute(di, ci); /* execute the decoded instruction */
increment_ip(di,ce); /* move instruction pointer to next instruction */
system_work(); /* opportunity to extract information */
}
}
void execute(int di, int ci)
{ switch(di)
{ case 0x00: nop_0(ci); break; /* no operation */
case 0x01: nop_1(ci); break; /* no operation */
case 0x02: or1(ci); break; /* flip low order bit of cx, cx ^= 1 */
case 0x03: shl(ci); break; /* shift left cx register, cx <<= 1 */
case 0x04: zero(ci); break; /* set cx register to zero, cx = 0 */
case 0x05: if_cz(ci); break; /* if cx==0 execute next instruction */
case 0x06: sub_ab(ci); break; /* subtract bx from ax, cx = ax - bx */
case 0x07: sub_ac(ci); break; /* subtract cx from ax, ax = ax - cx */
case 0x08: inc_a(ci); break; /* increment ax, ax = ax + 1 */
case 0x09: inc_b(ci); break; /* increment bx, bx = bx + 1 */
case 0x0a: dec_c(ci); break; /* decrement cx, cx = cx - 1 */
case 0x0b: inc_c(ci); break; /* increment cx, cx = cx + 1 */
case 0x0c: push_ax(ci); break; /* push ax on stack */
case 0x0d: push_bx(ci); break; /* push bx on stack */
case 0x0e: push_cx(ci); break; /* push cx on stack */
case 0x0f: push_dx(ci); break; /* push dx on stack */
case 0x10: pop_ax(ci); break; /* pop top of stack into ax */
case 0x11: pop_bx(ci); break; /* pop top of stack into bx */
case 0x12: pop_cx(ci); break; /* pop top of stack into cx */
case 0x13: pop_dx(ci); break; /* pop top of stack into dx */
case 0x14: jmp(ci); break; /* move ip to template */
case 0x15: jmpb(ci); break; /* move ip backward to template */
case 0x16: call(ci); break; /* call a procedure */
case 0x17: ret(ci); break; /* return from a procedure */
case 0x18: mov_cd(ci); break; /* move cx to dx, dx = cx */
case 0x19: mov_ab(ci); break; /* move ax to bx, bx = ax */
case 0x1a: mov_iab(ci); break; /* move instruction at address in bx
to address in ax */
case 0x1b: adr(ci); break; /* address of nearest template to ax */
case 0x1c: adrb(ci); break; /* search backward for template */
case 0x1d: adrf(ci); break; /* search forward for template */
case 0x1e: mal(ci); break; /* allocate memory for daughter cell */
case 0x1f: divide(ci); break; /* cell division */
}
inst_exec_c++;
}