├── Makefile ├── dev ├── compiler.c ├── i808.c ├── i808.h ├── simplevm.c └── vm.c ├── examples └── helloworld.asm ├── manual.htm └── readme.txt /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -std=c99 -Wall -pedantic -o compiler dev/compiler.c 3 | gcc -std=c99 -Wall -pedantic -o vm dev/vm.c dev/i808.c 4 | gcc -std=c99 -Wall -pedantic -o simplevm dev/simplevm.c dev/i808.c 5 | clean: 6 | rm -f compiler 7 | rm -f vm 8 | rm -f simplevm 9 | rm -f *.bin 10 | -------------------------------------------------------------------------------- /dev/compiler.c: -------------------------------------------------------------------------------- 1 | /* 2 | compiler.c - Module file for i808 source code compiler 3 | v1.0b - 2007.11.15 4 | Coded by Ian Seyler (iseyler@gmail.com) 5 | */ 6 | 7 | /* Obligatory includes */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | /* Version information strings */ 14 | char VERSIONINFO1[] = "i808 Compiler v1.0b"; 15 | char VERSIONINFO2[] = "Compiled on 2007.11.15, based on i808 spec 2006.08.30"; 16 | /* Function prototypes */ 17 | int hex2dec(char val); 18 | int incCounter(); 19 | int incPageCounter(); 20 | void printhelp(); 21 | 22 | /* Global variables */ 23 | char arg[50], parsedarg[20]; 24 | unsigned int writeCounter = 0, writePageCounter = 0; 25 | unsigned int argval = 0, argvalue = 0; 26 | int verbose = 0, debug = 0, error = 0; 27 | int maxProgramSize = 0, maxPages = 0; 28 | int destArch = 0; // i808 = 8080, i808v2 = 8081, i816 = 8160, i816v2 = i8161, 0 = not specified 29 | char *program_name; 30 | 31 | int main(int argc, char *argv[]) 32 | { 33 | char *inputFile, outputFile[30]; 34 | int tint = 0, tint2 = 0; 35 | char VAR[] = "var"; 36 | char NOP[] = "nop"; 37 | char ADD[] = "add"; 38 | char SUB[] = "sub"; 39 | char MOV[] = "mov"; 40 | char CMP[] = "cmp"; 41 | char INC[] = "inc"; 42 | char DEC[] = "dec"; 43 | char AND[] = "and"; 44 | char OR[] = "or"; 45 | char XOR[] = "xor"; 46 | char NOT[] = "not"; 47 | char IN[] = "in"; 48 | char OUT[] = "out"; 49 | char PUSH[] = "push"; 50 | char POP[] = "pop"; 51 | char JL[] = "jl"; 52 | char JLE[] = "jle"; 53 | char JE[] = "je"; 54 | char JGE[] = "jge"; 55 | char JG[] = "jg"; 56 | char JNE[] = "jne"; 57 | char JMP[] = "jmp"; 58 | char JSF[] = "jsf"; 59 | char JSB[] = "jsb"; 60 | char CALL[] = "call"; 61 | char RET[] = "ret"; 62 | char BSL[] = "bsl"; 63 | char BSR[] = "bsr"; 64 | char PUSHA[] = "pusha"; 65 | char POPA[] = "popa"; 66 | char RND[] = "rnd"; 67 | int IP = 0, memval1 = 0, memval2 = 0; 68 | unsigned int argval1 = 0, argval2 = 0, argvalue1 = 0, argvalue2 = 0; 69 | int subOptionPointer[50], subOptionRunningNumber = 0; 70 | int tempJumpAddress = 0; 71 | char subOptionName[50][20]; // 20 chars each 72 | char tempsubOptionName[50]; 73 | unsigned char jumpcounter[50], jumptint = 0; 74 | unsigned int varCounter = 0; 75 | char varName[50][20]; 76 | unsigned int varAddress[50]; 77 | unsigned int varRunningAddress = 255; 78 | char parsed[50], arg1[50], arg2[50], parsedarg1[20], parsedarg2[20]; 79 | unsigned char compiledCode[2][256]; 80 | // unsigned char compiled16bitCode[2][65536]; 81 | unsigned char tchar; 82 | FILE *fpIn, *fpOut; 83 | 84 | program_name = argv[0]; 85 | 86 | if (argc < 2 || argv[1][0] == '-' || argv[1][0] == '/') // make sure there is at least one argument (filename) 87 | { 88 | printhelp(); 89 | exit (1); 90 | } 91 | 92 | inputFile = argv[1]; 93 | // printf("Start\n"); 94 | for(tint=0; tint= 0x88 && compiledCode[0][tint] <= 0x9F) //Fix the jumps to proper address, 2-byte commands 2509 | { 2510 | tint++; 2511 | } 2512 | else if (compiledCode[0][tint] >= 0x80 && compiledCode[0][tint] <= 0x87) //Fix the jumps to proper address 2513 | { 2514 | if (verbose == 1) printf("0x%02X to ", compiledCode[0][tint]); 2515 | tint++; 2516 | tchar = compiledCode[0][tint]; 2517 | if (tchar > subOptionRunningNumber) printf("Potential jump error"); 2518 | tchar = subOptionPointer[tchar]; 2519 | if (verbose == 1) printf("0x%02X\n", tchar); 2520 | compiledCode[0][tint] = tchar; 2521 | } 2522 | } 2523 | 2524 | // jumptint-1, jumpcounter[jumptint-1]); 2525 | 2526 | fpOut = fopen(outputFile, "wb"); 2527 | fwrite(compiledCode[0], maxProgramSize, 1, fpOut); 2528 | fclose(fpOut); 2529 | 2530 | // printf("Finish\n"); 2531 | if (verbose == 1) printf("\n"); 2532 | if (error == 0) 2533 | { 2534 | if (verbose == 1) printf("Compiled sucessfully. Saved %d bytes of code to %s\n", IP, outputFile); 2535 | } 2536 | else if (error == 1) 2537 | { 2538 | printf("There was an error during compile. Output may not be as expected.\n"); 2539 | } 2540 | else 2541 | { 2542 | printf("There were %d errors during compile. Output may not be as expected.\n", error); 2543 | } 2544 | 2545 | // system("PAUSE"); 2546 | return 0; 2547 | } 2548 | 2549 | int hex2dec(char val) 2550 | { 2551 | int temp; 2552 | /* if (isdigit(val)) 2553 | { 2554 | printf("Got a digit"); 2555 | temp = atoi(val); 2556 | }*/ 2557 | if (val == '0') 2558 | { 2559 | temp = 0; 2560 | } 2561 | else if (val == '1') 2562 | { 2563 | temp = 1; 2564 | } 2565 | else if (val == '2') 2566 | { 2567 | temp = 2; 2568 | } 2569 | else if (val == '3') 2570 | { 2571 | temp = 3; 2572 | } 2573 | else if (val == '4') 2574 | { 2575 | temp = 4; 2576 | } 2577 | else if (val == '5') 2578 | { 2579 | temp = 5; 2580 | } 2581 | else if (val == '6') 2582 | { 2583 | temp = 6; 2584 | } 2585 | else if (val == '7') 2586 | { 2587 | temp = 7; 2588 | } 2589 | else if (val == '8') 2590 | { 2591 | temp = 8; 2592 | } 2593 | else if (val == '9') 2594 | { 2595 | temp = 9; 2596 | } 2597 | else if (val == 'a' || val == 'A') 2598 | { 2599 | temp = 10; 2600 | } 2601 | else if (val == 'b' || val == 'B') 2602 | { 2603 | temp = 11; 2604 | } 2605 | else if (val == 'c' || val == 'C') 2606 | { 2607 | temp = 12; 2608 | } 2609 | else if (val == 'd' || val == 'D') 2610 | { 2611 | temp = 13; 2612 | } 2613 | else if (val == 'e' || val == 'E') 2614 | { 2615 | temp = 14; 2616 | } 2617 | else if (val == 'f' || val == 'F') 2618 | { 2619 | temp = 15; 2620 | } 2621 | else 2622 | { 2623 | printf("Error during hex to dec conversion"); 2624 | temp = -1; 2625 | } 2626 | return temp; 2627 | } 2628 | 2629 | int incCounter() 2630 | { 2631 | writeCounter++; 2632 | if (writeCounter > maxProgramSize) 2633 | printf("Error! Compiled program has exceeded resources\n"); 2634 | } 2635 | 2636 | int incPageCounter() 2637 | { 2638 | writePageCounter++; 2639 | if (writePageCounter > maxPages) 2640 | printf("Error! Compiled program has exceeded resources\n"); 2641 | } 2642 | 2643 | void printhelp() 2644 | { 2645 | printf("%s\n", VERSIONINFO1); 2646 | printf("%s\n", VERSIONINFO2); 2647 | printf("Coded by Ian Seyler (iseyler@gmail.com)\n\n"); 2648 | printf("Usage: %s [source file] [options]\n", program_name); 2649 | printf("Options:\n"); 2650 | printf(" -v Verbose mode\n"); 2651 | } 2652 | -------------------------------------------------------------------------------- /dev/i808.c: -------------------------------------------------------------------------------- 1 | /* 2 | i808.c - Module file for i808 Virtual Computer 3 | v1.0b - 2007.11.15 4 | Coded by Ian Seyler (iseyler@gmail.com) 5 | */ 6 | 7 | /* Obligatory includes */ 8 | #include 9 | #include "i808.h" 10 | 11 | /* Global variables */ 12 | unsigned char bit8fieldl[16] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; 13 | unsigned char bit8fieldh[16] = {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}; 14 | 15 | /* Version information strings */ 16 | char i808VERSIONINFO[] = "i808 Virtual Computer Library"; 17 | char i808VERSIONNUMINFO[] = "v1.0b (Standard) FOR PUBLIC DISTRIBUTION"; 18 | char i808VERSIONSUBINFO[] = "Designed and programmed by Ian Seyler (iseyler@gmail.com)"; 19 | 20 | 21 | /*========================================================* 22 | * Function: i808compute() 23 | * Purpose : Process an 808 computer 24 | * Entry : eightbitComputer *c = Pointer to a computer 25 | * int cycles = Cycles to process 26 | * int verbose = 1 for verbose mode 27 | * Returns : nothing 28 | *========================================================*/ 29 | 30 | void i808compute(eightbitComputer *c, unsigned int cycles, unsigned int verbose) 31 | { 32 | unsigned int step = 0, tint = 0; 33 | unsigned char temp = 0x00; // only being used to show zero and carry data at end 34 | while (step < cycles) 35 | { 36 | if (verbose == 1) printf("A:%02X B:%02X C:%02X D:%02X I:%02X F:%02X", c->reg[0], c->reg[1], c->reg[2], c->reg[3], c->ip, c->flags); 37 | 38 | temp = c->mem[c->ip]; // page flipping c->mem[c->page][c->ip] 39 | switch(c->mem[c->ip]) 40 | { 41 | case 0x00: // 0x00 42 | if (verbose == 1) printf("\t%02X\tNOP", c->mem[c->ip]); 43 | c->ip++; 44 | break; 45 | case 0x01: 46 | if (verbose == 1) printf("\t%02X\tRET", c->mem[c->ip]); 47 | c->ip = c->ipstack[0]; 48 | c->ipstack[0] = c->ipstack[1]; 49 | c->ipstack[1] = c->ipstack[2]; 50 | c->ipstack[2] = c->ipstack[3]; 51 | c->ipstack[3] = 0; 52 | if (verbose == 1) printf("\t\tI: "); 53 | for(tint=0; tint<4; tint++) 54 | { 55 | if (verbose == 1) printf("%02X ", c->ipstack[tint]); 56 | } 57 | break; 58 | case 0x02: 59 | if (verbose == 1) printf("\t%02X\tPUSHA", c->mem[c->ip]); 60 | c->stack[15] = c->stack[11]; 61 | c->stack[14] = c->stack[10]; 62 | c->stack[13] = c->stack[9]; 63 | c->stack[12] = c->stack[8]; 64 | c->stack[11] = c->stack[7]; 65 | c->stack[10] = c->stack[6]; 66 | c->stack[9] = c->stack[5]; 67 | c->stack[8] = c->stack[4]; 68 | c->stack[7] = c->stack[3]; 69 | c->stack[6] = c->stack[2]; 70 | c->stack[5] = c->stack[1]; 71 | c->stack[4] = c->stack[0]; 72 | c->stack[3] = c->reg[0]; 73 | c->stack[2] = c->reg[1]; 74 | c->stack[1] = c->reg[2]; 75 | c->stack[0] = c->reg[3]; 76 | c->ip++; 77 | if (verbose == 1) printf("\t\tS: "); 78 | for(tint=0; tint<16; tint++) 79 | { 80 | if (verbose == 1) printf("%02X ",c->stack[tint]); 81 | } 82 | break; 83 | case 0x03: 84 | if (verbose == 1) printf("\t%02X\tPOPA", c->mem[c->ip]); 85 | c->reg[3] = c->stack[0]; 86 | c->reg[2] = c->stack[1]; 87 | c->reg[1] = c->stack[2]; 88 | c->reg[0] = c->stack[3]; 89 | c->stack[0] = c->stack[4]; 90 | c->stack[1] = c->stack[5]; 91 | c->stack[2] = c->stack[6]; 92 | c->stack[3] = c->stack[7]; 93 | c->stack[4] = c->stack[8]; 94 | c->stack[5] = c->stack[9]; 95 | c->stack[6] = c->stack[10]; 96 | c->stack[7] = c->stack[11]; 97 | c->stack[8] = c->stack[12]; 98 | c->stack[9] = c->stack[13]; 99 | c->stack[10] = c->stack[14]; 100 | c->stack[11] = c->stack[15]; 101 | c->stack[12] = 0; 102 | c->stack[13] = 0; 103 | c->stack[14] = 0; 104 | c->stack[15] = 0; 105 | c->ip++; 106 | if (verbose == 1) printf("\t\tS: "); 107 | for(tint=0; tint<16; tint++) 108 | { 109 | if (verbose == 1) printf("%02X ",c->stack[tint]); 110 | } 111 | break; 112 | case 0x04: 113 | if (verbose == 1) printf("\t%02X\tNOT A", c->mem[c->ip]); 114 | c->reg[0] = 255 - c->reg[0]; 115 | c->ip++; 116 | break; 117 | case 0x05: 118 | if (verbose == 1) printf("\t%02X\tNOT B", c->mem[c->ip]); 119 | c->reg[1] = 255 - c->reg[1]; 120 | c->ip++; 121 | break; 122 | case 0x06: 123 | if (verbose == 1) printf("\t%02X\tNOT C", c->mem[c->ip]); 124 | c->reg[2] = 255 - c->reg[2]; 125 | c->ip++; 126 | break; 127 | case 0x07: 128 | if (verbose == 1) printf("\t%02X\tNOT D", c->mem[c->ip]); 129 | c->reg[3] = 255 - c->reg[3]; 130 | c->ip++; 131 | break; 132 | case 0x08: 133 | if (verbose == 1) printf("\t%02X\tINC A", c->mem[c->ip]); 134 | c->reg[0]++; 135 | c->ip++; 136 | break; 137 | case 0x09: 138 | if (verbose == 1) printf("\t%02X\tINC B", c->mem[c->ip]); 139 | c->reg[1]++; 140 | c->ip++; 141 | break; 142 | case 0x0A: 143 | if (verbose == 1) printf("\t%02X\tINC C", c->mem[c->ip]); 144 | c->reg[2]++; 145 | c->ip++; 146 | break; 147 | case 0x0B: 148 | if (verbose == 1) printf("\t%02X\tINC D", c->mem[c->ip]); 149 | c->reg[3]++; 150 | c->ip++; 151 | break; 152 | case 0x0C: 153 | if (verbose == 1) printf("\t%02X\tDEC A", c->mem[c->ip]); 154 | c->reg[0]--; 155 | c->ip++; 156 | break; 157 | case 0x0D: 158 | if (verbose == 1) printf("\t%02X\tDEC B", c->mem[c->ip]); 159 | c->reg[1]--; 160 | c->ip++; 161 | break; 162 | case 0x0E: 163 | if (verbose == 1) printf("\t%02X\tDEC C", c->mem[c->ip]); 164 | c->reg[2]--; 165 | c->ip++; 166 | break; 167 | case 0x0F: 168 | if (verbose == 1) printf("\t%02X\tDEC D", c->mem[c->ip]); 169 | c->reg[3]--; 170 | c->ip++; 171 | break; 172 | case 0x10: // 0x10 173 | if (verbose == 1) printf("\t%02X\tADD A, A", c->mem[c->ip]); 174 | c->reg[0] = c->reg[0] + c->reg[0]; 175 | c->ip++; 176 | break; 177 | case 0x11: 178 | if (verbose == 1) printf("\t%02X\tADD A, B", c->mem[c->ip]); 179 | c->reg[0] = c->reg[0] + c->reg[1]; 180 | c->ip++; 181 | break; 182 | case 0x12: 183 | if (verbose == 1) printf("\t%02X\tADD A, C", c->mem[c->ip]); 184 | c->reg[0] = c->reg[0] + c->reg[2]; 185 | c->ip++; 186 | break; 187 | case 0x13: 188 | if (verbose == 1) printf("\t%02X\tADD A, D", c->mem[c->ip]); 189 | c->reg[0] = c->reg[0] + c->reg[3]; 190 | c->ip++; 191 | break; 192 | case 0x14: 193 | if (verbose == 1) printf("\t%02X\tADD B, A", c->mem[c->ip]); 194 | c->reg[1] = c->reg[1] + c->reg[0]; 195 | c->ip++; 196 | break; 197 | case 0x15: 198 | if (verbose == 1) printf("\t%02X\tADD B, B", c->mem[c->ip]); 199 | c->reg[1] = c->reg[1] + c->reg[1]; 200 | c->ip++; 201 | break; 202 | case 0x16: 203 | if (verbose == 1) printf("\t%02X\tADD B, C", c->mem[c->ip]); 204 | c->reg[1] = c->reg[1] + c->reg[2]; 205 | c->ip++; 206 | break; 207 | case 0x17: 208 | if (verbose == 1) printf("\t%02X\tADD B, D", c->mem[c->ip]); 209 | c->reg[1] = c->reg[1] + c->reg[3]; 210 | c->ip++; 211 | break; 212 | case 0x18: 213 | if (verbose == 1) printf("\t%02X\tADD C, A", c->mem[c->ip]); 214 | c->reg[2] = c->reg[2] + c->reg[0]; 215 | c->ip++; 216 | break; 217 | case 0x19: 218 | if (verbose == 1) printf("\t%02X\tADD C, B", c->mem[c->ip]); 219 | c->reg[2] = c->reg[2] + c->reg[1]; 220 | c->ip++; 221 | break; 222 | case 0x1A: 223 | if (verbose == 1) printf("\t%02X\tADD C, C", c->mem[c->ip]); 224 | c->reg[2] = c->reg[2] + c->reg[2]; 225 | c->ip++; 226 | break; 227 | case 0x1B: 228 | if (verbose == 1) printf("\t%02X\tADD C, D", c->mem[c->ip]); 229 | c->reg[2] = c->reg[2] + c->reg[3]; 230 | c->ip++; 231 | break; 232 | case 0x1C: 233 | if (verbose == 1) printf("\t%02X\tADD D, A", c->mem[c->ip]); 234 | c->reg[3] = c->reg[3] + c->reg[0]; 235 | c->ip++; 236 | break; 237 | case 0x1D: 238 | if (verbose == 1) printf("\t%02X\tADD D, B", c->mem[c->ip]); 239 | c->reg[3] = c->reg[3] + c->reg[1]; 240 | c->ip++; 241 | break; 242 | case 0x1E: 243 | if (verbose == 1) printf("\t%02X\tADD D, C", c->mem[c->ip]); 244 | c->reg[3] = c->reg[3] + c->reg[2]; 245 | c->ip++; 246 | break; 247 | case 0x1F: 248 | if (verbose == 1) printf("\t%02X\tADD D, D", c->mem[c->ip]); 249 | c->reg[3] = c->reg[3] + c->reg[3]; 250 | c->ip++; 251 | break; 252 | case 0x20: // 0x20 253 | if (verbose == 1) printf("\t%02X\tSUB A, A", c->mem[c->ip]); 254 | c->reg[0] = c->reg[0] - c->reg[0]; 255 | c->ip++; 256 | break; 257 | case 0x21: 258 | if (verbose == 1) printf("\t%02X\tSUB A, B", c->mem[c->ip]); 259 | c->reg[0] = c->reg[0] - c->reg[1]; 260 | c->ip++; 261 | break; 262 | case 0x22: 263 | if (verbose == 1) printf("\t%02X\tSUB A, C", c->mem[c->ip]); 264 | c->reg[0] = c->reg[0] - c->reg[2]; 265 | c->ip++; 266 | break; 267 | case 0x23: 268 | if (verbose == 1) printf("\t%02X\tSUB A, D", c->mem[c->ip]); 269 | c->reg[0] = c->reg[0] - c->reg[3]; 270 | c->ip++; 271 | break; 272 | case 0x24: 273 | if (verbose == 1) printf("\t%02X\tSUB B, A", c->mem[c->ip]); 274 | c->reg[1] = c->reg[1] - c->reg[0]; 275 | c->ip++; 276 | break; 277 | case 0x25: 278 | if (verbose == 1) printf("\t%02X\tSUB B, B", c->mem[c->ip]); 279 | c->reg[1] = c->reg[1] - c->reg[1]; 280 | c->ip++; 281 | break; 282 | case 0x26: 283 | if (verbose == 1) printf("\t%02X\tSUB B, C", c->mem[c->ip]); 284 | c->reg[1] = c->reg[1] - c->reg[2]; 285 | c->ip++; 286 | break; 287 | case 0x27: 288 | if (verbose == 1) printf("\t%02X\tSUB B, D", c->mem[c->ip]); 289 | c->reg[1] = c->reg[1] - c->reg[3]; 290 | c->ip++; 291 | break; 292 | case 0x28: 293 | if (verbose == 1) printf("\t%02X\tSUB C, A", c->mem[c->ip]); 294 | c->reg[2] = c->reg[2] - c->reg[0]; 295 | c->ip++; 296 | break; 297 | case 0x29: 298 | if (verbose == 1) printf("\t%02X\tSUB C, B", c->mem[c->ip]); 299 | c->reg[2] = c->reg[2] - c->reg[1]; 300 | c->ip++; 301 | break; 302 | case 0x2A: 303 | if (verbose == 1) printf("\t%02X\tSUB C, C", c->mem[c->ip]); 304 | c->reg[2] = c->reg[2] - c->reg[2]; 305 | c->ip++; 306 | break; 307 | case 0x2B: 308 | if (verbose == 1) printf("\t%02X\tSUB C, D", c->mem[c->ip]); 309 | c->reg[2] = c->reg[2] - c->reg[3]; 310 | c->ip++; 311 | break; 312 | case 0x2C: 313 | if (verbose == 1) printf("\t%02X\tSUB D, A", c->mem[c->ip]); 314 | c->reg[3] = c->reg[3] - c->reg[0]; 315 | c->ip++; 316 | break; 317 | case 0x2D: 318 | if (verbose == 1) printf("\t%02X\tSUB D, B", c->mem[c->ip]); 319 | c->reg[3] = c->reg[3] - c->reg[1]; 320 | c->ip++; 321 | break; 322 | case 0x2E: 323 | if (verbose == 1) printf("\t%02X\tSUB D, C", c->mem[c->ip]); 324 | c->reg[3] = c->reg[3] - c->reg[2]; 325 | c->ip++; 326 | break; 327 | case 0x2F: 328 | if (verbose == 1) printf("\t%02X\tSUB D, D", c->mem[c->ip]); 329 | c->reg[3] = c->reg[3] - c->reg[3]; 330 | c->ip++; 331 | break; 332 | case 0x30: // 0x30 333 | if (verbose == 1) printf("\t%02X\tMOV A, A", c->mem[c->ip]); 334 | c->reg[0] = c->reg[0]; 335 | c->ip++; 336 | break; 337 | case 0x31: 338 | if (verbose == 1) printf("\t%02X\tMOV A, B", c->mem[c->ip]); 339 | c->reg[0] = c->reg[1]; 340 | c->ip++; 341 | break; 342 | case 0x32: 343 | if (verbose == 1) printf("\t%02X\tMOV A, C", c->mem[c->ip]); 344 | c->reg[0] = c->reg[2]; 345 | c->ip++; 346 | break; 347 | case 0x33: 348 | if (verbose == 1) printf("\t%02X\tMOV A, D", c->mem[c->ip]); 349 | c->reg[0] = c->reg[3]; 350 | c->ip++; 351 | break; 352 | case 0x34: 353 | if (verbose == 1) printf("\t%02X\tMOV B, A", c->mem[c->ip]); 354 | c->reg[1] = c->reg[0]; 355 | c->ip++; 356 | break; 357 | case 0x35: 358 | if (verbose == 1) printf("\t%02X\tMOV B, B", c->mem[c->ip]); 359 | c->reg[1] = c->reg[1]; 360 | c->ip++; 361 | break; 362 | case 0x36: 363 | if (verbose == 1) printf("\t%02X\tMOV B, C", c->mem[c->ip]); 364 | c->reg[1] = c->reg[2]; 365 | c->ip++; 366 | break; 367 | case 0x37: 368 | if (verbose == 1) printf("\t%02X\tMOV B, D", c->mem[c->ip]); 369 | c->reg[1] = c->reg[3]; 370 | c->ip++; 371 | break; 372 | case 0x38: 373 | if (verbose == 1) printf("\t%02X\tMOV C, A", c->mem[c->ip]); 374 | c->reg[2] = c->reg[0]; 375 | c->ip++; 376 | break; 377 | case 0x39: 378 | if (verbose == 1) printf("\t%02X\tMOV C, B", c->mem[c->ip]); 379 | c->reg[2] = c->reg[1]; 380 | c->ip++; 381 | break; 382 | case 0x3A: 383 | if (verbose == 1) printf("\t%02X\tMOV C, C", c->mem[c->ip]); 384 | c->reg[2] = c->reg[2]; 385 | c->ip++; 386 | break; 387 | case 0x3B: 388 | if (verbose == 1) printf("\t%02X\tMOV C, D", c->mem[c->ip]); 389 | c->reg[2] = c->reg[3]; 390 | c->ip++; 391 | break; 392 | case 0x3C: 393 | if (verbose == 1) printf("\t%02X\tMOV D, A", c->mem[c->ip]); 394 | c->reg[3] = c->reg[0]; 395 | c->ip++; 396 | break; 397 | case 0x3D: 398 | if (verbose == 1) printf("\t%02X\tMOV D, B", c->mem[c->ip]); 399 | c->reg[3] = c->reg[1]; 400 | c->ip++; 401 | break; 402 | case 0x3E: 403 | if (verbose == 1) printf("\t%02X\tMOV D, C", c->mem[c->ip]); 404 | c->reg[3] = c->reg[2]; 405 | c->ip++; 406 | break; 407 | case 0x3F: 408 | if (verbose == 1) printf("\t%02X\tMOV D, D", c->mem[c->ip]); 409 | c->reg[3] = c->reg[3]; 410 | c->ip++; 411 | break; 412 | case 0x40: // 0x40 413 | if (verbose == 1) printf("\t%02X\tCMP A, A", c->mem[c->ip]); 414 | c->flags = c->flags | 0x01; // Zero to 1 415 | c->ip++; 416 | break; 417 | case 0x41: 418 | if (verbose == 1) printf("\t%02X\tCMP A, B", c->mem[c->ip]); 419 | if (c->reg[0] == c->reg[1]) 420 | c->flags = c->flags | 0x01; // Zero to 1 421 | else 422 | { 423 | c->flags = c->flags & 0xFE; // Zero to 0 424 | if (c->reg[0] < c->reg[1]) 425 | c->flags = c->flags & 0xFD; // Carry to 0 426 | else if (c->reg[0] > c->reg[1]) 427 | c->flags = c->flags | 0x02; // Carry to 1 428 | } 429 | c->ip++; 430 | break; 431 | case 0x42: 432 | if (verbose == 1) printf("\t%02X\tCMP A, C", c->mem[c->ip]); 433 | if (c->reg[0] == c->reg[2]) 434 | c->flags = c->flags | 0x01; // Zero to 1 435 | else 436 | { 437 | c->flags = c->flags & 0xFE; // Zero to 0 438 | if (c->reg[0] < c->reg[2]) 439 | c->flags = c->flags & 0xFD; // Carry to 0 440 | else if (c->reg[0] > c->reg[2]) 441 | c->flags = c->flags | 0x02; // Carry to 1 442 | } 443 | c->ip++; 444 | break; 445 | case 0x43: 446 | if (verbose == 1) printf("\t%02X\tCMP A, D", c->mem[c->ip]); 447 | if (c->reg[0] == c->reg[3]) 448 | c->flags = c->flags | 0x01; // Zero to 1 449 | else 450 | { 451 | c->flags = c->flags & 0xFE; // Zero to 0 452 | if (c->reg[0] < c->reg[3]) 453 | c->flags = c->flags & 0xFD; // Carry to 0 454 | else if (c->reg[0] > c->reg[3]) 455 | c->flags = c->flags | 0x02; // Carry to 1 456 | } 457 | c->ip++; 458 | break; 459 | case 0x44: 460 | if (verbose == 1) printf("\t%02X\tCMP B, A", c->mem[c->ip]); 461 | if (c->reg[1] == c->reg[0]) 462 | c->flags = c->flags | 0x01; // Zero to 1 463 | else 464 | { 465 | c->flags = c->flags & 0xFE; // Zero to 0 466 | if (c->reg[1] < c->reg[0]) 467 | c->flags = c->flags & 0xFD; // Carry to 0 468 | else if (c->reg[1] > c->reg[0]) 469 | c->flags = c->flags | 0x02; // Carry to 1 470 | } 471 | c->ip++; 472 | break; 473 | case 0x45: 474 | if (verbose == 1) printf("\t%02X\tCMP B, B", c->mem[c->ip]); 475 | c->flags = c->flags | 0x01; // Zero to 1 476 | c->ip++; 477 | break; 478 | case 0x46: 479 | if (verbose == 1) printf("\t%02X\tCMP B, C", c->mem[c->ip]); 480 | if (c->reg[1] == c->reg[2]) 481 | c->flags = c->flags | 0x01; // Zero to 1 482 | else 483 | { 484 | c->flags = c->flags & 0xFE; // Zero to 0 485 | if (c->reg[1] < c->reg[2]) 486 | c->flags = c->flags & 0xFD; // Carry to 0 487 | else if (c->reg[1] > c->reg[2]) 488 | c->flags = c->flags | 0x02; // Carry to 1 489 | } 490 | c->ip++; 491 | break; 492 | case 0x47: 493 | if (verbose == 1) printf("\t%02X\tCMP B, D", c->mem[c->ip]); 494 | if (c->reg[1] == c->reg[3]) 495 | c->flags = c->flags | 0x01; // Zero to 1 496 | else 497 | { 498 | c->flags = c->flags & 0xFE; // Zero to 0 499 | if (c->reg[1] < c->reg[3]) 500 | c->flags = c->flags & 0xFD; // Carry to 0 501 | else if (c->reg[1] > c->reg[3]) 502 | c->flags = c->flags | 0x02; // Carry to 1 503 | } 504 | c->ip++; 505 | break; 506 | case 0x48: 507 | if (verbose == 1) printf("\t%02X\tCMP C, A", c->mem[c->ip]); 508 | if (c->reg[2] == c->reg[0]) 509 | c->flags = c->flags | 0x01; // Zero to 1 510 | else 511 | { 512 | c->flags = c->flags & 0xFE; // Zero to 0 513 | if (c->reg[2] < c->reg[0]) 514 | c->flags = c->flags & 0xFD; // Carry to 0 515 | else if (c->reg[2] > c->reg[0]) 516 | c->flags = c->flags | 0x02; // Carry to 1 517 | } 518 | c->ip++; 519 | break; 520 | case 0x49: 521 | if (verbose == 1) printf("\t%02X\tCMP C, B", c->mem[c->ip]); 522 | if (c->reg[2] == c->reg[1]) 523 | c->flags = c->flags | 0x01; // Zero to 1 524 | else 525 | { 526 | c->flags = c->flags & 0xFE; // Zero to 0 527 | if (c->reg[2] < c->reg[1]) 528 | c->flags = c->flags & 0xFD; // Carry to 0 529 | else if (c->reg[2] > c->reg[1]) 530 | c->flags = c->flags | 0x02; // Carry to 1 531 | } 532 | c->ip++; 533 | break; 534 | case 0x4A: 535 | if (verbose == 1) printf("\t%02X\tCMP C, C", c->mem[c->ip]); 536 | c->flags = c->flags | 0x01; // Zero to 1 537 | c->ip++; 538 | break; 539 | case 0x4B: 540 | if (verbose == 1) printf("\t%02X\tCMP C, D", c->mem[c->ip]); 541 | if (c->reg[2] == c->reg[3]) 542 | c->flags = c->flags | 0x01; // Zero to 1 543 | else 544 | { 545 | c->flags = c->flags & 0xFE; // Zero to 0 546 | if (c->reg[2] < c->reg[3]) 547 | c->flags = c->flags & 0xFD; // Carry to 0 548 | else if (c->reg[2] > c->reg[3]) 549 | c->flags = c->flags | 0x02; // Carry to 1 550 | } 551 | c->ip++; 552 | break; 553 | case 0x4C: 554 | if (verbose == 1) printf("\t%02X\tCMP D, A", c->mem[c->ip]); 555 | if (c->reg[3] == c->reg[0]) 556 | c->flags = c->flags | 0x01; // Zero to 1 557 | else 558 | { 559 | c->flags = c->flags & 0xFE; // Zero to 0 560 | if (c->reg[3] < c->reg[0]) 561 | c->flags = c->flags & 0xFD; // Carry to 0 562 | else if (c->reg[3] > c->reg[0]) 563 | c->flags = c->flags | 0x02; // Carry to 1 564 | } 565 | c->ip++; 566 | break; 567 | case 0x4D: 568 | if (verbose == 1) printf("\t%02X\tCMP D, B", c->mem[c->ip]); 569 | if (c->reg[3] == c->reg[1]) 570 | c->flags = c->flags | 0x01; // Zero to 1 571 | else 572 | { 573 | c->flags = c->flags & 0xFE; // Zero to 0 574 | if (c->reg[3] < c->reg[1]) 575 | c->flags = c->flags & 0xFD; // Carry to 0 576 | else if (c->reg[3] > c->reg[1]) 577 | c->flags = c->flags | 0x02; // Carry to 1 578 | } 579 | c->ip++; 580 | break; 581 | case 0x4E: 582 | if (verbose == 1) printf("\t%02X\tCMP D, C", c->mem[c->ip]); 583 | if (c->reg[3] == c->reg[2]) 584 | c->flags = c->flags | 0x01; // Zero to 1 585 | else 586 | { 587 | c->flags = c->flags & 0xFE; // Zero to 0 588 | if (c->reg[3] < c->reg[2]) 589 | c->flags = c->flags & 0xFD; // Carry to 0 590 | else if (c->reg[3] > c->reg[2]) 591 | c->flags = c->flags | 0x02; // Carry to 1 592 | } 593 | c->ip++; 594 | break; 595 | case 0x4F: 596 | if (verbose == 1) printf("\t%02X\tCMP D, D", c->mem[c->ip]); 597 | c->flags = c->flags | 0x01; // Zero to 1 598 | c->ip++; 599 | break; 600 | case 0x50: // 0x50 601 | if (verbose == 1) printf("\t%02X\tAND A, A", c->mem[c->ip]); 602 | c->reg[0] = c->reg[0] & c->reg[0]; 603 | c->ip++; 604 | break; 605 | case 0x51: 606 | if (verbose == 1) printf("\t%02X\tAND A, B", c->mem[c->ip]); 607 | c->reg[0] = c->reg[0] & c->reg[1]; 608 | c->ip++; 609 | break; 610 | case 0x52: 611 | if (verbose == 1) printf("\t%02X\tAND A, C", c->mem[c->ip]); 612 | c->reg[0] = c->reg[0] & c->reg[2]; 613 | c->ip++; 614 | break; 615 | case 0x53: 616 | if (verbose == 1) printf("\t%02X\tAND A, D", c->mem[c->ip]); 617 | c->reg[0] = c->reg[0] & c->reg[3]; 618 | c->ip++; 619 | break; 620 | case 0x54: 621 | if (verbose == 1) printf("\t%02X\tAND B, A", c->mem[c->ip]); 622 | c->reg[1] = c->reg[1] & c->reg[0]; 623 | c->ip++; 624 | break; 625 | case 0x55: 626 | if (verbose == 1) printf("\t%02X\tAND B, B", c->mem[c->ip]); 627 | c->reg[1] = c->reg[1] & c->reg[1]; 628 | c->ip++; 629 | break; 630 | case 0x56: 631 | if (verbose == 1) printf("\t%02X\tAND B, C", c->mem[c->ip]); 632 | c->reg[1] = c->reg[1] & c->reg[2]; 633 | c->ip++; 634 | break; 635 | case 0x57: 636 | if (verbose == 1) printf("\t%02X\tAND B, D", c->mem[c->ip]); 637 | c->reg[1] = c->reg[1] & c->reg[3]; 638 | c->ip++; 639 | break; 640 | case 0x58: 641 | if (verbose == 1) printf("\t%02X\tAND C, A", c->mem[c->ip]); 642 | c->reg[2] = c->reg[2] & c->reg[0]; 643 | c->ip++; 644 | break; 645 | case 0x59: 646 | if (verbose == 1) printf("\t%02X\tAND C, B", c->mem[c->ip]); 647 | c->reg[2] = c->reg[2] & c->reg[1]; 648 | c->ip++; 649 | break; 650 | case 0x5A: 651 | if (verbose == 1) printf("\t%02X\tAND C, C", c->mem[c->ip]); 652 | c->reg[2] = c->reg[2] & c->reg[2]; 653 | c->ip++; 654 | break; 655 | case 0x5B: 656 | if (verbose == 1) printf("\t%02X\tAND C, D", c->mem[c->ip]); 657 | c->reg[2] = c->reg[2] & c->reg[3]; 658 | c->ip++; 659 | break; 660 | case 0x5C: 661 | if (verbose == 1) printf("\t%02X\tAND D, A", c->mem[c->ip]); 662 | c->reg[3] = c->reg[3] & c->reg[0]; 663 | c->ip++; 664 | break; 665 | case 0x5D: 666 | if (verbose == 1) printf("\t%02X\tAND D, B", c->mem[c->ip]); 667 | c->reg[3] = c->reg[3] & c->reg[1]; 668 | c->ip++; 669 | break; 670 | case 0x5E: 671 | if (verbose == 1) printf("\t%02X\tAND D, C", c->mem[c->ip]); 672 | c->reg[3] = c->reg[3] & c->reg[2]; 673 | c->ip++; 674 | break; 675 | case 0x5F: 676 | if (verbose == 1) printf("\t%02X\tAND D, D", c->mem[c->ip]); 677 | c->reg[3] = c->reg[3] & c->reg[3]; 678 | c->ip++; 679 | break; 680 | case 0x60: // 0x60 681 | if (verbose == 1) printf("\t%02X\tOR A, A", c->mem[c->ip]); 682 | c->reg[0] = c->reg[0] | c->reg[0]; 683 | c->ip++; 684 | break; 685 | case 0x61: 686 | if (verbose == 1) printf("\t%02X\tOR A, B", c->mem[c->ip]); 687 | c->reg[0] = c->reg[0] | c->reg[1]; 688 | c->ip++; 689 | break; 690 | case 0x62: 691 | if (verbose == 1) printf("\t%02X\tOR A, C", c->mem[c->ip]); 692 | c->reg[0] = c->reg[0] | c->reg[2]; 693 | c->ip++; 694 | break; 695 | case 0x63: 696 | if (verbose == 1) printf("\t%02X\tOR A, D", c->mem[c->ip]); 697 | c->reg[0] = c->reg[0] | c->reg[3]; 698 | c->ip++; 699 | break; 700 | case 0x64: 701 | if (verbose == 1) printf("\t%02X\tOR B, A", c->mem[c->ip]); 702 | c->reg[1] = c->reg[1] | c->reg[0]; 703 | c->ip++; 704 | break; 705 | case 0x65: 706 | if (verbose == 1) printf("\t%02X\tOR B, B", c->mem[c->ip]); 707 | c->reg[1] = c->reg[1] | c->reg[1]; 708 | c->ip++; 709 | break; 710 | case 0x66: 711 | if (verbose == 1) printf("\t%02X\tOR B, C", c->mem[c->ip]); 712 | c->reg[1] = c->reg[1] | c->reg[2]; 713 | c->ip++; 714 | break; 715 | case 0x67: 716 | if (verbose == 1) printf("\t%02X\tOR B, D", c->mem[c->ip]); 717 | c->reg[1] = c->reg[1] | c->reg[3]; 718 | c->ip++; 719 | break; 720 | case 0x68: 721 | if (verbose == 1) printf("\t%02X\tOR C, A", c->mem[c->ip]); 722 | c->reg[2] = c->reg[2] | c->reg[0]; 723 | c->ip++; 724 | break; 725 | case 0x69: 726 | if (verbose == 1) printf("\t%02X\tOR C, B", c->mem[c->ip]); 727 | c->reg[2] = c->reg[2] | c->reg[1]; 728 | c->ip++; 729 | break; 730 | case 0x6A: 731 | if (verbose == 1) printf("\t%02X\tOR C, C", c->mem[c->ip]); 732 | c->reg[2] = c->reg[2] | c->reg[2]; 733 | c->ip++; 734 | break; 735 | case 0x6B: 736 | if (verbose == 1) printf("\t%02X\tOR C, D", c->mem[c->ip]); 737 | c->reg[2] = c->reg[2] | c->reg[3]; 738 | c->ip++; 739 | break; 740 | case 0x6C: 741 | if (verbose == 1) printf("\t%02X\tOR D, A", c->mem[c->ip]); 742 | c->reg[3] = c->reg[3] | c->reg[0]; 743 | c->ip++; 744 | break; 745 | case 0x6D: 746 | if (verbose == 1) printf("\t%02X\tOR D, B", c->mem[c->ip]); 747 | c->reg[3] = c->reg[3] | c->reg[1]; 748 | c->ip++; 749 | break; 750 | case 0x6E: 751 | if (verbose == 1) printf("\t%02X\tOR D, C", c->mem[c->ip]); 752 | c->reg[3] = c->reg[3] | c->reg[2]; 753 | c->ip++; 754 | break; 755 | case 0x6F: 756 | if (verbose == 1) printf("\t%02X\tOR D, D", c->mem[c->ip]); 757 | c->reg[3] = c->reg[3] | c->reg[3]; 758 | c->ip++; 759 | break; 760 | case 0x70: // 0x70 761 | if (verbose == 1) printf("\t%02X\tXOR A, A", c->mem[c->ip]); 762 | c->reg[0] = c->reg[0] ^ c->reg[0]; 763 | c->ip++; 764 | break; 765 | case 0x71: 766 | if (verbose == 1) printf("\t%02X\tXOR A, B", c->mem[c->ip]); 767 | c->reg[0] = c->reg[0] ^ c->reg[1]; 768 | c->ip++; 769 | break; 770 | case 0x72: 771 | if (verbose == 1) printf("\t%02X\tXOR A, C", c->mem[c->ip]); 772 | c->reg[0] = c->reg[0] ^ c->reg[2]; 773 | c->ip++; 774 | break; 775 | case 0x73: 776 | if (verbose == 1) printf("\t%02X\tXOR A, D", c->mem[c->ip]); 777 | c->reg[0] = c->reg[0] ^ c->reg[3]; 778 | c->ip++; 779 | break; 780 | case 0x74: 781 | if (verbose == 1) printf("\t%02X\tXOR B, A", c->mem[c->ip]); 782 | c->reg[1] = c->reg[1] ^ c->reg[0]; 783 | c->ip++; 784 | break; 785 | case 0x75: 786 | if (verbose == 1) printf("\t%02X\tXOR B, B", c->mem[c->ip]); 787 | c->reg[1] = c->reg[1] ^ c->reg[1]; 788 | c->ip++; 789 | break; 790 | case 0x76: 791 | if (verbose == 1) printf("\t%02X\tXOR B, C", c->mem[c->ip]); 792 | c->reg[1] = c->reg[1] ^ c->reg[2]; 793 | c->ip++; 794 | break; 795 | case 0x77: 796 | if (verbose == 1) printf("\t%02X\tXOR B, D", c->mem[c->ip]); 797 | c->reg[1] = c->reg[1] ^ c->reg[3]; 798 | c->ip++; 799 | break; 800 | case 0x78: 801 | if (verbose == 1) printf("\t%02X\tXOR C, A", c->mem[c->ip]); 802 | c->reg[2] = c->reg[2] ^ c->reg[0]; 803 | c->ip++; 804 | break; 805 | case 0x79: 806 | if (verbose == 1) printf("\t%02X\tXOR C, B", c->mem[c->ip]); 807 | c->reg[2] = c->reg[2] ^ c->reg[1]; 808 | c->ip++; 809 | break; 810 | case 0x7A: 811 | if (verbose == 1) printf("\t%02X\tXOR C, C", c->mem[c->ip]); 812 | c->reg[2] = c->reg[2] ^ c->reg[2]; 813 | c->ip++; 814 | break; 815 | case 0x7B: 816 | if (verbose == 1) printf("\t%02X\tXOR C, D", c->mem[c->ip]); 817 | c->reg[2] = c->reg[2] ^ c->reg[3]; 818 | c->ip++; 819 | break; 820 | case 0x7C: 821 | if (verbose == 1) printf("\t%02X\tXOR D, A", c->mem[c->ip]); 822 | c->reg[3] = c->reg[3] ^ c->reg[0]; 823 | c->ip++; 824 | break; 825 | case 0x7D: 826 | if (verbose == 1) printf("\t%02X\tXOR D, B", c->mem[c->ip]); 827 | c->reg[3] = c->reg[3] ^ c->reg[1]; 828 | c->ip++; 829 | break; 830 | case 0x7E: 831 | if (verbose == 1) printf("\t%02X\tXOR D, C", c->mem[c->ip]); 832 | c->reg[3] = c->reg[3] ^ c->reg[2]; 833 | c->ip++; 834 | break; 835 | case 0x7F: 836 | if (verbose == 1) printf("\t%02X\tXOR D, D", c->mem[c->ip]); 837 | c->reg[3] = c->reg[3] ^ c->reg[3]; 838 | c->ip++; 839 | break; 840 | case 0x80: // 0x80 841 | if (verbose == 1) printf("\t%02X%02X\tJL [0x%02X]", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 842 | 843 | if ((c->flags & 0x02) == 0x00) // Carry == 0 844 | c->ip = c->mem[c->ip+1]; 845 | else 846 | c->ip+=2; 847 | break; 848 | case 0x81: 849 | if (verbose == 1) printf("\t%02X%02X\tJLE [0x%02X]", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 850 | if ((c->flags & 0x02) == 0x00 || (c->flags & 0x01) == 0x01) // Carry = 0 || Zero = 1 851 | c->ip = c->mem[c->ip+1]; 852 | else 853 | c->ip+=2; 854 | break; 855 | case 0x82: 856 | if (verbose == 1) printf("\t%02X%02X\tJE [0x%02X]", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 857 | if ((c->flags & 0x01) == 0x01) // Zero = 1 858 | c->ip = c->mem[c->ip+1]; 859 | else 860 | c->ip+=2; 861 | break; 862 | case 0x83: 863 | if (verbose == 1) printf("\t%02X%02X\tJGE [0x%02X]", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 864 | if ((c->flags & 0x02) == 0x02 || (c->flags & 0x01) == 0x01) // Carry = 1 || Zero = 1 865 | c->ip = c->mem[c->ip+1]; 866 | else 867 | c->ip+=2; 868 | break; 869 | case 0x84: 870 | if (verbose == 1) printf("\t%02X%02X\tJG [0x%02X]", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 871 | if ((c->flags & 0x02) == 0x02) // Carry = 1 872 | c->ip = c->mem[c->ip+1]; 873 | else 874 | c->ip+=2; 875 | break; 876 | case 0x85: 877 | if (verbose == 1) printf("\t%02X%02X\tJMP [0x%02X]", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 878 | c->ip = c->mem[c->ip+1]; 879 | break; 880 | case 0x86: 881 | if (verbose == 1) printf("\t%02X%02X\tJNE [0x%02X]", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 882 | if ((c->flags & 0x01) == 0x00) // Zero = 0 883 | c->ip = c->mem[c->ip+1]; 884 | else 885 | c->ip+=2; 886 | break; 887 | case 0x87: 888 | if (verbose == 1) printf("\t%02X%02X\tCALL [0x%02X]", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 889 | c->ipstack[3] = c->ipstack[2]; 890 | c->ipstack[2] = c->ipstack[1]; 891 | c->ipstack[1] = c->ipstack[0]; 892 | c->ipstack[0] = c->ip+2; 893 | c->ip = c->mem[c->ip+1]; 894 | if (verbose == 1) printf("\tI: "); 895 | for(tint=0; tint<4; tint++) 896 | { 897 | if (verbose == 1) printf("%02X ",c->ipstack[tint]); 898 | } 899 | break; 900 | case 0x88: 901 | if (verbose == 1) printf("\t%02X%02X\tMOV [0x%02X], A", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 902 | c->mem[c->mem[c->ip+1]] = c->reg[0]; 903 | c->ip+=2; 904 | break; 905 | case 0x89: 906 | if (verbose == 1) printf("\t%02X%02X\tMOV [0x%02X], B", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 907 | c->mem[c->mem[c->ip+1]] = c->reg[1]; 908 | c->ip+=2; 909 | break; 910 | case 0x8A: 911 | if (verbose == 1) printf("\t%02X%02X\tMOV [0x%02X], C", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 912 | c->mem[c->mem[c->ip+1]] = c->reg[2]; 913 | c->ip+=2; 914 | break; 915 | case 0x8B: 916 | if (verbose == 1) printf("\t%02X%02X\tMOV [0x%02X], D", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 917 | c->mem[c->mem[c->ip+1]] = c->reg[3]; 918 | c->ip+=2; 919 | break; 920 | case 0x8C: 921 | if (verbose == 1) printf("\t%02X%02X\tMOV A, [0x%02X]", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 922 | c->reg[0] = c->mem[c->mem[c->ip+1]]; 923 | c->ip+=2; 924 | break; 925 | case 0x8D: 926 | if (verbose == 1) printf("\t%02X%02X\tMOV B, [0x%02X]", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 927 | c->reg[1] = c->mem[c->mem[c->ip+1]]; 928 | c->ip+=2; 929 | break; 930 | case 0x8E: 931 | if (verbose == 1) printf("\t%02X%02X\tMOV C, [0x%02X]", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 932 | c->reg[2] = c->mem[c->mem[c->ip+1]]; 933 | c->ip+=2; 934 | break; 935 | case 0x8F: 936 | if (verbose == 1) printf("\t%02X%02X\tMOV D, [0x%02X]", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 937 | c->reg[3] = c->mem[c->mem[c->ip+1]]; 938 | c->ip+=2; 939 | break; 940 | case 0x90: // 0x90 941 | if (verbose == 1) printf("\t%02X%02X\tADD A, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 942 | c->reg[0]+=c->mem[c->ip+1]; 943 | c->ip+=2; 944 | break; 945 | case 0x91: 946 | if (verbose == 1) printf("\t%02X%02X\tADD B, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 947 | c->reg[1]+=c->mem[c->ip+1]; 948 | c->ip+=2; 949 | break; 950 | case 0x92: 951 | if (verbose == 1) printf("\t%02X%02X\tADD C, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 952 | c->reg[2]+=c->mem[c->ip+1]; 953 | c->ip+=2; 954 | break; 955 | case 0x93: 956 | if (verbose == 1) printf("\t%02X%02X\tADD D, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 957 | c->reg[3]+=c->mem[c->ip+1]; 958 | c->ip+=2; 959 | break; 960 | case 0x94: 961 | if (verbose == 1) printf("\t%02X%02X\tSUB A, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 962 | c->reg[0]-=c->mem[c->ip+1]; 963 | c->ip+=2; 964 | break; 965 | case 0x95: 966 | if (verbose == 1) printf("\t%02X%02X\tSUB B, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 967 | c->reg[1]-=c->mem[c->ip+1]; 968 | c->ip+=2; 969 | break; 970 | case 0x96: 971 | if (verbose == 1) printf("\t%02X%02X\tSUB C, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 972 | c->reg[2]-=c->mem[c->ip+1]; 973 | c->ip+=2; 974 | break; 975 | case 0x97: 976 | if (verbose == 1) printf("\t%02X%02X\tSUB D, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 977 | c->reg[3]-=c->mem[c->ip+1]; 978 | c->ip+=2; 979 | break; 980 | case 0x98: 981 | if (verbose == 1) printf("\t%02X%02X\tMOV A, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 982 | c->reg[0] = c->mem[c->ip+1]; 983 | c->ip+=2; 984 | break; 985 | case 0x99: 986 | if (verbose == 1) printf("\t%02X%02X\tMOV B, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 987 | c->reg[1] = c->mem[c->ip+1]; 988 | c->ip+=2; 989 | break; 990 | case 0x9A: 991 | if (verbose == 1) printf("\t%02X%02X\tMOV C, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 992 | c->reg[2] = c->mem[c->ip+1]; 993 | c->ip+=2; 994 | break; 995 | case 0x9B: 996 | if (verbose == 1) printf("\t%02X%02X\tMOV D, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 997 | c->reg[3] = c->mem[c->ip+1]; 998 | c->ip+=2; 999 | break; 1000 | case 0x9C: 1001 | if (verbose == 1) printf("\t%02X%02X\tCMP A, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 1002 | if (c->reg[0] == c->mem[c->ip+1]) 1003 | c->flags = c->flags | 0x01; // Zero to 1 1004 | else 1005 | { 1006 | c->flags = c->flags & 0xFE; // Zero to 0 1007 | if (c->reg[0] < c->mem[c->ip+1]) 1008 | c->flags = c->flags & 0xFD; // Carry to 0 1009 | else if (c->reg[0] > c->mem[c->ip+1]) 1010 | c->flags = c->flags | 0x02; // Carry to 1 1011 | } 1012 | c->ip+=2; 1013 | break; 1014 | case 0x9D: 1015 | if (verbose == 1) printf("\t%02X%02X\tCMP B, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 1016 | if (c->reg[1] == c->mem[c->ip+1]) 1017 | c->flags = c->flags | 0x01; // Zero to 1 1018 | else 1019 | { 1020 | c->flags = c->flags & 0xFE; // Zero to 0 1021 | if (c->reg[1] < c->mem[c->ip+1]) 1022 | c->flags = c->flags & 0xFD; // Carry to 0 1023 | else if (c->reg[1] > c->mem[c->ip+1]) 1024 | c->flags = c->flags | 0x02; // Carry to 1 1025 | } 1026 | c->ip+=2; 1027 | break; 1028 | case 0x9E: 1029 | if (verbose == 1) printf("\t%02X%02X\tCMP C, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 1030 | if (c->reg[2] == c->mem[c->ip+1]) 1031 | c->flags = c->flags | 0x01; // Zero to 1 1032 | else 1033 | { 1034 | c->flags = c->flags & 0xFE; // Zero to 0 1035 | if (c->reg[2] < c->mem[c->ip+1]) 1036 | c->flags = c->flags & 0xFD; // Carry to 0 1037 | else if (c->reg[2] > c->mem[c->ip+1]) 1038 | c->flags = c->flags | 0x02; // Carry to 1 1039 | } 1040 | c->ip+=2; 1041 | break; 1042 | case 0x9F: 1043 | if (verbose == 1) printf("\t%02X%02X\tCMP D, 0x%02X", c->mem[c->ip], c->mem[c->ip+1], c->mem[c->ip+1]); 1044 | if (c->reg[3] == c->mem[c->ip+1]) 1045 | c->flags = c->flags | 0x01; // Zero to 1 1046 | else 1047 | { 1048 | c->flags = c->flags & 0xFE; // Zero to 0 1049 | if (c->reg[3] < c->mem[c->ip+1]) 1050 | c->flags = c->flags & 0xFD; // Carry to 0 1051 | else if (c->reg[3] > c->mem[c->ip+1]) 1052 | c->flags = c->flags | 0x02; // Carry to 1 1053 | } 1054 | c->ip+=2; 1055 | break; 1056 | case 0xA0: // 0xA0 1057 | if (verbose == 1) printf("\t%02X\tMOV [&A], A", c->mem[c->ip]); 1058 | c->mem[c->reg[0]] = c->reg[0]; 1059 | c->ip++; 1060 | break; 1061 | case 0xA1: 1062 | if (verbose == 1) printf("\t%02X\tMOV [&A], B", c->mem[c->ip]); 1063 | c->mem[c->reg[0]] = c->reg[1]; 1064 | c->ip++; 1065 | break; 1066 | case 0xA2: 1067 | if (verbose == 1) printf("\t%02X\tMOV [&A], C", c->mem[c->ip]); 1068 | c->mem[c->reg[0]] = c->reg[2]; 1069 | c->ip++; 1070 | break; 1071 | case 0xA3: 1072 | if (verbose == 1) printf("\t%02X\tMOV [&A], D", c->mem[c->ip]); 1073 | c->mem[c->reg[0]] = c->reg[3]; 1074 | c->ip++; 1075 | break; 1076 | case 0xA4: 1077 | if (verbose == 1) printf("\t%02X\tMOV [&B], A", c->mem[c->ip]); 1078 | c->mem[c->reg[1]] = c->reg[0]; 1079 | c->ip++; 1080 | break; 1081 | case 0xA5: 1082 | if (verbose == 1) printf("\t%02X\tMOV [&B], B", c->mem[c->ip]); 1083 | c->mem[c->reg[1]] = c->reg[1]; 1084 | c->ip++; 1085 | break; 1086 | case 0xA6: 1087 | if (verbose == 1) printf("\t%02X\tMOV [&B], C", c->mem[c->ip]); 1088 | c->mem[c->reg[1]] = c->reg[2]; 1089 | c->ip++; 1090 | break; 1091 | case 0xA7: 1092 | if (verbose == 1) printf("\t%02X\tMOV [&B], D", c->mem[c->ip]); 1093 | c->mem[c->reg[1]] = c->reg[3]; 1094 | c->ip++; 1095 | break; 1096 | case 0xA8: 1097 | if (verbose == 1) printf("\t%02X\tMOV [&C], A", c->mem[c->ip]); 1098 | c->mem[c->reg[2]] = c->reg[0]; 1099 | c->ip++; 1100 | break; 1101 | case 0xA9: 1102 | if (verbose == 1) printf("\t%02X\tMOV [&C], B", c->mem[c->ip]); 1103 | c->mem[c->reg[2]] = c->reg[1]; 1104 | c->ip++; 1105 | break; 1106 | case 0xAA: 1107 | if (verbose == 1) printf("\t%02X\tMOV [&C], C", c->mem[c->ip]); 1108 | c->mem[c->reg[2]] = c->reg[2]; 1109 | c->ip++; 1110 | break; 1111 | case 0xAB: 1112 | if (verbose == 1) printf("\t%02X\tMOV [&C], D", c->mem[c->ip]); 1113 | c->mem[c->reg[2]] = c->reg[3]; 1114 | c->ip++; 1115 | break; 1116 | case 0xAC: 1117 | if (verbose == 1) printf("\t%02X\tMOV [&D], A", c->mem[c->ip]); 1118 | c->mem[c->reg[3]] = c->reg[0]; 1119 | c->ip++; 1120 | break; 1121 | case 0xAD: 1122 | if (verbose == 1) printf("\t%02X\tMOV [&D], B", c->mem[c->ip]); 1123 | c->mem[c->reg[3]] = c->reg[1]; 1124 | c->ip++; 1125 | break; 1126 | case 0xAE: 1127 | if (verbose == 1) printf("\t%02X\tMOV [&D], C", c->mem[c->ip]); 1128 | c->mem[c->reg[3]] = c->reg[2]; 1129 | c->ip++; 1130 | break; 1131 | case 0xAF: 1132 | if (verbose == 1) printf("\t%02X\tMOV [&D], D", c->mem[c->ip]); 1133 | c->mem[c->reg[3]] = c->reg[3]; 1134 | c->ip++; 1135 | break; 1136 | case 0xB0: // 0xB0 1137 | if (verbose == 1) printf("\t%02X\tMOV A, [&A]", c->mem[c->ip]); 1138 | c->reg[0] = c->mem[c->reg[0]]; 1139 | c->ip++; 1140 | break; 1141 | case 0xB1: 1142 | if (verbose == 1) printf("\t%02X\tMOV A, [&B]", c->mem[c->ip]); 1143 | c->reg[0] = c->mem[c->reg[1]]; 1144 | c->ip++; 1145 | break; 1146 | case 0xB2: 1147 | if (verbose == 1) printf("\t%02X\tMOV A, [&C]", c->mem[c->ip]); 1148 | c->reg[0] = c->mem[c->reg[2]]; 1149 | c->ip++; 1150 | break; 1151 | case 0xB3: 1152 | if (verbose == 1) printf("\t%02X\tMOV A, [&D]", c->mem[c->ip]); 1153 | c->reg[0] = c->mem[c->reg[3]]; 1154 | c->ip++; 1155 | break; 1156 | case 0xB4: 1157 | if (verbose == 1) printf("\t%02X\tMOV B, [&A]", c->mem[c->ip]); 1158 | c->reg[1] = c->mem[c->reg[0]]; 1159 | c->ip++; 1160 | break; 1161 | case 0xB5: 1162 | if (verbose == 1) printf("\t%02X\tMOV B, [&B]", c->mem[c->ip]); 1163 | c->reg[1] = c->mem[c->reg[1]]; 1164 | c->ip++; 1165 | break; 1166 | case 0xB6: 1167 | if (verbose == 1) printf("\t%02X\tMOV B, [&C]", c->mem[c->ip]); 1168 | c->reg[1] = c->mem[c->reg[2]]; 1169 | c->ip++; 1170 | break; 1171 | case 0xB7: 1172 | if (verbose == 1) printf("\t%02X\tMOV B, [&D]", c->mem[c->ip]); 1173 | c->reg[1] = c->mem[c->reg[3]]; 1174 | c->ip++; 1175 | break; 1176 | case 0xB8: 1177 | if (verbose == 1) printf("\t%02X\tMOV C, [&A]", c->mem[c->ip]); 1178 | c->reg[2] = c->mem[c->reg[0]]; 1179 | c->ip++; 1180 | break; 1181 | case 0xB9: 1182 | if (verbose == 1) printf("\t%02X\tMOV C, [&B]", c->mem[c->ip]); 1183 | c->reg[2] = c->mem[c->reg[1]]; 1184 | c->ip++; 1185 | break; 1186 | case 0xBA: 1187 | if (verbose == 1) printf("\t%02X\tMOV C, [&C]", c->mem[c->ip]); 1188 | c->reg[2] = c->mem[c->reg[2]]; 1189 | c->ip++; 1190 | break; 1191 | case 0xBB: 1192 | if (verbose == 1) printf("\t%02X\tMOV C, [&D]", c->mem[c->ip]); 1193 | c->reg[2] = c->mem[c->reg[3]]; 1194 | c->ip++; 1195 | break; 1196 | case 0xBC: 1197 | if (verbose == 1) printf("\t%02X\tMOV D, [&A]", c->mem[c->ip]); 1198 | c->reg[3] = c->mem[c->reg[0]]; 1199 | c->ip++; 1200 | break; 1201 | case 0xBD: 1202 | if (verbose == 1) printf("\t%02X\tMOV D, [&B]", c->mem[c->ip]); 1203 | c->reg[3] = c->mem[c->reg[1]]; 1204 | c->ip++; 1205 | break; 1206 | case 0xBE: 1207 | if (verbose == 1) printf("\t%02X\tMOV D, [&C]", c->mem[c->ip]); 1208 | c->reg[3] = c->mem[c->reg[2]]; 1209 | c->ip++; 1210 | break; 1211 | case 0xBF: 1212 | if (verbose == 1) printf("\t%02X\tMOV D, [&D]", c->mem[c->ip]); 1213 | c->reg[3] = c->mem[c->reg[3]]; 1214 | c->ip++; 1215 | break; 1216 | case 0xC0: // 0xC0 1217 | if (verbose == 1) printf("\t%02X\tIN A, pA", c->mem[c->ip]); 1218 | if (i808checkportflag(c, c->reg[0]) == 0) 1219 | c->flags = c->flags & 0xFE; // Zero to 0 1220 | else 1221 | c->flags = c->flags | 0x01; // Zero to 1 1222 | c->reg[0] = c->ioport[c->reg[0] & 0x0F]; 1223 | i808setportflag(c, c->reg[0], 0); 1224 | c->ip++; 1225 | break; 1226 | case 0xC1: 1227 | if (verbose == 1) printf("\t%02X\tIN A, pB", c->mem[c->ip]); 1228 | if (i808checkportflag(c, c->reg[1]) == 0) 1229 | c->flags = c->flags & 0xFE; // Zero to 0 1230 | else 1231 | c->flags = c->flags | 0x01; // Zero to 1 1232 | c->reg[0] = c->ioport[c->reg[1] & 0x0F]; 1233 | i808setportflag(c, c->reg[1], 0); 1234 | c->ip++; 1235 | break; 1236 | case 0xC2: 1237 | if (verbose == 1) printf("\t%02X\tIN A, pC", c->mem[c->ip]); 1238 | if (i808checkportflag(c, c->reg[2]) == 0) 1239 | c->flags = c->flags & 0xFE; // Zero to 0 1240 | else 1241 | c->flags = c->flags | 0x01; // Zero to 1 1242 | c->reg[0] = c->ioport[c->reg[2] & 0x0F]; 1243 | i808setportflag(c, c->reg[2], 0); 1244 | c->ip++; 1245 | break; 1246 | case 0xC3: 1247 | if (verbose == 1) printf("\t%02X\tIN A, pD", c->mem[c->ip]); 1248 | if (i808checkportflag(c, c->reg[3]) == 0) 1249 | c->flags = c->flags & 0xFE; // Zero to 0 1250 | else 1251 | c->flags = c->flags | 0x01; // Zero to 1 1252 | c->reg[0] = c->ioport[c->reg[3] & 0x0F]; 1253 | i808setportflag(c, c->reg[3], 0); 1254 | c->ip++; 1255 | break; 1256 | case 0xC4: 1257 | if (verbose == 1) printf("\t%02X\tIN B, pA", c->mem[c->ip]); 1258 | if (i808checkportflag(c, c->reg[0]) == 0) 1259 | c->flags = c->flags & 0xFE; // Zero to 0 1260 | else 1261 | c->flags = c->flags | 0x01; // Zero to 1 1262 | c->reg[1] = c->ioport[c->reg[0] & 0x0F]; 1263 | i808setportflag(c, c->reg[0], 0); 1264 | c->ip++; 1265 | break; 1266 | case 0xC5: 1267 | if (verbose == 1) printf("\t%02X\tIN B, pB", c->mem[c->ip]); 1268 | if (i808checkportflag(c, c->reg[1]) == 0) 1269 | c->flags = c->flags & 0xFE; // Zero to 0 1270 | else 1271 | c->flags = c->flags | 0x01; // Zero to 1 1272 | c->reg[1] = c->ioport[c->reg[1] & 0x0F]; 1273 | i808setportflag(c, c->reg[1], 0); 1274 | c->ip++; 1275 | break; 1276 | case 0xC6: 1277 | if (verbose == 1) printf("\t%02X\tIN B, pC", c->mem[c->ip]); 1278 | if (i808checkportflag(c, c->reg[2]) == 0) 1279 | c->flags = c->flags & 0xFE; // Zero to 0 1280 | else 1281 | c->flags = c->flags | 0x01; // Zero to 1 1282 | c->reg[1] = c->ioport[c->reg[2] & 0x0F]; 1283 | i808setportflag(c, c->reg[2], 0); 1284 | c->ip++; 1285 | break; 1286 | case 0xC7: 1287 | if (verbose == 1) printf("\t%02X\tIN B, pD", c->mem[c->ip]); 1288 | if (i808checkportflag(c, c->reg[3]) == 0) 1289 | c->flags = c->flags & 0xFE; // Zero to 0 1290 | else 1291 | c->flags = c->flags | 0x01; // Zero to 1 1292 | c->reg[1] = c->ioport[c->reg[3] & 0x0F]; 1293 | i808setportflag(c, c->reg[3], 0); 1294 | c->ip++; 1295 | break; 1296 | case 0xC8: 1297 | if (verbose == 1) printf("\t%02X\tIN C, pA", c->mem[c->ip]); 1298 | if (i808checkportflag(c, c->reg[0]) == 0) 1299 | c->flags = c->flags & 0xFE; // Zero to 0 1300 | else 1301 | c->flags = c->flags | 0x01; // Zero to 1 1302 | c->reg[2] = c->ioport[c->reg[0] & 0x0F]; 1303 | i808setportflag(c, c->reg[0], 0); 1304 | c->ip++; 1305 | break; 1306 | case 0xC9: 1307 | if (verbose == 1) printf("\t%02X\tIN C, pB", c->mem[c->ip]); 1308 | if (i808checkportflag(c, c->reg[1]) == 0) 1309 | c->flags = c->flags & 0xFE; // Zero to 0 1310 | else 1311 | c->flags = c->flags | 0x01; // Zero to 1 1312 | c->reg[2] = c->ioport[c->reg[1] & 0x0F]; 1313 | i808setportflag(c, c->reg[1], 0); 1314 | c->ip++; 1315 | break; 1316 | case 0xCA: 1317 | if (verbose == 1) printf("\t%02X\tIN C, pC", c->mem[c->ip]); 1318 | if (i808checkportflag(c, c->reg[2]) == 0) 1319 | c->flags = c->flags & 0xFE; // Zero to 0 1320 | else 1321 | c->flags = c->flags | 0x01; // Zero to 1 1322 | c->reg[2] = c->ioport[c->reg[2] & 0x0F]; 1323 | i808setportflag(c, c->reg[2], 0); 1324 | c->ip++; 1325 | break; 1326 | case 0xCB: 1327 | if (verbose == 1) printf("\t%02X\tIN C, pD", c->mem[c->ip]); 1328 | if (i808checkportflag(c, c->reg[3]) == 0) 1329 | c->flags = c->flags & 0xFE; // Zero to 0 1330 | else 1331 | c->flags = c->flags | 0x01; // Zero to 1 1332 | 1333 | c->reg[2] = c->ioport[c->reg[3] & 0x0F]; 1334 | i808setportflag(c, c->reg[3], 0); 1335 | c->ip++; 1336 | break; 1337 | case 0xCC: 1338 | if (verbose == 1) printf("\t%02X\tIN D, pA", c->mem[c->ip]); 1339 | if (i808checkportflag(c, c->reg[0]) == 1) 1340 | c->flags = c->flags & 0xFE; // Zero to 0 1341 | else 1342 | c->flags = c->flags | 0x01; // Zero to 1 1343 | c->reg[3] = c->ioport[c->reg[0] & 0x0F]; 1344 | i808setportflag(c, c->reg[0], 0); 1345 | c->ip++; 1346 | break; 1347 | case 0xCD: 1348 | if (verbose == 1) printf("\t%02X\tIN D, pB", c->mem[c->ip]); 1349 | if (i808checkportflag(c, c->reg[1]) == 0) 1350 | c->flags = c->flags & 0xFE; // Zero to 0 1351 | else 1352 | c->flags = c->flags | 0x01; // Zero to 1 1353 | c->reg[3] = c->ioport[c->reg[1] & 0x0F]; 1354 | i808setportflag(c, c->reg[1], 0); 1355 | c->ip++; 1356 | break; 1357 | case 0xCE: 1358 | if (verbose == 1) printf("\t%02X\tIN D, pC", c->mem[c->ip]); 1359 | if (i808checkportflag(c, c->reg[2]) == 0) 1360 | c->flags = c->flags & 0xFE; // Zero to 0 1361 | else 1362 | c->flags = c->flags | 0x01; // Zero to 1 1363 | c->reg[3] = c->ioport[c->reg[2] & 0x0F]; 1364 | i808setportflag(c, c->reg[2], 0); 1365 | c->ip++; 1366 | break; 1367 | case 0xCF: 1368 | if (verbose == 1) printf("\t%02X\tIN D, pD", c->mem[c->ip]); 1369 | if (i808checkportflag(c, c->reg[3]) == 0) 1370 | c->flags = c->flags & 0xFE; // Zero to 0 1371 | else 1372 | c->flags = c->flags | 0x01; // Zero to 1 1373 | c->reg[3] = c->ioport[c->reg[3] & 0x0F]; 1374 | i808setportflag(c, c->reg[3], 0); 1375 | c->ip++; 1376 | break; 1377 | case 0xD0: // 0xD0 1378 | if (verbose == 1) printf("\t%02X\tOUT pA, A", c->mem[c->ip]); 1379 | c->ioport[c->reg[0] & 0x0F] = c->reg[0]; 1380 | i808setportflag(c, c->reg[0], 1); 1381 | c->ip++; 1382 | break; 1383 | case 0xD1: 1384 | if (verbose == 1) printf("\t%02X\tOUT pA, B", c->mem[c->ip]); 1385 | c->ioport[c->reg[0] & 0x0F] = c->reg[1]; 1386 | i808setportflag(c, c->reg[0], 1); 1387 | c->ip++; 1388 | break; 1389 | case 0xD2: 1390 | if (verbose == 1) printf("\t%02X\tOUT pA, C", c->mem[c->ip]); 1391 | c->ioport[c->reg[0] & 0x0F] = c->reg[2]; 1392 | i808setportflag(c, c->reg[0], 1); 1393 | c->ip++; 1394 | break; 1395 | case 0xD3: 1396 | if (verbose == 1) printf("\t%02X\tOUT pA, D", c->mem[c->ip]); 1397 | c->ioport[c->reg[0] & 0x0F] = c->reg[3]; 1398 | i808setportflag(c, c->reg[0], 1); 1399 | c->ip++; 1400 | break; 1401 | case 0xD4: 1402 | if (verbose == 1) printf("\t%02X\tOUT pB, A", c->mem[c->ip]); 1403 | c->ioport[c->reg[1] & 0x0F] = c->reg[0]; 1404 | i808setportflag(c, c->reg[1], 1); 1405 | c->ip++; 1406 | break; 1407 | case 0xD5: 1408 | if (verbose == 1) printf("\t%02X\tOUT pB, B", c->mem[c->ip]); 1409 | c->ioport[c->reg[1] & 0x0F] = c->reg[1]; 1410 | i808setportflag(c, c->reg[1], 1); 1411 | c->ip++; 1412 | break; 1413 | case 0xD6: 1414 | if (verbose == 1) printf("\t%02X\tOUT pB, C", c->mem[c->ip]); 1415 | c->ioport[c->reg[1] & 0x0F] = c->reg[2]; 1416 | i808setportflag(c, c->reg[1], 1); 1417 | c->ip++; 1418 | break; 1419 | case 0xD7: 1420 | if (verbose == 1) printf("\t%02X\tOUT pB, D", c->mem[c->ip]); 1421 | c->ioport[c->reg[1] & 0x0F] = c->reg[3]; 1422 | i808setportflag(c, c->reg[1], 1); 1423 | c->ip++; 1424 | break; 1425 | case 0xD8: 1426 | if (verbose == 1) printf("\t%02X\tOUT pC, A", c->mem[c->ip]); 1427 | c->ioport[c->reg[2] & 0x0F] = c->reg[0]; 1428 | i808setportflag(c, c->reg[2], 1); 1429 | c->ip++; 1430 | break; 1431 | case 0xD9: 1432 | if (verbose == 1) printf("\t%02X\tOUT pC, B", c->mem[c->ip]); 1433 | c->ioport[c->reg[2] & 0x0F] = c->reg[1]; 1434 | i808setportflag(c, c->reg[2], 1); 1435 | c->ip++; 1436 | break; 1437 | case 0xDA: 1438 | if (verbose == 1) printf("\t%02X\tOUT pC, C", c->mem[c->ip]); 1439 | c->ioport[c->reg[2] & 0x0F] = c->reg[2]; 1440 | i808setportflag(c, c->reg[2], 1); 1441 | c->ip++; 1442 | break; 1443 | case 0xDB: 1444 | if (verbose == 1) printf("\t%02X\tOUT pC, D", c->mem[c->ip]); 1445 | c->ioport[c->reg[2] & 0x0F] = c->reg[3]; 1446 | i808setportflag(c, c->reg[2], 1); 1447 | c->ip++; 1448 | break; 1449 | case 0xDC: 1450 | if (verbose == 1) printf("\t%02X\tOUT pD, A", c->mem[c->ip]); 1451 | c->ioport[c->reg[3] & 0x0F] = c->reg[0]; 1452 | i808setportflag(c, c->reg[3], 1); 1453 | c->ip++; 1454 | break; 1455 | case 0xDD: 1456 | if (verbose == 1) printf("\t%02X\tOUT pD, B", c->mem[c->ip]); 1457 | c->ioport[c->reg[3] & 0x0F] = c->reg[1]; 1458 | i808setportflag(c, c->reg[3], 1); 1459 | c->ip++; 1460 | break; 1461 | case 0xDE: 1462 | if (verbose == 1) printf("\t%02X\tOUT pD, C", c->mem[c->ip]); 1463 | c->ioport[c->reg[3] & 0x0F] = c->reg[2]; 1464 | i808setportflag(c, c->reg[3], 1); 1465 | c->ip++; 1466 | break; 1467 | case 0xDF: 1468 | if (verbose == 1) printf("\t%02X\tOUT pD, D", c->mem[c->ip]); 1469 | c->ioport[c->reg[3] & 0x0F] = c->reg[3]; 1470 | i808setportflag(c, c->reg[3], 1); 1471 | c->ip++; 1472 | break; 1473 | case 0xE0: // 0xE0 1474 | if (verbose == 1) printf("\t%02X\tPUSH A", c->mem[c->ip]); 1475 | for(tint=15; tint>0; tint--) 1476 | c->stack[tint] = c->stack[tint-1]; 1477 | c->stack[0] = c->reg[0]; 1478 | c->ip++; 1479 | break; 1480 | case 0xE1: 1481 | if (verbose == 1) printf("\t%02X\tPUSH B", c->mem[c->ip]); 1482 | for(tint=15; tint>0; tint--) 1483 | c->stack[tint] = c->stack[tint-1]; 1484 | c->stack[0] = c->reg[1]; 1485 | c->ip++; 1486 | break; 1487 | case 0xE2: 1488 | if (verbose == 1) printf("\t%02X\tPUSH C", c->mem[c->ip]); 1489 | for(tint=15; tint>0; tint--) 1490 | c->stack[tint] = c->stack[tint-1]; 1491 | c->stack[0] = c->reg[2]; 1492 | c->ip++; 1493 | break; 1494 | case 0xE3: 1495 | if (verbose == 1) printf("\t%02X\tPUSH D", c->mem[c->ip]); 1496 | for(tint=15; tint>0; tint--) 1497 | c->stack[tint] = c->stack[tint-1]; 1498 | c->stack[0] = c->reg[3]; 1499 | c->ip++; 1500 | break; 1501 | case 0xE4: 1502 | if (verbose == 1) printf("\t%02X\tPOP A", c->mem[c->ip]); 1503 | c->reg[0] = c->stack[0]; 1504 | for (tint=0; tint<15; tint++) 1505 | c->stack[tint] = c->stack[tint+1]; 1506 | c->stack[15] = 0; 1507 | c->ip++; 1508 | break; 1509 | case 0xE5: 1510 | if (verbose == 1) printf("\t%02X\tPOP B", c->mem[c->ip]); 1511 | c->reg[1] = c->stack[0]; 1512 | for (tint=0; tint<15; tint++) 1513 | c->stack[tint] = c->stack[tint+1]; 1514 | c->stack[15] = 0; 1515 | c->ip++; 1516 | break; 1517 | case 0xE6: 1518 | if (verbose == 1) printf("\t%02X\tPOP C", c->mem[c->ip]); 1519 | c->reg[2] = c->stack[0]; 1520 | for (tint=0; tint<15; tint++) 1521 | c->stack[tint] = c->stack[tint+1]; 1522 | c->stack[15] = 0; 1523 | c->ip++; 1524 | break; 1525 | case 0xE7: 1526 | if (verbose == 1) printf("\t%02X\tPOP D", c->mem[c->ip]); 1527 | c->reg[3] = c->stack[0]; 1528 | for (tint=0; tint<15; tint++) 1529 | c->stack[tint] = c->stack[tint+1]; 1530 | c->stack[15] = 0; 1531 | c->ip++; 1532 | break; 1533 | case 0xE8: 1534 | if (verbose == 1) printf("\t%02X\tBSL A", c->mem[c->ip]); 1535 | c->reg[0] = c->reg[0] << 1; 1536 | c->ip++; 1537 | break; 1538 | case 0xE9: 1539 | if (verbose == 1) printf("\t%02X\tBSL B", c->mem[c->ip]); 1540 | c->reg[1] = c->reg[1] << 1; 1541 | c->ip++; 1542 | break; 1543 | case 0xEA: 1544 | if (verbose == 1) printf("\t%02X\tBSL C", c->mem[c->ip]); 1545 | c->reg[2] = c->reg[2] << 1; 1546 | c->ip++; 1547 | break; 1548 | case 0xEB: 1549 | if (verbose == 1) printf("\t%02X\tBSL D", c->mem[c->ip]); 1550 | c->reg[3] = c->reg[3] << 1; 1551 | c->ip++; 1552 | break; 1553 | case 0xEC: 1554 | if (verbose == 1) printf("\t%02X\tBSR A", c->mem[c->ip]); 1555 | c->reg[0] = c->reg[0] >> 1; 1556 | c->ip++; 1557 | break; 1558 | case 0xED: 1559 | if (verbose == 1) printf("\t%02X\tBSR B", c->mem[c->ip]); 1560 | c->reg[1] = c->reg[1] >> 1; 1561 | c->ip++; 1562 | break; 1563 | case 0xEE: 1564 | if (verbose == 1) printf("\t%02X\tBSR C", c->mem[c->ip]); 1565 | c->reg[2] = c->reg[2] >> 1; 1566 | c->ip++; 1567 | break; 1568 | case 0xEF: 1569 | if (verbose == 1) printf("\t%02X\tBSR D", c->mem[c->ip]); 1570 | c->reg[3] = c->reg[3] >> 1; 1571 | c->ip++; 1572 | break; 1573 | case 0xF0: // 0xF0 1574 | if (verbose == 1) printf("\t%02X\tJSF A", c->mem[c->ip]); 1575 | c->ip += c->reg[0]; 1576 | c->ip++; 1577 | break; 1578 | case 0xF1: 1579 | if (verbose == 1) printf("\t%02X\tJSF B", c->mem[c->ip]); 1580 | c->ip += c->reg[1]; 1581 | c->ip++; 1582 | break; 1583 | case 0xF2: 1584 | if (verbose == 1) printf("\t%02X\tJSF C", c->mem[c->ip]); 1585 | c->ip += c->reg[2]; 1586 | c->ip++; 1587 | break; 1588 | case 0xF3: 1589 | if (verbose == 1) printf("\t%02X\tJSF D", c->mem[c->ip]); 1590 | c->ip += c->reg[3]; 1591 | c->ip++; 1592 | break; 1593 | case 0xF4: 1594 | if (verbose == 1) printf("\t%02X\tJSB A", c->mem[c->ip]); 1595 | c->ip -= c->reg[0]; 1596 | if (c->reg[0] == 0) // stop from getting stuck in a backwards jump of 0 1597 | c->ip++; 1598 | break; 1599 | case 0xF5: 1600 | if (verbose == 1) printf("\t%02X\tJSB B", c->mem[c->ip]); 1601 | c->ip -= c->reg[1]; 1602 | if (c->reg[1] == 0) 1603 | c->ip++; 1604 | break; 1605 | case 0xF6: 1606 | if (verbose == 1) printf("\t%02X\tJSB C", c->mem[c->ip]); 1607 | c->ip -= c->reg[2]; 1608 | if (c->reg[2] == 0) 1609 | c->ip++; 1610 | break; 1611 | case 0xF7: 1612 | if (verbose == 1) printf("\t%02X\tJSB D", c->mem[c->ip]); 1613 | c->ip -= c->reg[3]; 1614 | if (c->reg[3] == 0) 1615 | c->ip++; 1616 | break; 1617 | case 0xF8: 1618 | if (verbose == 1) printf("\t%02X\tRND A", c->mem[c->ip]); 1619 | c->reg[0] = rand() % 256; 1620 | c->ip++; 1621 | break; 1622 | case 0xF9: 1623 | if (verbose == 1) printf("\t%02X\tRND B", c->mem[c->ip]); 1624 | c->reg[1] = rand() % 256; 1625 | c->ip++; 1626 | break; 1627 | case 0xFA: 1628 | if (verbose == 1) printf("\t%02X\tRND C", c->mem[c->ip]); 1629 | c->reg[2] = rand() % 256; 1630 | c->ip++; 1631 | break; 1632 | case 0xFB: 1633 | if (verbose == 1) printf("\t%02X\tRND D", c->mem[c->ip]); 1634 | c->reg[3] = rand() % 256; 1635 | c->ip++; 1636 | break; 1637 | case 0xFC: 1638 | if (verbose == 1) printf("\t%02X\tUnimplemented opcode", c->mem[c->ip]); 1639 | c->ip++; 1640 | break; 1641 | case 0xFD: 1642 | if (verbose == 1) printf("\t%02X\tUnimplemented opcode", c->mem[c->ip]); 1643 | c->ip++; 1644 | break; 1645 | case 0xFE: 1646 | if (verbose == 1) printf("\t%02X\tUnimplemented opcode", c->mem[c->ip]); 1647 | c->ip++; 1648 | break; 1649 | case 0xFF: 1650 | if (verbose == 1) printf("\t%02X\tUnimplemented opcode", c->mem[c->ip]); 1651 | c->ip++; 1652 | break; 1653 | default: // We have a case for each situation so we should never hit this 1654 | if (verbose == 1) printf("\t%02X\tUnimplemented opcode", c->mem[c->ip]); 1655 | c->ip++; 1656 | break; 1657 | } 1658 | if (verbose == 1) 1659 | { 1660 | if ((temp >= 0x40 && temp <= 0x4F) || (temp >= 0x9C && temp <= 0x9F)) 1661 | printf("\tZ=%d, C=%d", i808checkflag(c, 0), i808checkflag(c, 1)); 1662 | } 1663 | step++; 1664 | } 1665 | } 1666 | 1667 | 1668 | /*========================================================* 1669 | * Function: i808show() 1670 | * Purpose : Show a dump of an i808 computer 1671 | * Entry : eightbitComputer *c = Pointer to a computer 1672 | * Returns : nothing 1673 | *========================================================*/ 1674 | 1675 | void i808show(eightbitComputer *c) 1676 | { 1677 | int k = 0, h = 0, i = 0; 1678 | printf("\n/----/------------------ Memory Dump ------------------\\"); 1679 | printf("\n| 0x | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |"); 1680 | printf("\n|----|-------------------------------------------------|"); 1681 | printf("\n| 00 | "); 1682 | for (k=0; k<256; k++) 1683 | { 1684 | printf("%02X ", c->mem[k]); // hexadecimal 1685 | // printf("%03d ", c->mem[k]); // decimal 1686 | h++; 1687 | if (h > 15) 1688 | { 1689 | printf("|\n"); 1690 | h = 0; 1691 | if (i < 0xEF) 1692 | printf("| %02X | ", i+=16); 1693 | } 1694 | } 1695 | printf("\\----\\-------------------------------------------------/\n"); 1696 | printf("A:%02X\tB:%02X\tC:%02X\tD:%02X\tIP:%02X\tZero:%d Carry:%d\n", c->reg[0], c->reg[1], c->reg[2], c->reg[3], c->ip, i808checkflag(c, 0), i808checkflag(c, 1)); 1697 | printf(" Stack: "); 1698 | for (k=0; k<16; k++) 1699 | printf("%02X ", c->stack[k]); 1700 | printf("\nIP Stack: "); 1701 | for (k=0; k<4; k++) 1702 | printf("%02X ", c->ipstack[k]); 1703 | printf("\n IO: "); 1704 | for (k=0; k<16; k++) 1705 | printf("%02X ", c->ioport[k]); 1706 | printf("\n IO Flag: "); 1707 | for (k=0; k<16; k++) 1708 | printf("%2d ", i808checkportflag(c, k)); 1709 | printf("\n"); 1710 | } 1711 | 1712 | 1713 | /*========================================================* 1714 | * Function: i808reset() 1715 | * Purpose : Reset an i808 computer 1716 | * Entry : eightbitComputer *c = Pointer to a computer 1717 | * Returns : nothing 1718 | *========================================================*/ 1719 | 1720 | void i808reset(eightbitComputer *c) 1721 | { 1722 | unsigned char tchar = 0; 1723 | 1724 | for (tchar=0; tchar<4; tchar++) 1725 | { 1726 | c->reg[tchar] = 0x00; 1727 | c->ipstack[tchar] = 0x00; 1728 | } 1729 | for (tchar=0; tchar<16; tchar++) 1730 | { 1731 | c->stack[tchar] = 0x00; 1732 | c->ioport[tchar] = 0x00; 1733 | } 1734 | c->ip = 0x00; 1735 | c->flags = 0x00; 1736 | c->ioportflag[0]=0x00; 1737 | c->ioportflag[1]=0x00; 1738 | } 1739 | 1740 | 1741 | /*========================================================* 1742 | * Function: i808readport() 1743 | * Purpose : Reads a value from an i808 computer port 1744 | * Entry : eightbitComputer *c = Pointer to a computer 1745 | * unsigned char port = Port to read from (0-15) 1746 | * Returns : unsigned char from port 1747 | *========================================================*/ 1748 | 1749 | unsigned char i808readport(eightbitComputer *c, unsigned char port) 1750 | { 1751 | unsigned char tchar = port & 0x0F; // remove high nibble, only 0 - 15 are valid 1752 | 1753 | if (i808checkportflag(c, tchar) == 1) 1754 | { 1755 | i808setportflag(c, tchar, 0); 1756 | return c->ioport[tchar]; 1757 | } 1758 | else 1759 | { 1760 | return 0; 1761 | } 1762 | } 1763 | 1764 | 1765 | /*========================================================* 1766 | * Function: i808writeport() 1767 | * Purpose : Writes a value to an i808 computer port 1768 | * Entry : eightbitComputer *c = Pointer to a computer 1769 | * unsigned char port = Port to write to (0-15) 1770 | * unsigned char val = Value to write 1771 | * Returns : nothing 1772 | *========================================================*/ 1773 | 1774 | void i808writeport(eightbitComputer *c, unsigned char port, unsigned char val) 1775 | { 1776 | unsigned char tchar = port & 0x0F; // remove high nibble, only 0 - 15 are valid 1777 | 1778 | c->ioport[tchar] = val; 1779 | i808setportflag(c, tchar, 1); 1780 | } 1781 | 1782 | 1783 | /*========================================================* 1784 | * Function: i808setportflag() 1785 | * Purpose : Sets a port flag 1786 | * Entry : eightbitComputer *c = Pointer to a computer 1787 | * port = Port to set 1788 | * val = Value to set (0 or 1) 1789 | * Returns : Nothing 1790 | *========================================================*/ 1791 | 1792 | void i808setportflag(eightbitComputer *c, unsigned char port, unsigned char val) 1793 | { 1794 | unsigned char tchar = port & 0x0F; // remove high nibble, only 0 - 15 are valid 1795 | 1796 | if (tchar < 8) // low byte 1797 | { 1798 | if (val == 0) 1799 | { 1800 | c->ioportflag[1] = c->ioportflag[1] & bit8fieldh[tchar]; // set flag to 0 1801 | } 1802 | else 1803 | { 1804 | c->ioportflag[1] = c->ioportflag[1] | bit8fieldl[tchar]; // set flag to 1 1805 | } 1806 | } 1807 | else // high byte 1808 | { 1809 | tchar = tchar - 8; 1810 | if (val == 0) 1811 | { 1812 | c->ioportflag[0] = c->ioportflag[0] & bit8fieldh[tchar]; // set flag to 0 1813 | } 1814 | else 1815 | { 1816 | c->ioportflag[0] = c->ioportflag[0] | bit8fieldl[tchar]; // set flag to 1 1817 | } 1818 | } 1819 | } 1820 | 1821 | 1822 | /*========================================================* 1823 | * Function: i808checkportflag() 1824 | * Purpose : Checks a port flag 1825 | * Entry : eightbitComputer *c = Pointer to a computer 1826 | * port = Port to check 1827 | * Returns : Flag on port (1 or 0) 1828 | *========================================================*/ 1829 | 1830 | unsigned char i808checkportflag(eightbitComputer *c, unsigned char port) 1831 | { 1832 | unsigned char tchar = port & 0x0F; // remove high nibble, only 0 - 15 are valid 1833 | 1834 | if (tchar < 8) // low byte 1835 | { 1836 | if ((c->ioportflag[1] & bit8fieldl[tchar]) > 0) // it is 1 1837 | return 1; 1838 | else 1839 | return 0; 1840 | } 1841 | else // high byte 1842 | { 1843 | tchar = tchar - 8; 1844 | if ((c->ioportflag[0] & bit8fieldl[tchar]) > 0) // it is 1 1845 | return 1; 1846 | else 1847 | return 0; 1848 | } 1849 | } 1850 | 1851 | 1852 | /*========================================================* 1853 | * Function: i808setflag() 1854 | * Purpose : Sets a flag 1855 | * Entry : eightbitComputer *c = Pointer to a computer 1856 | * flag = Flag to set 1857 | * val = Value to set (0 or 1) 1858 | * Returns : Nothing 1859 | *========================================================*/ 1860 | 1861 | void i808setflag(eightbitComputer *c, unsigned char flag, unsigned char val) 1862 | { 1863 | if (val == 0) 1864 | { 1865 | c->flags = c->flags & bit8fieldh[flag]; // set flag to 0 1866 | } 1867 | else if (val == 1) 1868 | { 1869 | c->flags = c->flags | bit8fieldl[flag]; // set flag to 1 1870 | } 1871 | else 1872 | { 1873 | printf("i808 Library: Flag set error! No change was made.\n"); 1874 | } 1875 | } 1876 | 1877 | 1878 | /*========================================================* 1879 | * Function: i808checkflag() 1880 | * Purpose : Checks a flag 1881 | * Entry : eightbitComputer *c = Pointer to a computer 1882 | * flag = Flag to check 1883 | * Returns : Flag on port (1 or 0) 1884 | *========================================================*/ 1885 | 1886 | unsigned char i808checkflag(eightbitComputer *c, unsigned char flag) 1887 | { 1888 | if ((c->flags & bit8fieldl[flag]) > 0) // it is 1 1889 | return 1; 1890 | else 1891 | return 0; 1892 | } 1893 | 1894 | 1895 | /*========================================================* 1896 | * Function: i808savestate() 1897 | * Purpose : Save the state of an i808 to file 1898 | * Entry : eightbitComputer *c = Pointer to a computer 1899 | * char *statefilename = Name of state file 1900 | * Returns : Success or Failure 1901 | *========================================================*/ 1902 | 1903 | unsigned char i808savestate(eightbitComputer *c, char *statefilename) 1904 | { 1905 | FILE *statefile; 1906 | 1907 | if ((statefile = fopen(statefilename, "wb")) == NULL) 1908 | { 1909 | printf("\ni808 Error:\nError saving state file %s\n", statefilename); 1910 | return 1; 1911 | } 1912 | fwrite(c, sizeof(eightbitComputer), 1, statefile); 1913 | fclose(statefile); 1914 | 1915 | return 0; 1916 | } 1917 | 1918 | 1919 | /*========================================================* 1920 | * Function: i808loadstate() 1921 | * Purpose : Load the state of an i808 from file 1922 | * Entry : eightbitComputer *c = Pointer to a computer 1923 | * char *statefilename = Name of state file 1924 | * Returns : Success or Failure 1925 | *========================================================*/ 1926 | 1927 | unsigned char i808loadstate(eightbitComputer *c, char *statefilename) 1928 | { 1929 | FILE *statefile; 1930 | 1931 | if ((statefile = fopen(statefilename, "rb")) == NULL) 1932 | { 1933 | printf("\ni808 Error:\nError loading state file %s\n", statefilename); 1934 | return 1; 1935 | } 1936 | fread(c, sizeof(eightbitComputer), 1, statefile); 1937 | fclose(statefile); 1938 | 1939 | return 0; 1940 | } 1941 | 1942 | 1943 | /*========================================================* 1944 | * Function: i808saveprogram() 1945 | * Purpose : Save the program of an i808 to file 1946 | * Entry : eightbitComputer *c = Pointer to a computer 1947 | * char *programfilename = Name of program file 1948 | * Returns : Success or Failure 1949 | *========================================================*/ 1950 | 1951 | unsigned char i808saveprogram(eightbitComputer *c, char *programfilename) 1952 | { 1953 | FILE *programfile; 1954 | 1955 | if ((programfile = fopen(programfilename, "wb")) == NULL) 1956 | { 1957 | printf("\ni808 Error:\nError saving program file %s\n", programfilename); 1958 | return 1; 1959 | } 1960 | fwrite(c->mem, sizeof(c->mem), 1, programfile); 1961 | fclose(programfile); 1962 | 1963 | return 0; 1964 | } 1965 | 1966 | 1967 | /*========================================================* 1968 | * Function: i808loadprogram() 1969 | * Purpose : Load a program to an i808 from file 1970 | * Entry : eightbitComputer *c = Pointer to a computer 1971 | * char *programfilename = Name of program file 1972 | * Returns : Success or Failure 1973 | *========================================================*/ 1974 | 1975 | unsigned char i808loadprogram(eightbitComputer *c, char *programfilename) 1976 | { 1977 | FILE *programfile; 1978 | 1979 | if ((programfile = fopen(programfilename, "rb")) == NULL) 1980 | { 1981 | printf("\ni808 Error:\nError loading program file %s\n", programfilename); 1982 | return 1; 1983 | } 1984 | fread(c->mem, sizeof(c->mem), 1, programfile); 1985 | fclose(programfile); 1986 | 1987 | return 0; 1988 | } 1989 | -------------------------------------------------------------------------------- /dev/i808.h: -------------------------------------------------------------------------------- 1 | /* 2 | i808.h - Header file for i808 Virtual Computer 3 | v1.0b - 2007.11.15 4 | Coded by Ian Seyler (iseyler@gmail.com) 5 | */ 6 | 7 | /* Structure of an i808 Computer */ 8 | struct i808Struct { 9 | unsigned char mem[256]; 10 | unsigned char reg[4]; // A, B, C, D 11 | unsigned char ip; 12 | unsigned char flags; // bits: unused, unused, unused, unused, unused, unused, carry, zero 13 | unsigned char stack[16]; 14 | unsigned char ipstack[4]; 15 | unsigned char ioport[16]; 16 | unsigned char ioportflag[2]; // 0 high, 1 low 17 | unsigned char unused[20]; // filler space, total size of i808Struct is 320 bytes 18 | }; 19 | 20 | /* Typedef for the structure */ 21 | typedef struct i808Struct eightbitComputer; 22 | 23 | /* Function prototypes */ 24 | void i808compute(eightbitComputer *c, unsigned int cycles, unsigned int verbose); 25 | void i808show(eightbitComputer *c); 26 | void i808reset(eightbitComputer *c); 27 | unsigned char i808readport(eightbitComputer *c, unsigned char port); 28 | void i808writeport(eightbitComputer *c, unsigned char port, unsigned char val); 29 | void i808setportflag(eightbitComputer *c, unsigned char port, unsigned char val); 30 | unsigned char i808checkportflag(eightbitComputer *c, unsigned char port); 31 | void i808setflag(eightbitComputer *c, unsigned char flag, unsigned char val); 32 | unsigned char i808checkflag(eightbitComputer *c, unsigned char flag); 33 | unsigned char i808savestate(eightbitComputer *c, char *statefilename); 34 | unsigned char i808loadstate(eightbitComputer *c, char *statefilename); 35 | unsigned char i808saveprogram(eightbitComputer *c, char *programfilename); 36 | unsigned char i808loadprogram(eightbitComputer *c, char *programfilename); 37 | -------------------------------------------------------------------------------- /dev/simplevm.c: -------------------------------------------------------------------------------- 1 | /* 2 | simplevm.c - Module file for a simple i808 virtual machine tester 3 | v1.0b - 2007.03.30 4 | Coded by Ian Seyler (iseyler@gmail.com) 5 | */ 6 | 7 | /* Obligatory includes */ 8 | #include 9 | #include 10 | #include "i808.h" 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | eightbitComputer computer; 15 | FILE *startfile; 16 | char *inputfilename; 17 | char *program_name = argv[0]; 18 | unsigned int cyclestorun = 20, verbose = 1; 19 | 20 | if (argc < 2) 21 | { 22 | printf("A Simple i808 VM Tester v0.97b (2007 01 02)\n"); 23 | printf("Coded by Ian Seyler (iseyler@gmail.com)\n\n"); 24 | printf("Usage is %s [program file]\n", program_name); 25 | printf("Example:\n"); 26 | printf(" %s program.bin Runs program.bin\n", program_name); 27 | exit (1); 28 | } 29 | 30 | inputfilename = argv[1]; 31 | if ((startfile = fopen(inputfilename, "rb")) == NULL) 32 | { 33 | printf("\nVM Error:\nError opening file %s\n", inputfilename); 34 | exit (1); 35 | } 36 | fread(computer.mem, 256, 1, startfile); 37 | fclose(startfile); 38 | 39 | i808reset(&computer); 40 | 41 | printf("Computer Start Status:\n"); 42 | i808show(&computer); 43 | 44 | i808compute(&computer, cyclestorun, verbose); 45 | 46 | printf("Computer Finish Status:\n"); 47 | i808show(&computer); 48 | 49 | printf("\n"); //Just to be clean 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /dev/vm.c: -------------------------------------------------------------------------------- 1 | /* 2 | vm.c - Module file for i808 virtual machine tester 3 | v1.0b - 2007.11.15 4 | Coded by Ian Seyler (iseyler@gmail.com) 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "i808.h" 12 | 13 | /* Version information strings */ 14 | char VERSIONINFO1[] = "i808 VM Tester v1.0b"; 15 | char VERSIONINFO2[] = "Compiled on 2007.11.15, based on i808 spec 2006.08.30"; 16 | 17 | /* Function prototypes. */ 18 | int randint(int min, int max); 19 | void printhelp(); 20 | 21 | /* Global variables */ 22 | eightbitComputer computer; 23 | FILE *startfile; 24 | char *inputfile; 25 | char *program_name; 26 | char statefile_name[40]; 27 | 28 | int main(int argc, char *argv[]) 29 | { 30 | unsigned char tchar; 31 | unsigned int cyclestorun = 20, verbose = 0, randomness = 0, timed = 0; 32 | unsigned int loadstate = 0, savestate = 0, tint; 33 | time_t tval1, tval2; // used for keeping track of running time 34 | 35 | program_name = argv[0]; 36 | 37 | srand(time(NULL)); // randomize 38 | for (tint=0; tint<5; tint++) 39 | tint = randint(0, 255); // clear out the first few random numbers 40 | 41 | if (argc < 2 || argv[1][0] == '/' || argv[1][0] == '-') // make sure there is at least one argument (filename) 42 | { 43 | printhelp(); 44 | exit (1); 45 | } 46 | 47 | // Parse the arguments 48 | for(tint=1; tint Port %d : ", 15); 150 | printf("%c", tchar); 151 | // printf("%02X", tchar); 152 | } 153 | } 154 | time(&tval2); // Running time 155 | 156 | i808show(&computer); 157 | 158 | if (timed == 1) 159 | printf("\nElapsed program time in seconds: %.0lf", difftime(tval2,tval1)); 160 | 161 | if (savestate == 1) 162 | i808savestate(&computer, statefile_name); 163 | 164 | printf("\n"); // Just to be clean 165 | 166 | return (0); 167 | } 168 | 169 | 170 | /*========================================================* 171 | * Function: randint() 172 | * Purpose : generate a random number between min and max 173 | * Entry : int min = Minimum number 174 | * : int max = Maximum number 175 | * Returns : random number between min and max inclusive 176 | *========================================================*/ 177 | 178 | int randint(int min, int max) 179 | { 180 | return (min + (rand() % ((max+1) - min))); 181 | } 182 | 183 | 184 | /*========================================================* 185 | * Function: printhelp() 186 | * Purpose : Print the help text 187 | * Entry : None 188 | * Returns : None 189 | *========================================================*/ 190 | 191 | void printhelp() 192 | { 193 | printf("%s\n", VERSIONINFO1); 194 | printf("%s\n", VERSIONINFO2); 195 | printf("Coded by Ian Seyler (iseyler@gmail.com)\n\n"); 196 | printf("Usage: %s [program file] [options]\n", program_name); 197 | printf("Options:\n"); 198 | printf(" -c Cycles (20 if not specified)\n"); 199 | printf(" -v Verbose mode\n"); 200 | printf(" -l Load state from program.bin.state at start\n"); 201 | printf(" -s Save state to program.bin.state at end\n"); 202 | // printf(" -r Randomize contents of memory\n"); 203 | // printf(" -t Time how long processing takes to complete\n"); 204 | printf("Examples:\n"); 205 | printf(" %s program.bin -c 200 Runs program.bin for 200 cycles\n", program_name); 206 | printf(" %s example.bin -s -v Runs example.bin saving state, verbose\n", program_name); 207 | } 208 | -------------------------------------------------------------------------------- /examples/helloworld.asm: -------------------------------------------------------------------------------- 1 | // Print Hello World // 2 | // Run for 120 cycles for best result // 3 | 4 | dest=i808 5 | 6 | :Start 7 | mov A, 0x30 // memory address of start of message // 8 | mov D, 0x0F // port to write message to // 9 | :Next 10 | mov B, [A] // get a byte of the message // 11 | cmp B, 0x00 // check it against a null byte // 12 | je End // if equal then you are at the end of the message, bail out // 13 | out D, B // output the message byte to the port // 14 | inc A 15 | jmp Next // do the next one // 16 | :End 17 | jmp End 18 | @0x30 19 | :Message DATA "Hello World!" ENDDATA 20 | -------------------------------------------------------------------------------- /manual.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 68 | 69 |
70 |

71 | i808 Manual 72 |

73 |
74 |

75 |

76 | This is the manual for the i808 Virtual CPU.
77 |
78 |

79 | Specifications 80 |

81 | 8-bit architecture
82 | 4 8-bit general purpose registers (A, B, C, D)
83 | 1 8-bit instruction pointer (IP)
84 | 2 1-bit flags (Zero, Carry)
85 | 256 bytes of addressable memory
86 | 16 data ports for external communication
87 | 16 bytes of stack memory
88 | 4 bytes of instruction pointer stack memory
89 |
90 |
91 |

92 | Architecture 93 |

94 | The architecture of the i808 CPU is strictly 8-bit. This means the highest value 95 | the CPU can use is 255 (0 is the lowest). Issues will arise when two large 96 | values are added together for instance.
97 |
98 | 2 + 2 = 4 <- OK
99 | 200 + 50 = 250 <- OK
100 | 255 + 1 = 0 <- Overflow
101 | 255 + 10 = 9 <- Overflow
102 |
103 |
104 |

105 | Stack 106 |

107 | The stack of the i808 CPU uses a Last in, first out structure (also known as 108 | "First In, Last out").
109 | Please see the Wikipedia article for more info: 110 | http://en.wikipedia.org/wiki/LIFO
111 |
112 |
113 |

114 | Opcodes 115 |

116 |
117 | All opcodes that allow for dual arguments have the same sequence.
118 |     OPCODE 119 | DESTINATION, 120 | SOURCE
121 | Otherwise single argument instruction use this mnemonic.
122 |     OPCODE 123 | DESTINATION
124 | Some opcodes require no arguments.
125 |     OPCODE
126 |
127 |

128 | Data Transfers 129 |

130 |
131 | These opcodes allow you to transfer bytes of data between the registers, memory 132 | and stack.
133 |
134 |

135 | MOV (MOVe data) 136 |

137 |
138 | The MOV command will copy a byte from the source to the destination. You can 139 | move data between the registers, an immediate value into a register, between the 140 | registers and memory, and between memory pointers and registers.
141 |
142 | The MOV instruction copies the contents of the source operand into the 143 | destination operand.
144 |
145 |     mov reg, reg    eg: mov A, B    146 | A = B
147 |     mov reg, val    eg: mov B, 148 | 45    B = 45
149 |     mov mem, reg    eg: mov 23, C
150 |     mov reg, mem    eg: mov D, 62
151 |     mov &reg, reg    eg: mov &A, B
152 |     mov reg, &reg    eg: mov C, &D
153 |
154 |

155 | PUSH 156 |

157 |
158 | The PUSH command will push the value in a register onto the stack.
159 |
160 |     push reg    eg: push A
161 |
162 |

163 | POP 164 |

165 |
166 | The POP command will pop the next value in the stack into the register.
167 |
168 |     pop reg        eg: pop B
169 |
170 |

171 | PUSHA (PUSH All) 172 |

173 |
174 | The PUSHA command will push all register onto the stack.
175 |
176 |     pusha
177 |
178 |

179 | POPA (POP All) 180 |

181 |
182 | The POPA command will pop the next values on the stack into the registers.
183 |
184 |     popa
185 |
186 |
187 |
188 |

189 | Arithmetic 190 |

191 |
192 | These opcodes do various arithmetic using registers. Beware of overflows!
193 |
194 |

195 | ADD (ADDition) 196 |

197 |
198 | The ADD opcode will add the destination and source together and place the result 199 | into the destination.
200 |
201 |     add reg, reg    eg: add A, B    202 | A = A + B
203 |     add reg, val    eg: add C, 204 | 12    C = C + 12
205 |
206 |

207 | SUB (SUBtraction) 208 |

209 |
210 | The SUB opcode will subtract the source from the destination and place the 211 | result into the destination.
212 |
213 |     sub reg, reg    eg: sub A, B    214 | A = A - B
215 |     sub reg, val    eg: sub C, 216 | 12    C = C - 12
217 |
218 |

219 | INC (INCrement) 220 |

221 |
222 | The INC opcode will increase the register by 1.
223 |
224 |     inc reg        eg: inc 225 | A    A = A + 1
226 |
227 |

228 | DEC (DECrement) 229 |

230 |
231 | The DEC opcode will decrease the register by 1.
232 |
233 |     dec reg        eg: dec 234 | B    B = B - 1
235 |
236 |

237 | CMP (CoMPare) 238 |

239 |
240 | The CMP command will compare argument 1 with argument 2. Based on output it will 241 | set the Zero and Carry flags. The logic is as follows:
242 |
243 |     if op1 = op2 then Zero = 1 else Zero = 0
244 |     if op1 < op2 then Carry = 0
245 |     if op1 > op2 then Carry = 1
246 |
247 | The CMP command will be used for deciding jumps in the programs. You can compare 248 | a register with another register or a register with an immediate value.
249 |
250 |     cmp reg, reg    eg: cmp A, B
251 |     cmp reg, val    eg: cmp C, 27
252 |
253 |
254 |
255 |

256 | Bitwise 257 |

258 |
259 | These opcodes work with registers at the bit level. For more information on this 260 | please see the Wikipedia entry: 261 | Logic 262 | Gates
263 |
264 |

265 | AND 266 |

267 |     and reg, reg    eg: and A, B
268 |
269 |

270 | OR 271 |

272 |     or reg, reg    eg: or C, D
273 |
274 |

275 | XOR 276 |

277 |     xor reg, reg    eg: xor A, B
278 |
279 |

280 | NOT 281 |

282 |     not reg        eg: not A
283 |
284 |

285 | BSL (Bit Shift Left) 286 |

287 |     bsl reg        eg: bsl B
288 |
289 |

290 | BSR (Bit Shift Right) 291 |

292 |     bsr reg        eg: bsr C
293 |
294 |
295 |
296 |

297 | Program Flow 298 |

299 |
300 | These commands allow you to interrupt the program flow based on previous opcodes 301 | (like CMP). They will evaluate the status of the Zero and Carry flags.
302 |
303 |

304 | JMP (JuMP) 305 |

306 |     jmp mem
307 |
308 |

309 | JL (Jump if Less) 310 |

311 |     jl mem   eg: if carry = 0 then jump to memory 312 | address
313 |
314 |

315 | JLE (Jump if Less or Equal) 316 |

317 |     jle mem   eg: if carry = 0 or zero = 1 then jump to 318 | memory address
319 |
320 |

321 | JE (Jump if Equal) 322 |

323 |     je mem   eg: if zero = 1 then jump to memory 324 | address
325 |
326 |

327 | JGE (Jump if Greater or Equal) 328 |

329 |     jge mem   eg: if carry = 1 or zero = 1 then jump to 330 | memory address
331 |
332 |

333 | JG (Jump if Greater) 334 |

335 |     jg mem   eg: if carry = 1 then jump to memory 336 | address
337 |
338 |

339 | JNE (Jump if Not Equal) 340 |

341 |     jne mem   eg: if zero = 0 then jump to memory 342 | address
343 |
344 |

345 | JSF (Jump Short Forward) 346 |

347 |     jsf reg
348 |
349 |

350 | JSB (Jump Short Backward) 351 |

352 |     jsb reg
353 |
354 |

355 | CALL (CALL function) 356 |

357 |     call mem
358 |
359 | The CALL instruction sets the CPU to jump to a specific address where a function 360 | is located. Make sure you have a RET opcode at the end of your function so your 361 | program returns to normal operation.
362 |
363 |     call 212
364 |
365 |

366 | RET (RETurn) 367 |

368 |
369 | The RET instruction returns program flow back to where the last CALL instruction 370 | was called.
371 |
372 |     ret
373 |
374 |
375 |
376 |

377 | I/O 378 |

379 |
380 | These opcodes allow you to move data into and out of the CPU. The IN and OUT 381 | opcode modify the ZERO flag based on whether the operation was a success. Each 382 | port has a flag. When the flag is set then there is data waiting to be used. If 383 | the flag for a port is not set then there is nothing waiting. Like a mailbox.
384 |
385 |

386 | IN (INput) 387 |

388 |
389 | The IN instruction copies a byte from the source operand into the destination 390 | operand. This will also set the carry flag based on if the port flag was high. 391 | You can check if there was something that was actually read by doing a "jl 392 | NoRead".
393 |
394 |     in reg, preg    eg: in A, B
395 |
396 |

397 | OUT (OUTput) 398 |

399 |
400 | The OUT instruction copies a byte from the source operand into the destination 401 | operand. This will also set the flag on the port to high.
402 |
403 |     out preg, reg    eg: out C, D
404 |
405 |
406 |
407 |

408 | Miscellaneous 409 |

410 |
411 |

412 | NOP (No Operation) 413 |

414 |
415 | The NOP instruction does nothing. It will only increment the Instruction Pointer 416 | by 1.
417 |
418 |     nop
419 |
420 |
421 |
422 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | Getting Started: 2 | 3 | Compiling your first program: 4 | compiler helloworld.asm 5 | 6 | Running your first program: 7 | vm helloworld.bin -c 120 --------------------------------------------------------------------------------