#include #include #include #include #include struct State{ uint16_t programCounter; int8_t accumulator; uint8_t input; uint8_t programPage; uint8_t memoryPage; uint8_t X; uint8_t memory[65536]; bool carry; uint16_t program[65536]; }; struct State initState(FILE* f){ struct State state; memset(state.program, 0, sizeof(uint16_t)*65536); int i=0; char hexString[5]; hexString[4] = '\0'; int c; while((c = fgetc(f))!=-1){ int val; hexString[i%4] = c; if((i+1)%4==0){ int status; state.program[i/4] = strtoi(hexString,NULL,16,0,65535,&status); if(status) fprintf(stderr,"Something went wrong converting %s\n", hexString); } i++; } state.programCounter =0; state.accumulator =0; state.input =0; state.programPage =0; state.programPage =0; state.memoryPage =0; state.X =0; state.carry = false; return state; } void printState(struct State state){ printf("Program counter: %x, Accumulator: %x, Input: %x, Program Page:" "%x, Memory Page: %x, x:" "%x\n",state.programCounter,state.accumulator,state.input,state.programPage,state.memoryPage,state.X); #define MEM state.memory printf("Memory from 0x0000 untill 0x0004: %x, %x, %x, %x, %x\n", MEM[0], MEM[1], MEM[2], MEM[3], MEM[4]); } //It will always return True unless it is at the end of the program. Beause //there is no halt instruction it is //at the the end of the program when it enounters an instruction that jumps //to itself bool nextState(struct State* state){ bool ret = true; uint16_t instruction = state->program[state->programCounter]; int operation = instruction >> 13; int condition = (instruction & 0x1c00)>>10; int busB = (instruction & 0x1800)>>11; int registerB = (instruction & 0x600)>>9; int addrBusB = (instruction & 0x100)>>8; uint8_t op = (uint8_t)(instruction & 0xff); uint8_t addrBus; switch(addrBusB){ case(0): addrBus = op; break; case(1): addrBus = state->X; break; } uint8_t* reg; switch(registerB){ case(0): reg = &(state->programPage); break; case(1): reg = &(state->memoryPage); break; case(2): reg = &(state->accumulator); break; case(3): reg = &(state->X); break; } uint16_t a = ((uint16_t)state->memoryPage)<<8; uint16_t b = (uint16_t)addrBus; uint16_t address = a+b; uint8_t bus; switch(busB){ case(0): bus = state->memory[address]; break; case(1): bus = op; break; case(2): bus = state->input; break; case(3): bus = state->accumulator; break; } if(operation==7){ bool conditionIsTrue; switch(condition){ case(0): conditionIsTrue = true; break; case(1): conditionIsTrue = state->accumulator>0; break; case(2): conditionIsTrue = state->accumulator>=0; break; case(3): conditionIsTrue = state->accumulator==0; break; case(4): conditionIsTrue = state->accumulator<0; break; case(5): conditionIsTrue = state->accumulator<=0; break; case(6): conditionIsTrue = state->carry; break; case(7): conditionIsTrue = state->accumulator!=0; break; } if(conditionIsTrue){ //change the program counter uint16_t newProgramCounter = (((uint16_t)state->programPage)<<8) + ((uint16_t)addrBus); ret = ret && (newProgramCounter!=state->programCounter); state->programCounter = newProgramCounter; }else{ state->programCounter++; } }else{ switch(operation){ case(0): //Load *reg = bus; break; case(1): //And *reg = bus & state->accumulator; break; case(2): //Or *reg = bus | state->accumulator; break; case(3): //Xor *reg = bus ^ state->accumulator; break; case(4): //Add *reg = bus + state->accumulator; break; case(5): //Sub *reg = state->accumulator-bus; break; case(6): //Store state->memory[address]= bus; break; } state->programCounter++; } return(ret); } void main(int argc, char** argv){ if(argc!=3){ fprintf(stderr,"You should give exactly two arguments"); return; } FILE* f = fopen(argv[2], "r"); struct State state = initState(f); bool debug = !strcmp(argv[1],"debug"); while(nextState(&state)){ if(debug){ printState(state); printf("Press enter to go to the next state:\n"); getchar(); } } printf("Terminated with the following state:\n"); printState(state); }