Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <assert.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <pthread.h>
- #define X_INSTRUCTIONS_NOT_NEEDED
- #include "xis.h"
- #include "xcpu.h"
- #define false 0
- #define true 1
- void xcpu_print( xcpu *c ) {
- int i;
- fprintf( stdout, "PC: %4.4x, State: %4.4x: Registers:\n", c->pc, c->state );
- for( i = 0; i < X_MAX_REGS; i++ ) {
- fprintf( stdout, " %4.4x", c->regs[i] );
- }
- fprintf( stdout, "\n" );
- }
- extern int xcpu_execute( xcpu *c ) {
- unsigned short OP1;
- unsigned short OP2;
- unsigned short S;
- unsigned short D;
- unsigned short L;
- unsigned short a;
- unsigned short item1;
- unsigned short item2;
- int status = true;
- //Fetch two bytes of the records
- OP1 = c->memory[(c->pc)]; //This is the high byte
- OP2 = c->memory[(c->pc+1)]; //This is the low byte
- c->pc = c->pc + 2; //General incrementation of the PC
- //Execute + Increment the PC
- switch ((XIS_OPS&OP1)>>6){
- case 0x00: // OPS OPNUM Operations with no operands
- switch(OP1){
- case I_BAD:
- status = false;
- break;
- case I_RET:
- item1 = c->memory[c->regs[15]];
- item2 = c->memory[c->regs[15]+1];
- c->pc = (item1 << 8)|item2;
- c->regs[15]+=2;
- status = true;
- break;
- case I_CLD:
- c->state &= 0xFFFD;
- status = true;
- break;
- case I_STD:
- c->state |= 0x0002;
- status = true;
- break;
- }
- break;
- case 0x01: // OPS I OPNUM Operations with one register operand
- switch((XIS_X_REG&OP1)>>5){
- case(0x00):
- D=OP2>>2;
- switch(OP1){
- case I_NEG:
- c->regs[D] = -1 * c->regs[D];
- status = true;
- break;
- case I_NOT:
- if (c->regs[D] == 0){
- c->regs[D] = 1;
- }
- else{
- c->regs[D] = 0;
- }
- status = true;
- break;
- case I_PUSH:
- c->regs[15]-=2;
- c->memory[c->regs[15]] = (c->regs[D]&0xFF00)>>8;
- c->memory[c->regs[15+1]] = c->regs[D]&0x00FF;
- status = true;
- break;
- case I_POP:
- c->regs[D] = c->memory[c->regs[15]];
- c->regs[15]+=2;
- status = true;
- break;
- case I_JMPR:
- c->pc = c->regs[D];
- status = true;
- break;
- case I_CALLR:
- c->regs[15]-=2;
- c->memory[c->regs[15]] = c->pc;
- c->pc = c->regs[D];
- status = true;
- break;
- case I_OUT:
- item1 = c->regs[D];
- printf("%c \n", item1);
- case I_INC:
- c->regs[D]++;
- status = true;
- break;
- case I_DEC:
- c->regs[D]--;
- status = true;
- break;
- }
- break;
- case(0x01):
- L=OP2;
- switch(OP1){
- case I_BR:
- if((c->state&0x0001) == 0x0001){
- c->pc = c->pc + (short)L;
- }
- status = true;
- break;
- case I_JR:
- c->pc = c->pc + (short)L;
- status = true;
- break;
- }
- break;
- }
- break;
- case 0x02: // OPS OPNUM Operations with two register operands
- S = (OP2>>8);
- D = (OP2&0x00Ff);
- switch(OP1){
- case I_ADD:
- c->regs[D] = c->regs[D] + c->regs[S];
- status = true;
- break;
- case I_SUB:
- c->regs[D] = c->regs[D] - c->regs[S];
- status = true;
- break;
- case I_MUL:
- c->regs[D] = c->regs[D] * c->regs[S];
- status = true;
- break;
- case I_DIV:
- c->regs[D] = c->regs[D] / c->regs[S];
- status = true;
- break;
- case I_AND:
- c->regs[D] = c->regs[D] & c->regs[S];
- status = true;
- break;
- case I_OR:
- c->regs[D] = c->regs[D] | c->regs[S];
- status = true;
- break;
- case I_XOR:
- c->regs[D] = c->regs[D] ^ c->regs[S];
- status = true;
- break;
- case I_SHR:
- c->regs[D] = c->regs[D] >> c->regs[S];
- status = true;
- break;
- case I_SHL:
- c->regs[D] = c->regs[D] << c->regs[S];
- status = true;
- break;
- case I_TEST:
- if((c->regs[S]&c->regs[D])!=0){
- c->state |= 0x0002;
- }
- else{
- c->state &= 0xFFFE;
- }
- status = true;
- break;
- case I_CMP:
- if((c->regs[S] < c->regs[D])!=0){
- c->state |= 0x0001;
- }
- else{
- c->state &= 0xFFFE;
- }
- status = true;
- break;
- case I_EQU:
- if((c->regs[S] == c->regs[D])!=0){
- c->state |= 0x0001;
- }
- else{
- c->state &= 0xFFFE;
- }
- status = true;
- break;
- case I_MOV:
- c->regs[D] = c->regs[S];
- status = true;
- break;
- case I_LOAD:
- c->regs[D] = c->memory[c->regs[S]];
- status = true;
- break;
- case I_STOR:
- c->regs[S] = c->memory[c->regs[D]];
- status = true;
- break;
- case I_LOADB:
- status = true;
- break;
- case I_STORB:
- status = true;
- break;
- }
- break;
- case 0x03:
- switch((XIS_EXTENDED&OP1)>>5){
- case(0x00): /* OPS R OPNUM X Operations with one immediate operand */
- L = (c->memory[c->pc]<<8)|c->memory[c->pc+1];//this is assuming that you already did pc+=2 at the start
- switch(OP1){
- case I_JMP:
- c->pc = c->memory[c->regs[L]];
- status = true;
- break;
- case I_CALL:
- c->regs[15]-=1;
- c->memory[c->regs[15]] = c->pc&0x00FF;
- c->regs[15]-=1;
- c->memory[c->regs[15]] = (c->pc&0xFF00>>8);
- c->pc = c->memory[c->regs[L]];
- status = true;
- break;
- }
- break;
- case(0x01): /* OPS R OPNUM X Ops with 1 imm. and 1 reg. operand */
- D = (OP2>>8);
- a = (c->memory[c->pc]<<8)|(c->memory[c->pc+1]);
- switch(OP1){
- case I_LOADI:
- c->regs[D] = a;
- c->pc = c->pc+2;
- status = true;
- break;
- }
- break;
- }
- break;
- }
- return status; //Returns True (1) if succesfull or False (0) for failed
- }
- /* Not needed for assignment 1 */
- int xcpu_exception( xcpu *c, unsigned int ex ) {
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement