· 9 years ago · Nov 23, 2016, 06:32 PM
1
2#include "stdafx.h"
3#include <winsock2.h>
4
5
6#pragma comment(lib, "wsock32.lib")
7
8
9#define STUDENT_NUMBER "00000000"
10
11#define IP_ADDRESS_SERVER "127.0.0.1"
12
13#define PORT_SERVER 0x1984 // We define a port that we are going to use.
14#define PORT_CLIENT 0x1985 // We define a port that we are going to use.
15
16#define WORD unsigned short
17#define DWORD unsigned long
18#define BYTE unsigned char
19
20
21#define MAX_FILENAME_SIZE 500
22#define MAX_BUFFER_SIZE 500
23
24SOCKADDR_IN server_addr;
25SOCKADDR_IN client_addr;
26
27SOCKET sock; // This is our socket, it is the handle to the IO address to read/write packets
28
29WSADATA data;
30
31char InputBuffer[MAX_BUFFER_SIZE];
32
33char hex_file[MAX_BUFFER_SIZE];
34char trc_file[MAX_BUFFER_SIZE];
35
36//////////////////////////
37// Registers //
38//////////////////////////
39
40#define FLAG_I 0x10
41#define FLAG_Z 0x04
42#define FLAG_N 0x02
43#define FLAG_C 0x01
44#define REGISTER_M 4
45#define REGISTER_A 3
46#define REGISTER_B 2
47#define REGISTER_H 1
48#define REGISTER_L 0
49#define REGISTER_X 0
50#define REGISTER_Y 1
51BYTE Index_Registers[2];
52
53BYTE Registers[5];
54BYTE Flags;
55WORD ProgramCounter;
56WORD StackPointer;
57
58
59
60////////////
61// Memory //
62////////////
63
64#define MEMORY_SIZE 65536
65
66BYTE Memory[MEMORY_SIZE];
67
68#define TEST_ADDRESS_1 0x01FA
69#define TEST_ADDRESS_2 0x01FB
70#define TEST_ADDRESS_3 0x01FC
71#define TEST_ADDRESS_4 0x01FD
72#define TEST_ADDRESS_5 0x01FE
73#define TEST_ADDRESS_6 0x01FF
74#define TEST_ADDRESS_7 0x0200
75#define TEST_ADDRESS_8 0x0201
76#define TEST_ADDRESS_9 0x0202
77#define TEST_ADDRESS_10 0x0203
78#define TEST_ADDRESS_11 0x0204
79#define TEST_ADDRESS_12 0x0205
80
81
82///////////////////////
83// Control variables //
84///////////////////////
85
86bool memory_in_range = true;
87bool halt = false;
88
89
90///////////////////////
91// Disassembly table //
92///////////////////////
93
94char opcode_mneumonics[][14] =
95{
96 "ILLEGAL ",
97 "DECX impl ",
98 "INCX impl ",
99 "DEY impl ",
100 "INCY impl ",
101 "CLC impl ",
102 "STC impl ",
103 "CLI impl ",
104 "STI impl ",
105 "ILLEGAL ",
106 "LDAA # ",
107 "LDAB # ",
108 "LX #,L ",
109 "LX #,L ",
110 "LDX # ",
111 "LDY # ",
112
113 "JMP abs ",
114 "JCC abs ",
115 "JCS abs ",
116 "JNE abs ",
117 "JEQ abs ",
118 "JMI abs ",
119 "JPL abs ",
120 "JHI abs ",
121 "JLE abs ",
122 "ILLEGAL ",
123 "LDAA abs ",
124 "LDAB abs ",
125 "MVI #,L ",
126 "MVI #,H ",
127 "LDX abs ",
128 "LDY abs ",
129
130 "LODS # ",
131 "JSR abs ",
132 "CCC abs ",
133 "CCS abs ",
134 "CNE abs ",
135 "CEQ abs ",
136 "CMI abs ",
137 "CPL abs ",
138 "CHI abs ",
139 "CLE abs ",
140 "LDAA abs,X ",
141 "LDAB abs,X ",
142 "NOP impl ",
143 "HLT impl ",
144 "LDX abs,X ",
145 "LDY abs,X ",
146
147 "LODS abs ",
148 "ADC A,L ",
149 "SBC A,L ",
150 "ADD A,L ",
151 "SUB A,L ",
152 "CMP A,L ",
153 "OR A,L ",
154 "AND A,L ",
155 "XOR A,L ",
156 "BIT A,L ",
157 "LDAA abs,Y ",
158 "LDAB abs,Y ",
159 "ILLEGAL ",
160 "ILLEGAL ",
161 "LDX abs,Y ",
162 "LDY abs,Y ",
163
164 "LODS abs,X ",
165 "ADC A,H ",
166 "SBC A,H ",
167 "ADD A,H ",
168 "SUB A,H ",
169 "CMP A,H ",
170 "OR A,H ",
171 "AND A,H ",
172 "XOR A,H ",
173 "BIT A,H ",
174 "LDAA (ind) ",
175 "LDAB (ind) ",
176 "RET impl ",
177 "ILLEGAL ",
178 "LDX (ind) ",
179 "LDY (ind) ",
180
181 "LODS abs,Y ",
182 "ADC A,M ",
183 "SBC A,M ",
184 "ADD A,M ",
185 "SUB A,M ",
186 "CMP A,M ",
187 "OR A,M ",
188 "AND A,M ",
189 "XOR A,M ",
190 "BIT A,M ",
191 "LDAA (ind,X) ",
192 "LDAB (ind,X) ",
193 "SWI impl ",
194 "RTI impl ",
195 "LDX (ind,X) ",
196 "LDY (ind,X) ",
197
198 "LODS (ind) ",
199 "ADC B,L ",
200 "SBC B,L ",
201 "ADD B,L ",
202 "SUB B,L ",
203 "CMP B,L ",
204 "OR B,L ",
205 "AND B,L ",
206 "XOR B,L ",
207 "BIT B,L ",
208 "STOS abs ",
209 "MOVE A,A ",
210 "MOVE B,A ",
211 "MOVE L,A ",
212 "MOVE H,A ",
213 "MOVE M,A ",
214
215 "LODS (ind,X) ",
216 "ADC B,H ",
217 "SBC B,H ",
218 "ADD B,H ",
219 "SUB B,H ",
220 "CMP B,H ",
221 "OR B,H ",
222 "AND B,H ",
223 "XOR B,H ",
224 "BIT B,H ",
225 "STOS abs,X ",
226 "MOVE A,B ",
227 "MOVE B,B ",
228 "MOVE L,B ",
229 "MOVE H,B ",
230 "MOVE M,B ",
231
232 "ILLEGAL ",
233 "ADC B,M ",
234 "SBC B,M ",
235 "ADD B,M ",
236 "SUB B,M ",
237 "CMP B,M ",
238 "OR B,M ",
239 "AND B,M ",
240 "XOR B,M ",
241 "BIT B,M ",
242 "STOS abs,Y ",
243 "MOVE A,L ",
244 "MOVE B,L ",
245 "MOVE L,L ",
246 "MOVE H,L ",
247 "MOVE M,L ",
248
249 "ILLEGAL ",
250 "ILLEGAL ",
251 "ILLEGAL ",
252 "SBIA # ",
253 "SBIB # ",
254 "CPIA # ",
255 "CPIB # ",
256 "ORIA # ",
257 "ORIB # ",
258 "ILLEGAL ",
259 "STOS (ind) ",
260 "MOVE A,H ",
261 "MOVE B,H ",
262 "MOVE L,H ",
263 "MOVE H,H ",
264 "MOVE M,H ",
265
266 "INC abs ",
267 "DEC abs ",
268 "RRC abs ",
269 "RLC abs ",
270 "SAL abs ",
271 "SAR abs ",
272 "LSR abs ",
273 "COM abs ",
274 "ROL abs ",
275 "RR abs ",
276 "STOS (ind,X) ",
277 "MOVE A,M ",
278 "MOVE B,M ",
279 "MOVE L,M ",
280 "MOVE H,M ",
281 "MOVE -,- ",
282
283 "INC abs,X ",
284 "DEC abs,X ",
285 "RRC abs,X ",
286 "RLC abs,X ",
287 "SAL abs,X ",
288 "SAR abs,X ",
289 "LSR abs,X ",
290 "COM abs,X ",
291 "ROL abs,X ",
292 "RR abs,X ",
293 "STORA abs ",
294 "STORB abs ",
295 "STOX abs ",
296 "STOY abs ",
297 "PUSH ,A ",
298 "POP A, ",
299
300 "INC abs,Y ",
301 "DEC abs,Y ",
302 "RRC abs,Y ",
303 "RLC abs,Y ",
304 "SAL abs,Y ",
305 "SAR abs,Y ",
306 "LSR abs,Y ",
307 "COM abs,Y ",
308 "ROL abs,Y ",
309 "RR abs,Y ",
310 "STORA abs,X ",
311 "STORB abs,X ",
312 "STOX abs,X ",
313 "STOY abs,X ",
314 "PUSH ,B ",
315 "POP B, ",
316
317 "INCA A,A ",
318 "DECA A,A ",
319 "RRCA A,A ",
320 "RLCA A,A ",
321 "SALA A,A ",
322 "SARA A,A ",
323 "LSRA A,A ",
324 "COMA A,A ",
325 "ROLA A,A ",
326 "RRA A,A ",
327 "STORA abs,Y ",
328 "STORB abs,Y ",
329 "STOX abs,Y ",
330 "STOY abs,Y ",
331 "PUSH ,s ",
332 "POP s, ",
333
334 "INCB B,B ",
335 "DECB B,B ",
336 "RRCB B,B ",
337 "RLCB B,B ",
338 "SALB B,B ",
339 "SARB B,B ",
340 "LSRB B,B ",
341 "COMB B,B ",
342 "ROLB B,B ",
343 "RRB B,B ",
344 "STORA (ind) ",
345 "STORB (ind) ",
346 "STOX (ind) ",
347 "STOY (ind) ",
348 "PUSH ,L ",
349 "POP L, ",
350
351 "CAY impl ",
352 "MYA impl ",
353 "CSA impl ",
354 "ABA impl ",
355 "SBA impl ",
356 "AAB impl ",
357 "SAB impl ",
358 "ADCP A,L ",
359 "SBCP A,L ",
360 "XCHG A,L ",
361 "STORA (ind,X)",
362 "STORB (ind,X)",
363 "STOX (ind,X) ",
364 "STOY (ind,X) ",
365 "PUSH ,H ",
366 "POP H, ",
367
368};
369
370////////////////////////////////////////////////////////////////////////////////
371// Simulator/Emulator (Start) //
372////////////////////////////////////////////////////////////////////////////////
373
374
375BYTE fetch()
376{
377 BYTE byte = 0;
378
379 if ((ProgramCounter >= 0) && (ProgramCounter <= MEMORY_SIZE))
380 {
381 memory_in_range = true;
382 byte = Memory[ProgramCounter];
383 ProgramCounter++;
384 }
385 else
386 {
387 memory_in_range = false;
388 }
389 return byte;
390}
391
392
393void set_flag_z(BYTE inReg) { //ZERO FLAG
394 BYTE reg;
395 reg = inReg;
396
397 if ((reg & 0x80) != 0) // msbit set
398 {
399 Flags = Flags | FLAG_N;
400 }
401 else
402 {
403 Flags = Flags & (0xFF - FLAG_N);
404 }
405}
406
407
408void set_flag_n(BYTE inReg) {
409 BYTE reg;
410 reg = inReg;
411
412 if ((reg & 0x80) != 0) // msbit set
413 {
414 Flags = Flags | FLAG_N;
415 }
416 else
417 {
418 Flags = Flags & (0xFF - FLAG_N);
419 }
420}
421
422
423void set_flag_c(WORD inResult) {
424 WORD temp_word;
425 temp_word = inResult;
426
427 if (temp_word >= 0x100) // msbit set
428 {
429 Flags = Flags | FLAG_C;
430 }
431 else
432 {
433 Flags = Flags & (0xFF - FLAG_C);
434 }
435}
436
437
438void Group_1(BYTE opcode) {
439
440
441 BYTE LB = 0;
442 BYTE HB = 0;
443 WORD address = 0;
444 WORD data = 0;
445 WORD temp_word = 0;
446 BYTE param1 = Registers[REGISTER_A];
447 BYTE param2 = Registers[REGISTER_L];
448 BYTE saved_flags;
449
450
451 switch (opcode) {
452
453 //LDAA & LDAB: Loads Memory into Accumulator
454
455 case 0x0A: //LDAA Immidiate
456 data = fetch(); Registers[REGISTER_A] = data;
457 break;
458
459 case 0x1A: //LDAA ABSOLUTE
460 HB = fetch();
461 LB = fetch();
462 address += (WORD)((WORD)HB << 8) + LB;
463 if (address >= 0 && address < MEMORY_SIZE) {
464 Registers[REGISTER_A] = Memory[address];
465 }
466 break;
467
468 case 0x2A: //LDAA INDEXED ABSOLUTE, X
469 address += Index_Registers[REGISTER_X];
470 HB = fetch();
471 LB = fetch();
472 address += (WORD)((WORD)HB << 8) + LB;
473 if (address >= 0 && address < MEMORY_SIZE) {
474 Registers[REGISTER_A] = Memory[address];
475 }
476 break;
477
478 case 0x3A: //LDAA INDEXED ABSOLUTE, Y
479 address += Index_Registers[REGISTER_Y];
480 HB = fetch();
481 LB = fetch();
482 address += (WORD)((WORD)HB << 8) + LB;
483 if (address >= 0 && address < MEMORY_SIZE) {
484 Registers[REGISTER_A] = Memory[address];
485 }
486 break;
487
488 case 0x4A: //LDAA INDIRECT
489 HB = fetch();
490 LB = fetch();
491 address = (WORD)((WORD)HB << 8) + LB;
492 HB = Memory[address];
493 LB = Memory[address + 1];
494 address = (WORD)((WORD)HB << 8) + LB;
495 if (address >= 0 && address < MEMORY_SIZE) {
496 Registers[REGISTER_A] = Memory[address];
497 }
498 break;
499
500 case 0x5A: //LDAA INDIRECT, X
501 HB = fetch();
502 LB = fetch();
503 address = (WORD)((WORD)HB << 8) + LB;
504 HB = Memory[address];
505 LB = Memory[address + 1];
506 address = (WORD)((WORD)HB << 8) + LB; address += Index_Registers[REGISTER_X];
507 if (address >= 0 && address < MEMORY_SIZE) {
508 Registers[REGISTER_A] = Memory[address];
509 }
510 break;
511
512 case 0x0B: //LDAB Immidiate
513 data = fetch(); Registers[REGISTER_B] = data;
514 break;
515
516 case 0x1B: //LDAB ABSOLUTE
517 HB = fetch();
518 LB = fetch();
519 address += (WORD)((WORD)HB << 8) + LB;
520 if (address >= 0 && address < MEMORY_SIZE) {
521 Registers[REGISTER_B] = Memory[address];
522 }
523 break;
524
525 case 0x2B: //LDAB INDEXED ABSOLUTE, X
526 address += Index_Registers[REGISTER_X];
527 HB = fetch();
528 LB = fetch();
529 address += (WORD)((WORD)HB << 8) + LB;
530 if (address >= 0 && address < MEMORY_SIZE) {
531 Registers[REGISTER_B] = Memory[address];
532 }
533 break;
534
535 case 0x3B: //LDAB INDEXED ABSOLUTE, Y
536 address += Index_Registers[REGISTER_Y];
537 HB = fetch();
538 LB = fetch();
539 address += (WORD)((WORD)HB << 8) + LB;
540 if (address >= 0 && address < MEMORY_SIZE) {
541 Registers[REGISTER_B] = Memory[address];
542 }
543 break;
544
545 case 0x4B: //LDAB INDIRECT
546 HB = fetch();
547 LB = fetch();
548 address = (WORD)((WORD)HB << 8) + LB;
549 HB = Memory[address];
550 LB = Memory[address + 1];
551 address = (WORD)((WORD)HB << 8) + LB;
552 if (address >= 0 && address < MEMORY_SIZE) {
553 Registers[REGISTER_B] = Memory[address];
554 }
555 break;
556
557 case 0x5B: //LDAB INDIRECT, X
558 HB = fetch();
559 LB = fetch();
560 address = (WORD)((WORD)HB << 8) + LB;
561 HB = Memory[address];
562 LB = Memory[address + 1];
563 address = (WORD)((WORD)HB << 8) + LB; address += Index_Registers[REGISTER_X];
564 if (address >= 0 && address < MEMORY_SIZE) {
565 Registers[REGISTER_B] = Memory[address];
566 }
567 break;
568
569 //STORA & STORB: Stores Accumulator into memory
570 case 0xBA: //STORA ABSOLUTE
571 HB = fetch();
572 LB = fetch();
573 address += (WORD)((WORD)HB << 8) + LB;
574 if (address >= 0 && address < MEMORY_SIZE) {
575 Memory[address] = Registers[REGISTER_A];
576 }
577 break;
578
579 case 0xCA: //STORA ABSOLUTE, X
580 address += Index_Registers[REGISTER_X];
581 HB = fetch();
582 LB = fetch();
583 address += (WORD)((WORD)HB << 8) + LB;
584 if (address >= 0 && address < MEMORY_SIZE) {
585 Memory[address] = Registers[REGISTER_A];
586 }
587 break;
588
589 case 0xDA: //STORA ABSOLUTE, Y
590 address += Index_Registers[REGISTER_Y];
591 HB = fetch();
592 LB = fetch();
593 address += (WORD)((WORD)HB << 8) + LB;
594 if (address >= 0 && address < MEMORY_SIZE) {
595 Memory[address] = Registers[REGISTER_A];
596 }
597 break;
598
599 case 0xEA: //STORA INDIRECT
600 HB = fetch();
601 LB = fetch();
602 address = (WORD)((WORD)HB << 8) + LB;
603 HB = Memory[address];
604 LB = Memory[address + 1];
605 address = (WORD)((WORD)HB << 8) + LB;
606 if (address >= 0 && address < MEMORY_SIZE) {
607 Memory[address] = Registers[REGISTER_A];
608 }
609 break;
610
611 case 0xFA: //STORA INDIRECT, X
612 HB = fetch();
613 LB = fetch();
614 address = (WORD)((WORD)HB << 8) + LB;
615 HB = Memory[address];
616 LB = Memory[address + 1];
617 address = (WORD)((WORD)HB << 8) + LB; address += Index_Registers[REGISTER_X];
618 if (address >= 0 && address < MEMORY_SIZE) {
619 Memory[address] = Registers[REGISTER_A];
620 }
621 break;
622
623
624 case 0xBB: //STORB ABSOLUTE
625 HB = fetch();
626 LB = fetch();
627 address += (WORD)((WORD)HB << 8) + LB;
628 if (address >= 0 && address < MEMORY_SIZE) {
629 Memory[address] = Registers[REGISTER_B];
630 }
631 break;
632
633 case 0xCB: //STORB ABSOLUTE, X
634 address += Index_Registers[REGISTER_X];
635 HB = fetch();
636 LB = fetch();
637 address += (WORD)((WORD)HB << 8) + LB;
638 if (address >= 0 && address < MEMORY_SIZE) {
639 Memory[address] = Registers[REGISTER_B];
640 }
641 break;
642
643 case 0xDB: //STORB ABSOLUTE, Y
644 address += Index_Registers[REGISTER_Y];
645 HB = fetch();
646 LB = fetch();
647 address += (WORD)((WORD)HB << 8) + LB;
648 if (address >= 0 && address < MEMORY_SIZE) {
649 Memory[address] = Registers[REGISTER_B];
650 }
651 break;
652
653 case 0xEB: //STORB INDIRECT
654 HB = fetch();
655 LB = fetch();
656 address = (WORD)((WORD)HB << 8) + LB;
657 HB = Memory[address];
658 LB = Memory[address + 1];
659 address = (WORD)((WORD)HB << 8) + LB;
660 if (address >= 0 && address < MEMORY_SIZE) {
661 Memory[address] = Registers[REGISTER_B];
662 }
663 break;
664
665 case 0xFB: //STORB INDIRECT, X
666 HB = fetch();
667 LB = fetch();
668 address = (WORD)((WORD)HB << 8) + LB;
669 HB = Memory[address];
670 LB = Memory[address + 1];
671 address = (WORD)((WORD)HB << 8) + LB; address += Index_Registers[REGISTER_X];
672 if (address >= 0 && address < MEMORY_SIZE) {
673 Memory[address] = Registers[REGISTER_B];
674 }
675 break;
676
677
678 //ADC: Register added to accumulator with carry
679
680 case 0x31: //ADC A, L
681 param1 = Registers[REGISTER_A];
682 param2 = Registers[REGISTER_L];
683 temp_word = (WORD)param1 + (WORD)param2; //adds accumulator with carry
684 if ((Flags & FLAG_C) != 0) {
685 temp_word++;
686 }
687 if (temp_word >= 0x100) {
688 Flags = Flags | FLAG_C; // Set carry flag
689 }
690 else {
691 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
692 }
693 set_flag_n((BYTE)temp_word);
694 set_flag_z((BYTE)temp_word);
695 Registers[REGISTER_A] = (BYTE)temp_word; //sets A to result
696 break;
697
698 case 0x41: //ADC A, H
699 param1 = Registers[REGISTER_A];
700 param2 = Registers[REGISTER_H];
701 temp_word = (WORD)param1 + (WORD)param2;
702 if ((Flags & FLAG_C) != 0) {
703 temp_word++;
704 }
705 if (temp_word >= 0x100) {
706 Flags = Flags | FLAG_C; // Set carry flag
707 }
708 else {
709 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
710 }
711 set_flag_n((BYTE)temp_word);
712 set_flag_z((BYTE)temp_word);
713 Registers[REGISTER_A] = (BYTE)temp_word;
714 break;
715
716 case 0x51: //ADC A, M
717 param1 = Registers[REGISTER_A];
718 param2 = Registers[REGISTER_M];
719 temp_word = (WORD)param1 + (WORD)param2;
720 if ((Flags & FLAG_C) != 0) {
721 temp_word++;
722 }
723 if (temp_word >= 0x100) {
724 Flags = Flags | FLAG_C; // Set carry flag
725 }
726 else {
727 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
728 }
729 set_flag_n((BYTE)temp_word);
730 set_flag_z((BYTE)temp_word);
731 Registers[REGISTER_A] = (BYTE)temp_word;
732 break;
733
734 case 0x61: //ADC B, L
735 param1 = Registers[REGISTER_B];
736 param2 = Registers[REGISTER_L];
737 temp_word = (WORD)param1 + (WORD)param2;
738 if ((Flags & FLAG_C) != 0) {
739 temp_word++;
740 }
741 if (temp_word >= 0x100) {
742 Flags = Flags | FLAG_C; // Set carry flag
743 }
744 else {
745 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
746 }
747 set_flag_n((BYTE)temp_word);
748 set_flag_z((BYTE)temp_word);
749 Registers[REGISTER_B] = (BYTE)temp_word;
750 break;
751
752 case 0x71: //ADC B, H
753 param1 = Registers[REGISTER_B];
754 param2 = Registers[REGISTER_H];
755 temp_word = (WORD)param1 + (WORD)param2;
756 if ((Flags & FLAG_C) != 0) {
757 temp_word++;
758 }
759 if (temp_word >= 0x100) {
760 Flags = Flags | FLAG_C; // Set carry flag
761 }
762 else {
763 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
764 }
765 set_flag_n((BYTE)temp_word);
766 set_flag_z((BYTE)temp_word);
767 Registers[REGISTER_B] = (BYTE)temp_word;
768 break;
769
770 case 0x81: //ADC B, M
771 param1 = Registers[REGISTER_B];
772 param2 = Registers[REGISTER_M];
773 temp_word = (WORD)param1 + (WORD)param2;
774 if ((Flags & FLAG_C) != 0) {
775 temp_word++;
776 }
777 if (temp_word >= 0x100) {
778 Flags = Flags | FLAG_C; // Set carry flag
779 }
780 else {
781 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
782 }
783 set_flag_n((BYTE)temp_word);
784 set_flag_z((BYTE)temp_word);
785 Registers[REGISTER_B] = (BYTE)temp_word;
786 break;
787
788
789 //SBC: Register subtracted to accumulator with carry
790
791 case 0x32: //SBC A, L
792 param1 = Registers[REGISTER_A];
793 param2 = Registers[REGISTER_L];
794 temp_word = (WORD)param1 - (WORD)param2;
795 if ((Flags & FLAG_C) != 0) {
796 temp_word--;
797 }
798 if (temp_word >= 0x100) {
799 Flags = Flags | FLAG_C; // Set carry flag
800 }
801 else {
802 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
803 }
804 set_flag_n((BYTE)temp_word);
805 set_flag_z((BYTE)temp_word);
806 Registers[REGISTER_A] = (BYTE)temp_word;
807 break;
808
809 case 0x42: //SBC A, H
810 param1 = Registers[REGISTER_A];
811 param2 = Registers[REGISTER_H];
812 temp_word = (WORD)param1 - (WORD)param2;
813 if ((Flags & FLAG_C) != 0) {
814 temp_word--;
815 }
816 if (temp_word >= 0x100) {
817 Flags = Flags | FLAG_C; // Set carry flag
818 }
819 else {
820 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
821 }
822 set_flag_n((BYTE)temp_word);
823 set_flag_z((BYTE)temp_word);
824 Registers[REGISTER_A] = (BYTE)temp_word;
825 break;
826
827 case 0x52: //SBC A, M
828 param1 = Registers[REGISTER_A];
829 param2 = Registers[REGISTER_M];
830 temp_word = (WORD)param1 - (WORD)param2;
831 if ((Flags & FLAG_C) != 0) {
832 temp_word--;
833 }
834 if (temp_word >= 0x100) {
835 Flags = Flags | FLAG_C; // Set carry flag
836 }
837 else {
838 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
839 }
840 set_flag_n((BYTE)temp_word);
841 set_flag_z((BYTE)temp_word);
842 Registers[REGISTER_A] = (BYTE)temp_word;
843 break;
844
845 case 0x62: //SBC B, L
846 param1 = Registers[REGISTER_B];
847 param2 = Registers[REGISTER_L];
848 temp_word = (WORD)param1 - (WORD)param2;
849 if ((Flags & FLAG_C) != 0) {
850 temp_word--;
851 }
852 if (temp_word >= 0x100) {
853 Flags = Flags | FLAG_C; // Set carry flag
854 }
855 else {
856 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
857 }
858 set_flag_n((BYTE)temp_word);
859 set_flag_z((BYTE)temp_word);
860 Registers[REGISTER_B] = (BYTE)temp_word;
861 break;
862
863 case 0x72: //SBC B, H
864 param1 = Registers[REGISTER_B];
865 param2 = Registers[REGISTER_H];
866 temp_word = (WORD)param1 - (WORD)param2;
867 if ((Flags & FLAG_C) != 0) {
868 temp_word--;
869 }
870 if (temp_word >= 0x100) {
871 Flags = Flags | FLAG_C; // Set carry flag
872 }
873 else {
874 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
875 }
876 set_flag_n((BYTE)temp_word);
877 set_flag_z((BYTE)temp_word);
878 Registers[REGISTER_B] = (BYTE)temp_word;
879 break;
880
881 case 0x82: //SBC B, M
882 param1 = Registers[REGISTER_B];
883 param2 = Registers[REGISTER_M];
884 temp_word = (WORD)param1 - (WORD)param2;
885 if ((Flags & FLAG_C) != 0) {
886 temp_word--;
887 }
888 if (temp_word >= 0x100) {
889 Flags = Flags | FLAG_C; // Set carry flag
890 }
891 else {
892 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
893 }
894 set_flag_n((BYTE)temp_word);
895 set_flag_z((BYTE)temp_word);
896 Registers[REGISTER_B] = (BYTE)temp_word;
897 break;
898
899
900 //ADD: Register added to accumulator
901 case 0x33: //ADD A, L
902 param1 = Registers[REGISTER_A];
903 param2 = Registers[REGISTER_L];
904 temp_word = (WORD)param1 + (WORD)param2;
905 if (temp_word >= 0x100) {
906 Flags = Flags | FLAG_C; // Set carry flag
907 }
908 else {
909 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
910 }
911 set_flag_n((BYTE)temp_word);
912 set_flag_z((BYTE)temp_word);
913 Registers[REGISTER_A] = (BYTE)temp_word;
914 break;
915
916 case 0x43: //ADD A, H
917 param1 = Registers[REGISTER_A];
918 param2 = Registers[REGISTER_H];
919 temp_word = (WORD)param1 + (WORD)param2;
920 if (temp_word >= 0x100) {
921 Flags = Flags | FLAG_C; // Set carry flag
922 }
923 else {
924 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
925 }
926 set_flag_n((BYTE)temp_word);
927 set_flag_z((BYTE)temp_word);
928 Registers[REGISTER_A] = (BYTE)temp_word;
929 break;
930
931 case 0x53: //ADD A, M
932 param1 = Registers[REGISTER_A];
933 param2 = Registers[REGISTER_M];
934 temp_word = (WORD)param1 + (WORD)param2;
935 if (temp_word >= 0x100) {
936 Flags = Flags | FLAG_C; // Set carry flag
937 }
938 else {
939 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
940 }
941 set_flag_n((BYTE)temp_word);
942 set_flag_z((BYTE)temp_word);
943 Registers[REGISTER_A] = (BYTE)temp_word;
944 break;
945
946 case 0x63: //ADD B, L
947 param1 = Registers[REGISTER_B];
948 param2 = Registers[REGISTER_L];
949 temp_word = (WORD)param1 + (WORD)param2;
950 if (temp_word >= 0x100) {
951 Flags = Flags | FLAG_C; // Set carry flag
952 }
953 else {
954 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
955 }
956 set_flag_n((BYTE)temp_word);
957 set_flag_z((BYTE)temp_word);
958 Registers[REGISTER_B] = (BYTE)temp_word;
959 break;
960
961 case 0x73: //ADD B, H
962 param1 = Registers[REGISTER_B];
963 param2 = Registers[REGISTER_H];
964 temp_word = (WORD)param1 + (WORD)param2;
965 if (temp_word >= 0x100) {
966 Flags = Flags | FLAG_C; // Set carry flag
967 }
968 else {
969 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
970 }
971 set_flag_n((BYTE)temp_word);
972 set_flag_z((BYTE)temp_word);
973 Registers[REGISTER_B] = (BYTE)temp_word;
974 break;
975
976 case 0x83: //ADD B, M
977 param1 = Registers[REGISTER_B];
978 param2 = Registers[REGISTER_M];
979 temp_word = (WORD)param1 + (WORD)param2;
980 if (temp_word >= 0x100) {
981 Flags = Flags | FLAG_C; // Set carry flag
982 }
983 else {
984 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
985 }
986 set_flag_n((BYTE)temp_word);
987 set_flag_z((BYTE)temp_word);
988 Registers[REGISTER_B] = (BYTE)temp_word;
989 break;
990
991 //SUB: Register subtracted to accumulator
992 case 0x34: //SUB A, L
993 param1 = Registers[REGISTER_A];
994 param2 = Registers[REGISTER_L];
995 temp_word = (WORD)param1 - (WORD)param2;
996 if (temp_word >= 0x100) {
997 Flags = Flags | FLAG_C; // Set carry flag
998 }
999 else {
1000 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1001 }
1002 set_flag_n((BYTE)temp_word);
1003 set_flag_z((BYTE)temp_word);
1004 Registers[REGISTER_A] = (BYTE)temp_word;
1005 break;
1006
1007 case 0x44: //SUB A, H
1008 param1 = Registers[REGISTER_A];
1009 param2 = Registers[REGISTER_H];
1010 temp_word = (WORD)param1 - (WORD)param2;
1011 if (temp_word >= 0x100) {
1012 Flags = Flags | FLAG_C; // Set carry flag
1013 }
1014 else {
1015 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1016 }
1017 set_flag_n((BYTE)temp_word);
1018 set_flag_z((BYTE)temp_word);
1019 Registers[REGISTER_A] = (BYTE)temp_word;
1020 break;
1021
1022 case 0x54: //SUB A, M
1023 param1 = Registers[REGISTER_A];
1024 param2 = Registers[REGISTER_M];
1025 temp_word = (WORD)param1 - (WORD)param2;
1026 if (temp_word >= 0x100) {
1027 Flags = Flags | FLAG_C; // Set carry flag
1028 }
1029 else {
1030 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1031 }
1032 set_flag_n((BYTE)temp_word);
1033 set_flag_z((BYTE)temp_word);
1034 Registers[REGISTER_A] = (BYTE)temp_word;
1035 break;
1036
1037 case 0x64: //SUB B, L
1038 param1 = Registers[REGISTER_B];
1039 param2 = Registers[REGISTER_L];
1040 temp_word = (WORD)param1 - (WORD)param2;
1041 if (temp_word >= 0x100) {
1042 Flags = Flags | FLAG_C; // Set carry flag
1043 }
1044 else {
1045 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1046 }
1047 set_flag_n((BYTE)temp_word);
1048 set_flag_z((BYTE)temp_word);
1049 Registers[REGISTER_B] = (BYTE)temp_word;
1050 break;
1051
1052 case 0x74: //SUB B, H
1053 param1 = Registers[REGISTER_B];
1054 param2 = Registers[REGISTER_H];
1055 temp_word = (WORD)param1 - (WORD)param2;
1056 if (temp_word >= 0x100) {
1057 Flags = Flags | FLAG_C; // Set carry flag
1058 }
1059 else {
1060 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1061 }
1062 set_flag_n((BYTE)temp_word);
1063 set_flag_z((BYTE)temp_word);
1064 Registers[REGISTER_B] = (BYTE)temp_word;
1065 break;
1066
1067 case 0x84: //SUB B, M
1068 param1 = Registers[REGISTER_B];
1069 param2 = Registers[REGISTER_M];
1070 temp_word = (WORD)param1 - (WORD)param2;
1071 if (temp_word >= 0x100) {
1072 Flags = Flags | FLAG_C; // Set carry flag
1073 }
1074 else {
1075 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1076 }
1077 set_flag_n((BYTE)temp_word);
1078 set_flag_z((BYTE)temp_word);
1079 Registers[REGISTER_B] = (BYTE)temp_word;
1080 break;
1081
1082
1083 //CMP: Register compared to Accumulator
1084
1085 case 0x35: //CMP A,L
1086 param1 = Registers[REGISTER_A];
1087 param2 = Registers[REGISTER_L];
1088 temp_word = (WORD)param1 - (WORD)param2;
1089 if (temp_word >= 0x100)
1090 {
1091 Flags = Flags | FLAG_C; // Set carry flag
1092 }
1093 set_flag_n((BYTE)temp_word);
1094 set_flag_z((BYTE)temp_word);
1095 break;
1096
1097 case 0x45: //CMP A,H
1098 param1 = Registers[REGISTER_A];
1099 param2 = Registers[REGISTER_H];
1100 temp_word = (WORD)param1 - (WORD)param2;
1101 if (temp_word >= 0x100)
1102 {
1103 Flags = Flags | FLAG_C; // Set carry flag
1104 }
1105 else
1106 {
1107 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1108 }
1109 set_flag_n((BYTE)temp_word);
1110 set_flag_z((BYTE)temp_word);
1111 break;
1112
1113 case 0x55: //CMP A,M
1114 param1 = Registers[REGISTER_A];
1115 param2 = Registers[REGISTER_M];
1116 temp_word = (WORD)param1 - (WORD)param2;
1117 if (temp_word >= 0x100)
1118 {
1119 Flags = Flags | FLAG_C; // Set carry flag
1120 }
1121 else
1122 {
1123 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1124 }
1125 set_flag_n((BYTE)temp_word);
1126 set_flag_z((BYTE)temp_word);
1127 break;
1128
1129 case 0x65: //CMP B,L
1130 param1 = Registers[REGISTER_B];
1131 param2 = Registers[REGISTER_L];
1132 temp_word = (WORD)param1 - (WORD)param2;
1133 if (temp_word >= 0x100)
1134 {
1135 Flags = Flags | FLAG_C; // Set carry flag
1136 }
1137 else
1138 {
1139 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1140 }
1141 set_flag_n((BYTE)temp_word);
1142 set_flag_z((BYTE)temp_word);
1143 break;
1144
1145 case 0x75: //CMP B,H
1146 param1 = Registers[REGISTER_B];
1147 param2 = Registers[REGISTER_H];
1148 temp_word = (WORD)param1 - (WORD)param2;
1149 if (temp_word >= 0x100)
1150 {
1151 Flags = Flags | FLAG_C; // Set carry flag
1152 }
1153 else
1154 {
1155 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1156 }
1157 set_flag_n((BYTE)temp_word);
1158 set_flag_z((BYTE)temp_word);
1159 break;
1160
1161 case 0x85: //CMP A,L
1162 param1 = Registers[REGISTER_B];
1163 param2 = Registers[REGISTER_M];
1164 temp_word = (WORD)param1 - (WORD)param2;
1165 if (temp_word >= 0x100)
1166 {
1167 Flags = Flags | FLAG_C; // Set carry flag
1168 }
1169 else
1170 {
1171 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1172 }
1173 set_flag_n((BYTE)temp_word);
1174 set_flag_z((BYTE)temp_word);
1175 break;
1176
1177
1178 //OR: Register bitwise inclusive or with Accumulator
1179
1180 case 0x36: //OR A,L
1181 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_L];
1182 set_flag_z((BYTE)temp_word);
1183 set_flag_n((BYTE)temp_word);
1184 Registers[REGISTER_A] = (BYTE)temp_word;
1185 break;
1186
1187 case 0x46: //OR A,H
1188 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_H];
1189 set_flag_z((BYTE)temp_word);
1190 set_flag_n((BYTE)temp_word);
1191 Registers[REGISTER_A] = (BYTE)temp_word;
1192 break;
1193
1194 case 0x56: //OR A,M
1195 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_M];
1196 set_flag_z((BYTE)temp_word);
1197 set_flag_n((BYTE)temp_word);
1198 Registers[REGISTER_A] = (BYTE)temp_word;
1199 break;
1200
1201 case 0x66: //OR B,L
1202 temp_word = (WORD)Registers[REGISTER_B] | (WORD)Registers[REGISTER_L];
1203 set_flag_z((BYTE)temp_word);
1204 set_flag_n((BYTE)temp_word);
1205 Registers[REGISTER_B] = (BYTE)temp_word;
1206 break;
1207
1208 case 0x76: //OR B,H
1209 temp_word = (WORD)Registers[REGISTER_B] | (WORD)Registers[REGISTER_H];
1210 set_flag_z((BYTE)temp_word);
1211 set_flag_n((BYTE)temp_word);
1212 Registers[REGISTER_B] = (BYTE)temp_word;
1213 break;
1214
1215 case 0x86: //OR B,M
1216 temp_word = (WORD)Registers[REGISTER_B] | (WORD)Registers[REGISTER_M];
1217 set_flag_z((BYTE)temp_word);
1218 set_flag_n((BYTE)temp_word);
1219 Registers[REGISTER_B] = (BYTE)temp_word;
1220 break;
1221
1222
1223 //AND: Register bitwise and with Accumulator
1224
1225 case 0x37: //AND
1226 param1 = Registers[REGISTER_A];
1227 param2 = Registers[REGISTER_L];
1228 temp_word = (WORD)param1 & (WORD)param2;
1229 set_flag_n((BYTE)temp_word);
1230 set_flag_z((BYTE)temp_word);
1231 Registers[REGISTER_A] = (BYTE)temp_word;
1232 break;
1233
1234 case 0x47://AND A,H
1235 param1 = Registers[REGISTER_A];
1236 param2 = Registers[REGISTER_H];
1237 temp_word = (WORD)param1 & (WORD)param2;
1238 set_flag_n((BYTE)temp_word);
1239 set_flag_z((BYTE)temp_word);
1240 Registers[REGISTER_A] = (BYTE)temp_word;
1241 break;
1242
1243 case 0x57://AND A,M
1244 param1 = Registers[REGISTER_A];
1245 param2 = Registers[REGISTER_M];
1246 temp_word = (WORD)param1 & (WORD)param2;
1247 set_flag_n((BYTE)temp_word);
1248 set_flag_z((BYTE)temp_word);
1249 Registers[REGISTER_A] = (BYTE)temp_word;
1250 break;
1251
1252 case 0x67://AND B,L
1253 param1 = Registers[REGISTER_B];
1254 param2 = Registers[REGISTER_L];
1255 temp_word = (WORD)param1 & (WORD)param2;
1256 set_flag_n((BYTE)temp_word);
1257 set_flag_z((BYTE)temp_word);
1258 Registers[REGISTER_B] = (BYTE)temp_word;
1259 break;
1260
1261 case 0x77://AND B,H
1262 param1 = Registers[REGISTER_B];
1263 param2 = Registers[REGISTER_H];
1264 temp_word = (WORD)param1 & (WORD)param2;
1265 set_flag_n((BYTE)temp_word);
1266 set_flag_z((BYTE)temp_word);
1267 Registers[REGISTER_B] = (BYTE)temp_word;
1268 break;
1269
1270 case 0x87://AND B,M
1271 param1 = Registers[REGISTER_B];
1272 param2 = Registers[REGISTER_M];
1273 temp_word = (WORD)param1 & (WORD)param2;
1274 set_flag_n((BYTE)temp_word);
1275 set_flag_z((BYTE)temp_word);
1276 Registers[REGISTER_B] = (BYTE)temp_word;
1277 break;
1278
1279
1280 //BIT: Regsiter Bit tested with Accumulator
1281
1282 case 0x39: //BIT A,L
1283 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_L];
1284 param1 = Registers[REGISTER_A];
1285 param2 = Registers[REGISTER_L];
1286 set_flag_n((BYTE)temp_word);
1287 set_flag_z((BYTE)temp_word);
1288 Registers[REGISTER_A];
1289 break;
1290
1291 case 0x49://BIT A,H
1292 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_H];
1293 param1 = Registers[REGISTER_A];
1294 param2 = Registers[REGISTER_H];
1295 set_flag_n((BYTE)temp_word);
1296 set_flag_z((BYTE)temp_word);
1297 Registers[REGISTER_A];
1298 break;
1299
1300 case 0x59://BIT A,M
1301 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_M];
1302 param1 = Registers[REGISTER_A];
1303 param2 = Registers[REGISTER_M];
1304 set_flag_n((BYTE)temp_word);
1305 set_flag_z((BYTE)temp_word);
1306 Registers[REGISTER_A];
1307 break;
1308
1309 case 0x69://BIT B,L
1310 temp_word = (WORD)Registers[REGISTER_B] & (WORD)Registers[REGISTER_L];
1311 param1 = Registers[REGISTER_B];
1312 param2 = Registers[REGISTER_L];
1313 set_flag_n((BYTE)temp_word);
1314 set_flag_z((BYTE)temp_word);
1315 Registers[REGISTER_B];
1316 break;
1317
1318 case 0x79://BIT B,H
1319 temp_word = (WORD)Registers[REGISTER_B] & (WORD)Registers[REGISTER_H];
1320 param1 = Registers[REGISTER_B];
1321 param2 = Registers[REGISTER_H];
1322 set_flag_n((BYTE)temp_word);
1323 set_flag_z((BYTE)temp_word);
1324 Registers[REGISTER_B];
1325 break;
1326
1327 case 0x89://BIT B,M
1328 temp_word = (WORD)Registers[REGISTER_B] & (WORD)Registers[REGISTER_M];
1329 param1 = Registers[REGISTER_B];
1330 param2 = Registers[REGISTER_M];
1331 set_flag_n((BYTE)temp_word);
1332 set_flag_z((BYTE)temp_word);
1333 Registers[REGISTER_B];
1334 break;
1335
1336
1337 //XOR: Register bitwise exclusive or with Accumulator
1338
1339 case 0x38: //XOR A,L
1340 param1 = Registers[REGISTER_A];
1341 param2 = Registers[REGISTER_L];
1342 temp_word = (WORD)param1 ^ (WORD)param2;
1343 set_flag_z((BYTE)temp_word);
1344 set_flag_n((BYTE)temp_word);
1345 Registers[REGISTER_A] = (BYTE)temp_word;
1346 break;
1347
1348 case 0x48: //XOR A,H
1349 param1 = Registers[REGISTER_A];
1350 param2 = Registers[REGISTER_H];
1351 temp_word = (WORD)param1 ^ (WORD)param2;
1352 set_flag_z((BYTE)temp_word);
1353 set_flag_n((BYTE)temp_word);
1354 Registers[REGISTER_A] = (BYTE)temp_word;
1355 break;
1356
1357 case 0x58: //XOR A,M
1358 param1 = Registers[REGISTER_A];
1359 param2 = Registers[REGISTER_M];
1360 temp_word = (WORD)param1 ^ (WORD)param2;
1361 set_flag_z((BYTE)temp_word);
1362 set_flag_n((BYTE)temp_word);
1363 Registers[REGISTER_A] = (BYTE)temp_word;
1364 break;
1365
1366 case 0x68: //XOR B,L
1367 param1 = Registers[REGISTER_B];
1368 param2 = Registers[REGISTER_L];
1369 temp_word = (WORD)param1 ^ (WORD)param2;
1370 set_flag_z((BYTE)temp_word);
1371 set_flag_n((BYTE)temp_word);
1372 Registers[REGISTER_B] = (BYTE)temp_word;
1373 break;
1374
1375 case 0x78: //XOR B,H
1376 param1 = Registers[REGISTER_B];
1377 param2 = Registers[REGISTER_H];
1378 temp_word = (WORD)param1 ^ (WORD)param2;
1379 set_flag_z((BYTE)temp_word);
1380 set_flag_n((BYTE)temp_word);
1381 Registers[REGISTER_B] = (BYTE)temp_word;
1382 break;
1383
1384 case 0x88: //XOR B,M
1385 param1 = Registers[REGISTER_B];
1386 param2 = Registers[REGISTER_M];
1387 temp_word = (WORD)param1 ^ (WORD)param2;
1388 set_flag_z((BYTE)temp_word);
1389 set_flag_n((BYTE)temp_word);
1390 Registers[REGISTER_B] = (BYTE)temp_word;
1391 break;
1392
1393 //SBIA & SBIB: Data subtracted to accumulator with carry
1394
1395 case 0x93: //SBIA (#)
1396 data = fetch();
1397 param1 = Registers[REGISTER_A];
1398 temp_word = (WORD)data - (WORD)param1;
1399 if ((Flags & FLAG_C) != 0) {
1400 temp_word--;
1401 }
1402 if (temp_word >= 0x100) {
1403 Flags = Flags | FLAG_C; // Set carry flag
1404 }
1405 else {
1406 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1407 }
1408 set_flag_n((BYTE)temp_word);
1409 set_flag_z((BYTE)temp_word);
1410 Registers[REGISTER_A] = temp_word;
1411 break;
1412
1413 case 0x94: //SBIB (#)
1414 data = fetch();
1415 param1 = Registers[REGISTER_B];
1416 temp_word = (WORD)data - (WORD)param1;
1417 if ((Flags & FLAG_C) != 0) {
1418 temp_word--;
1419 }
1420 if (temp_word >= 0x100) {
1421 Flags = Flags | FLAG_C; // Set carry flag
1422 }
1423 else {
1424 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1425 }
1426 set_flag_n((BYTE)temp_word);
1427 set_flag_z((BYTE)temp_word);
1428 Registers[REGISTER_B] = temp_word;
1429 break;
1430
1431 //ORIA & ORIB: Data bitwise inclusive or with Accumulator
1432 case 0x97: //ORIA (#)
1433 data = fetch();
1434 param1 = Registers[REGISTER_A];
1435 temp_word = (WORD)data | (WORD)param1;
1436 set_flag_z((WORD)temp_word);
1437 set_flag_n((WORD)temp_word);
1438 Registers[REGISTER_A] = temp_word;
1439 break;
1440
1441 case 0x98: //ORIB (#)
1442 data = fetch();
1443 param1 = Registers[REGISTER_B];
1444 temp_word = (WORD)data | (WORD)param1;
1445 set_flag_z((WORD)temp_word);
1446 set_flag_n((WORD)temp_word);
1447 Registers[REGISTER_B] = temp_word;
1448 break;
1449
1450 //INCA & INCB: Increment Memory or Accumulator
1451 case 0xD0: //INCA
1452 ++Registers[REGISTER_A];
1453 set_flag_n(Registers[REGISTER_A]);
1454 set_flag_z(Registers[REGISTER_A]);
1455 break;
1456
1457 case 0xE0: //INCB
1458 ++Registers[REGISTER_B];
1459 set_flag_n(Registers[REGISTER_B]);
1460 set_flag_z(Registers[REGISTER_B]);
1461 break;
1462
1463 //DECA & DECB: Decrament Memory or Accumulator
1464 case 0xD1: //DECA
1465 --Registers[REGISTER_A];
1466 set_flag_n(Registers[REGISTER_A]);
1467 set_flag_z(Registers[REGISTER_A]);
1468 break;
1469
1470 case 0xE1: //DECB
1471 --Registers[REGISTER_B];
1472 set_flag_n(Registers[REGISTER_B]);
1473 set_flag_z(Registers[REGISTER_B]);
1474 break;
1475
1476 //RRCA & RRCB: Rotate right through carry Memory or Accumulator
1477 case 0xD2: // RRCA
1478 saved_flags = Flags;
1479 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
1480 Flags = Flags | FLAG_C;
1481 }
1482 else {
1483 Flags = Flags & (0xFF - FLAG_C);
1484 }
1485 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
1486 if ((saved_flags & FLAG_C) == FLAG_C) {
1487 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
1488 }
1489 set_flag_n(Registers[REGISTER_A]);
1490 set_flag_z(Registers[REGISTER_A]);
1491 break;
1492
1493 case 0xE2: // RRCB
1494 saved_flags = Flags;
1495 if ((Registers[REGISTER_B] & 0x01) == 0x01) {
1496 Flags = Flags | FLAG_C;
1497 }
1498 else {
1499 Flags = Flags & (0xFF - FLAG_C);
1500 }
1501 Registers[REGISTER_B] = (Registers[REGISTER_B] >> 1) & 0x7F;
1502 if ((saved_flags & FLAG_C) == FLAG_C) {
1503 Registers[REGISTER_B] = Registers[REGISTER_B] | 0x80;
1504 }
1505 set_flag_n(Registers[REGISTER_B]);
1506 set_flag_z(Registers[REGISTER_B]);
1507 break;
1508
1509 //RLCA & RLCB: Rotate left rhough carry Memory or Accumulator
1510 case 0xD3: // RLCA
1511 saved_flags = Flags;
1512 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
1513 Flags = Flags | FLAG_C;
1514 }
1515 else {
1516 Flags = Flags & (0xFF - FLAG_C);
1517 }
1518 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
1519 if ((saved_flags & FLAG_C) == FLAG_C) {
1520 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
1521 }
1522 set_flag_n(Registers[REGISTER_A]);
1523 set_flag_z(Registers[REGISTER_A]);
1524 break;
1525
1526 case 0xE3: // RLCB
1527 saved_flags = Flags;
1528 if ((Registers[REGISTER_B] & 0x80) == 0x80) {
1529 Flags = Flags | FLAG_C;
1530 }
1531 else {
1532 Flags = Flags & (0xFF - FLAG_C);
1533 }
1534 Registers[REGISTER_B] = (Registers[REGISTER_B] << 1) & 0xFE;
1535 if ((saved_flags & FLAG_C) == FLAG_C) {
1536 Registers[REGISTER_B] = Registers[REGISTER_B] | 0x01;
1537 }
1538 set_flag_n(Registers[REGISTER_B]);
1539 set_flag_z(Registers[REGISTER_B]);
1540 break;
1541
1542
1543 //SALA & SALB: Arithmetic shift left Memory or Accumulator
1544 case 0xD4: // SALA
1545 saved_flags = Flags;
1546 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
1547 Flags = Flags | FLAG_C;
1548 }
1549 else {
1550 Flags = Flags & (0xFF - FLAG_C);
1551 }
1552 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
1553
1554 set_flag_n(Registers[REGISTER_A]);
1555 set_flag_z(Registers[REGISTER_A]);
1556 break;
1557
1558 case 0xE4: // SALB
1559 saved_flags = Flags;
1560 if ((Registers[REGISTER_B] & 0x80) == 0x80) {
1561 Flags = Flags | FLAG_C;
1562 }
1563 else {
1564 Flags = Flags & (0xFF - FLAG_C);
1565 }
1566 Registers[REGISTER_B] = (Registers[REGISTER_B] << 1) & 0xFE;
1567
1568 set_flag_n(Registers[REGISTER_B]);
1569 set_flag_z(Registers[REGISTER_B]);
1570 break;
1571
1572
1573
1574 //SARA & SARB: Arithmetic shift right Memory or Accumulator
1575 case 0xD5: // SARA
1576 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
1577 Flags = Flags | FLAG_C;
1578 }
1579 else {
1580 Flags = Flags & (0xFF - FLAG_C);
1581 }
1582
1583 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
1584 if ((Registers[REGISTER_A] & 0x40) == 0x40) {
1585 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
1586 }
1587 set_flag_n(Registers[REGISTER_A]);
1588 set_flag_z(Registers[REGISTER_A]);
1589 break;
1590
1591 case 0xE5: // SARB
1592 if ((Registers[REGISTER_B] & 0x01) == 0x01) {
1593 Flags = Flags | FLAG_C;
1594 }
1595 else {
1596 Flags = Flags & (0xFF - FLAG_C);
1597 }
1598
1599 Registers[REGISTER_B] = (Registers[REGISTER_B] >> 1) & 0x7F;
1600 if ((Registers[REGISTER_B] & 0x40) == 0x40) {
1601 Registers[REGISTER_B] = Registers[REGISTER_B] | 0x80;
1602 }
1603 set_flag_n(Registers[REGISTER_B]);
1604 set_flag_z(Registers[REGISTER_B]);
1605 break;
1606
1607
1608 //LSR Shift right Memory or Accumulator
1609 case 0xA6:// LSR ABSOLUTE
1610 HB = fetch();
1611 LB = fetch();
1612 address += (WORD)((WORD)HB << 8) + LB;
1613 temp_word = Memory[address];
1614 if (address >= 0 && address < MEMORY_SIZE)
1615 {
1616 if ((temp_word & 0x01) != 0)
1617 {
1618 Flags |= FLAG_C;
1619 }
1620 else
1621 {
1622 Flags &= (~FLAG_C);
1623 }
1624 temp_word = temp_word >> 1;
1625 temp_word = temp_word & 0x7F;
1626 }
1627 set_flag_n(Registers[REGISTER_B]);
1628 set_flag_z(Registers[REGISTER_B]);
1629 Memory[address] = (BYTE)temp_word;
1630 break;
1631
1632 case 0xB6:// LSR ABSOLUTE X
1633 address += Registers[REGISTER_X];
1634 HB = fetch();
1635 LB = fetch();
1636 address += (WORD)((WORD)HB << 8) + LB;
1637 temp_word = Memory[address];
1638 if (address >= 0 && address < MEMORY_SIZE)
1639 {
1640 if ((temp_word & 0x01) != 0)
1641 {
1642 Flags |= FLAG_C;
1643 }
1644 else
1645 {
1646 Flags &= (~FLAG_C);
1647 }
1648 temp_word = temp_word >> 1;
1649 temp_word = temp_word & 0x7F;
1650 }
1651 set_flag_n(Registers[REGISTER_B]);
1652 set_flag_z(Registers[REGISTER_B]);
1653 Memory[address] = (BYTE)temp_word;
1654 break;
1655
1656 case 0xC6:// LSR ABSOLUTE Y
1657 address += Registers[REGISTER_Y];
1658 HB = fetch();
1659 LB = fetch();
1660 address += (WORD)((WORD)HB << 8) + LB;
1661 temp_word = Memory[address];
1662 if (address >= 0 && address < MEMORY_SIZE) {
1663 if ((temp_word & 0x01) != 0)
1664 {
1665 Flags |= FLAG_C;
1666 }
1667 else
1668 {
1669 Flags &= (~FLAG_C);
1670 }
1671 temp_word = temp_word >> 1;
1672 temp_word = temp_word & 0x7F;
1673 }
1674 set_flag_n(Registers[REGISTER_B]);
1675 set_flag_z(Registers[REGISTER_B]);
1676 Memory[address] = (BYTE)temp_word;
1677 break;
1678
1679 case 0xD6: // LSRA
1680 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
1681 Flags = Flags | FLAG_C;
1682 }
1683 else {
1684 Flags = Flags & (0xFF - FLAG_C);
1685 }
1686 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
1687 set_flag_n(Registers[REGISTER_A]);
1688 set_flag_z(Registers[REGISTER_A]);
1689 break;
1690
1691 case 0xE6: // LSRB
1692 if ((Registers[REGISTER_B] & 0x01) == 0x01) {
1693 Flags = Flags | FLAG_C;
1694 }
1695 else {
1696 Flags = Flags & (0xFF - FLAG_C);
1697 }
1698 Registers[REGISTER_B] = (Registers[REGISTER_B] >> 1) & 0x7F;
1699 set_flag_n(Registers[REGISTER_B]);
1700 set_flag_z(Registers[REGISTER_B]);
1701 break;
1702
1703
1704
1705 case 0x0E: //LDX Immidiate
1706 data = fetch(); Registers[REGISTER_A] = data;
1707 break;
1708
1709 case 0x1E: //LDX ABSOLUTE
1710 HB = fetch();
1711 LB = fetch();
1712 address += (WORD)((WORD)HB << 8) + LB;
1713 if (address >= 0 && address < MEMORY_SIZE) {
1714 Registers[REGISTER_A] = Memory[address];
1715 }
1716 break;
1717
1718 case 0x2E: //LDX INDEXED ABSOLUTE, X
1719 address += Index_Registers[REGISTER_X];
1720 HB = fetch();
1721 LB = fetch();
1722 address += (WORD)((WORD)HB << 8) + LB;
1723 if (address >= 0 && address < MEMORY_SIZE) {
1724 Registers[REGISTER_A] = Memory[address];
1725 }
1726 break;
1727
1728 case 0x3E: //LDX INDEXED ABSOLUTE, Y
1729 address += Index_Registers[REGISTER_Y];
1730 HB = fetch();
1731 LB = fetch();
1732 address += (WORD)((WORD)HB << 8) + LB;
1733 if (address >= 0 && address < MEMORY_SIZE) {
1734 Registers[REGISTER_A] = Memory[address];
1735 }
1736 break;
1737
1738 case 0x4E: //LDX INDIRECT
1739 HB = fetch();
1740 LB = fetch();
1741 address = (WORD)((WORD)HB << 8) + LB;
1742 HB = Memory[address];
1743 LB = Memory[address + 1];
1744 address = (WORD)((WORD)HB << 8) + LB;
1745 if (address >= 0 && address < MEMORY_SIZE) {
1746 Registers[REGISTER_A] = Memory[address];
1747 }
1748 break;
1749
1750 case 0x5E: //LDX INDIRECT, X
1751 HB = fetch();
1752 LB = fetch();
1753 address = (WORD)((WORD)HB << 8) + LB;
1754 HB = Memory[address];
1755 LB = Memory[address + 1];
1756 address = (WORD)((WORD)HB << 8) + LB; address += Index_Registers[REGISTER_X];
1757 if (address >= 0 && address < MEMORY_SIZE) {
1758 Registers[REGISTER_A] = Memory[address];
1759 }
1760 break;
1761
1762
1763
1764 case 0xBC: //STOX ABSOLUTE
1765 HB = fetch();
1766 LB = fetch();
1767 address += (WORD)((WORD)HB << 8) + LB;
1768 if (address >= 0 && address < MEMORY_SIZE) {
1769 Memory[address] = Registers[REGISTER_A];
1770 }
1771 break;
1772
1773 case 0xCC: //STOX ABSOLUTE, X
1774 address += Index_Registers[REGISTER_X];
1775 HB = fetch();
1776 LB = fetch();
1777 address += (WORD)((WORD)HB << 8) + LB;
1778 if (address >= 0 && address < MEMORY_SIZE) {
1779 Memory[address] = Registers[REGISTER_A];
1780 }
1781 break;
1782
1783 case 0xDC: //STOX ABSOLUTE, Y
1784 address += Index_Registers[REGISTER_Y];
1785 HB = fetch();
1786 LB = fetch();
1787 address += (WORD)((WORD)HB << 8) + LB;
1788 if (address >= 0 && address < MEMORY_SIZE) {
1789 Memory[address] = Registers[REGISTER_A];
1790 }
1791 break;
1792
1793 case 0xEC: //STOX INDIRECT
1794 HB = fetch();
1795 LB = fetch();
1796 address = (WORD)((WORD)HB << 8) + LB;
1797 HB = Memory[address];
1798 LB = Memory[address + 1];
1799 address = (WORD)((WORD)HB << 8) + LB;
1800 if (address >= 0 && address < MEMORY_SIZE) {
1801 Memory[address] = Registers[REGISTER_A];
1802 }
1803 break;
1804
1805 case 0xFC: //STOX INDIRECT, X
1806 HB = fetch();
1807 LB = fetch();
1808 address = (WORD)((WORD)HB << 8) + LB;
1809 HB = Memory[address];
1810 LB = Memory[address + 1];
1811 address = (WORD)((WORD)HB << 8) + LB; address += Index_Registers[REGISTER_X];
1812 if (address >= 0 && address < MEMORY_SIZE) {
1813 Memory[address] = Registers[REGISTER_A];
1814 }
1815 break;
1816
1817
1818
1819 case 0x0F: //LDY Immidiate
1820 data = fetch(); Registers[REGISTER_A] = data;
1821 break;
1822
1823 case 0x1F: //LDY ABSOLUTE
1824 HB = fetch();
1825 LB = fetch();
1826 address += (WORD)((WORD)HB << 8) + LB;
1827 if (address >= 0 && address < MEMORY_SIZE) {
1828 Registers[REGISTER_A] = Memory[address];
1829 }
1830 break;
1831
1832 case 0x2F: //LDY INDEXED ABSOLUTE, X
1833 address += Index_Registers[REGISTER_X];
1834 HB = fetch();
1835 LB = fetch();
1836 address += (WORD)((WORD)HB << 8) + LB;
1837 if (address >= 0 && address < MEMORY_SIZE) {
1838 Registers[REGISTER_A] = Memory[address];
1839 }
1840 break;
1841
1842 case 0x3F: //LDY INDEXED ABSOLUTE, Y
1843 address += Index_Registers[REGISTER_Y];
1844 HB = fetch();
1845 LB = fetch();
1846 address += (WORD)((WORD)HB << 8) + LB;
1847 if (address >= 0 && address < MEMORY_SIZE) {
1848 Registers[REGISTER_A] = Memory[address];
1849 }
1850 break;
1851
1852 case 0x4F: //LDY INDIRECT
1853 HB = fetch();
1854 LB = fetch();
1855 address = (WORD)((WORD)HB << 8) + LB;
1856 HB = Memory[address];
1857 LB = Memory[address + 1];
1858 address = (WORD)((WORD)HB << 8) + LB;
1859 if (address >= 0 && address < MEMORY_SIZE) {
1860 Registers[REGISTER_A] = Memory[address];
1861 }
1862 break;
1863
1864 case 0x5F: //LDY INDIRECT, X
1865 HB = fetch();
1866 LB = fetch();
1867 address = (WORD)((WORD)HB << 8) + LB;
1868 HB = Memory[address];
1869 LB = Memory[address + 1];
1870 address = (WORD)((WORD)HB << 8) + LB; address += Index_Registers[REGISTER_X];
1871 if (address >= 0 && address < MEMORY_SIZE) {
1872 Registers[REGISTER_A] = Memory[address];
1873 }
1874 break;
1875
1876
1877
1878 case 0xBD: //STOY ABSOLUTE
1879 HB = fetch();
1880 LB = fetch();
1881 address += (WORD)((WORD)HB << 8) + LB;
1882 if (address >= 0 && address < MEMORY_SIZE) {
1883 Memory[address] = Registers[REGISTER_A];
1884 }
1885 break;
1886
1887 case 0xCD: //STOY ABSOLUTE, X
1888 address += Index_Registers[REGISTER_X];
1889 HB = fetch();
1890 LB = fetch();
1891 address += (WORD)((WORD)HB << 8) + LB;
1892 if (address >= 0 && address < MEMORY_SIZE) {
1893 Memory[address] = Registers[REGISTER_A];
1894 }
1895 break;
1896
1897 case 0xDD: //STOY ABSOLUTE, Y
1898 address += Index_Registers[REGISTER_Y];
1899 HB = fetch();
1900 LB = fetch();
1901 address += (WORD)((WORD)HB << 8) + LB;
1902 if (address >= 0 && address < MEMORY_SIZE) {
1903 Memory[address] = Registers[REGISTER_A];
1904 }
1905 break;
1906
1907 case 0xED: //STOY INDIRECT
1908 HB = fetch();
1909 LB = fetch();
1910 address = (WORD)((WORD)HB << 8) + LB;
1911 HB = Memory[address];
1912 LB = Memory[address + 1];
1913 address = (WORD)((WORD)HB << 8) + LB;
1914 if (address >= 0 && address < MEMORY_SIZE) {
1915 Memory[address] = Registers[REGISTER_A];
1916 }
1917 break;
1918
1919 case 0xFD: //STOY INDIRECT, X
1920 HB = fetch();
1921 LB = fetch();
1922 address = (WORD)((WORD)HB << 8) + LB;
1923 HB = Memory[address];
1924 LB = Memory[address + 1];
1925 address = (WORD)((WORD)HB << 8) + LB; address += Index_Registers[REGISTER_X];
1926 if (address >= 0 && address < MEMORY_SIZE) {
1927 Memory[address] = Registers[REGISTER_A];
1928 }
1929 break;
1930
1931
1932
1933 case 0x20: //LODS IMEDIATE
1934 data = fetch();
1935 StackPointer = data << 8; StackPointer += fetch();
1936 break;
1937
1938 case 0x30: //LODS ABSOLUTE
1939 HB = fetch();
1940 LB = fetch();
1941 address += (WORD)((WORD)HB << 8) + LB;
1942 if (address >= 0 && address < MEMORY_SIZE - 1) {
1943 StackPointer = (WORD)Memory[address] << 8;
1944 StackPointer += Memory[address + 1];
1945 }
1946 break;
1947
1948 case 0x40: //LODS ABSOLUTE X
1949 address += Index_Registers[REGISTER_X];
1950 HB = fetch();
1951 LB = fetch();
1952 address += (WORD)((WORD)HB << 8) + LB;
1953 if (address >= 0 && address < MEMORY_SIZE - 1) {
1954 StackPointer = (WORD)Memory[address] << 8;
1955 StackPointer += Memory[address + 1];
1956 }
1957 break;
1958
1959 case 0x50: //LODS ABSOLUTE Y
1960 address += Index_Registers[REGISTER_Y];
1961 HB = fetch();
1962 LB = fetch();
1963 address += (WORD)((WORD)HB << 8) + LB;
1964 if (address >= 0 && address < MEMORY_SIZE - 1) {
1965 StackPointer = (WORD)Memory[address] << 8;
1966 StackPointer += Memory[address + 1];
1967 }
1968 break;
1969
1970 case 0x60://LODS INDERECT
1971 HB = fetch();
1972 LB = fetch();
1973 address = (WORD)((WORD)HB << 8) + LB;
1974 HB = Memory[address];
1975 LB = Memory[address + 1];
1976 address = (WORD)((WORD)HB << 8) + LB;
1977 if (address >= 0 && address < MEMORY_SIZE - 1) {
1978 StackPointer = (WORD)Memory[address] << 8;
1979 StackPointer += Memory[address + 1];
1980 }
1981 break;
1982
1983 case 0x70://LODS INDIRECT X
1984 HB = fetch();
1985 LB = fetch();
1986 address = (WORD)((WORD)HB << 8) + LB;
1987 HB = Memory[address];
1988 LB = Memory[address + 1];
1989 address = (WORD)((WORD)HB << 8) + LB;
1990 address += Index_Registers[REGISTER_X];
1991 if (address >= 0 && address < MEMORY_SIZE - 1) {
1992 StackPointer = (WORD)Memory[address] << 8;
1993 StackPointer += Memory[address + 1];
1994 }
1995 break;
1996
1997
1998
1999
2000 case 0x6A: //STOS ABSOLUTE
2001 HB = fetch();
2002 LB = fetch();
2003 address += (WORD)((WORD)HB << 8) + LB;
2004 if (address >= 0 && address < MEMORY_SIZE) {
2005 Memory[address] = Registers[REGISTER_A];
2006 }
2007 break;
2008
2009 case 0x7A: //STOS ABSOLUTE, X
2010 address += Index_Registers[REGISTER_X];
2011 HB = fetch();
2012 LB = fetch();
2013 address += (WORD)((WORD)HB << 8) + LB;
2014 if (address >= 0 && address < MEMORY_SIZE) {
2015 Memory[address] = Registers[REGISTER_A];
2016 }
2017 break;
2018
2019 case 0x8A: //STOS ABSOLUTE, Y
2020 address += Index_Registers[REGISTER_Y];
2021 HB = fetch();
2022 LB = fetch();
2023 address += (WORD)((WORD)HB << 8) + LB;
2024 if (address >= 0 && address < MEMORY_SIZE) {
2025 Memory[address] = Registers[REGISTER_A];
2026 }
2027 break;
2028
2029 case 0x9A: //STOS INDIRECT
2030 HB = fetch();
2031 LB = fetch();
2032 address = (WORD)((WORD)HB << 8) + LB;
2033 HB = Memory[address];
2034 LB = Memory[address + 1];
2035 address = (WORD)((WORD)HB << 8) + LB;
2036 if (address >= 0 && address < MEMORY_SIZE) {
2037 Memory[address] = Registers[REGISTER_A];
2038 }
2039 break;
2040
2041 case 0xAA: //STOS INDIRECT, X
2042 HB = fetch();
2043 LB = fetch();
2044 address = (WORD)((WORD)HB << 8) + LB;
2045 HB = Memory[address];
2046 LB = Memory[address + 1];
2047 address = (WORD)((WORD)HB << 8) + LB; address += Index_Registers[REGISTER_X];
2048 if (address >= 0 && address < MEMORY_SIZE) {
2049 Memory[address] = Registers[REGISTER_A];
2050 }
2051 break;
2052
2053
2054
2055 case 0xF2: //CSA IMPLIED
2056 Registers[REGISTER_A] = Flags;
2057 break;
2058
2059
2060 case 0xBE: //PUSH A
2061 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2062 Memory[StackPointer] = Registers[REGISTER_A];
2063 StackPointer--;
2064 }
2065 break;
2066
2067 case 0xCE: //PUSH B
2068 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2069 Memory[StackPointer] = Registers[REGISTER_B];
2070 StackPointer--;
2071 }
2072 break;
2073
2074 case 0xDE: //PUSH FLAGS
2075 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2076 Memory[StackPointer] = Registers[Flags];
2077 StackPointer--;
2078 }
2079 break;
2080
2081 case 0xEE: //PUSH L
2082 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2083 Memory[StackPointer] = Registers[REGISTER_L];
2084 StackPointer--;
2085 }
2086 break;
2087
2088 case 0xFE: //PUSH H
2089 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2090 Memory[StackPointer] = Registers[REGISTER_H];
2091 StackPointer--;
2092 }
2093 break;
2094
2095
2096
2097 case 0xBF: //POP A
2098 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2099 StackPointer++;
2100 Registers[REGISTER_A] = Memory[StackPointer];
2101 }
2102 break;
2103
2104 case 0xCF: //POP B
2105 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2106 StackPointer++;
2107 Registers[REGISTER_B] = Memory[StackPointer];
2108 }
2109 break;
2110
2111 case 0xDF: //POP FLAGS
2112 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2113 StackPointer++;
2114 Registers[Flags] = Memory[StackPointer];
2115 }
2116 break;
2117
2118 case 0xEF: //POP L
2119 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2120 StackPointer++;
2121 Registers[REGISTER_L] = Memory[StackPointer];
2122 }
2123 break;
2124
2125 case 0xFF: //POP H
2126 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2127 StackPointer++;
2128 Registers[REGISTER_H] = Memory[StackPointer];
2129 }
2130 break;
2131
2132
2133
2134 case 0x0c: //LX LH Immidiate
2135 data = fetch();
2136 Registers[REGISTER_H] = data;
2137 data = fetch();
2138 Registers[REGISTER_L] = data;
2139 break;
2140
2141 case 0x0d: //LX LH Immidiate
2142 data = fetch();
2143 Registers[REGISTER_H] = data;
2144 data = fetch();
2145 Registers[REGISTER_L] = data;
2146 break;
2147
2148
2149
2150 case 0x10: //JMP abs
2151 HB = fetch();
2152 LB = fetch();
2153 address = ((WORD)HB << 8) + (WORD)LB;
2154 ProgramCounter = address;
2155 break;
2156
2157
2158
2159 case 0xF3: //ABA
2160 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_A];
2161 if (temp_word >= 100) {
2162 Flags - Flags | FLAG_C; //set carryflag
2163 }
2164 else {
2165 Flags - Flags&(0xFF - FLAG_C); //clear flag
2166 }
2167 set_flag_z((BYTE)temp_word);
2168 set_flag_n((BYTE)temp_word);
2169 Registers[REGISTER_A] = (BYTE)temp_word;
2170 break;
2171
2172
2173
2174 case 0xF4: //SBA
2175 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
2176 if (temp_word >= 100) {
2177 Flags - Flags | FLAG_C; //set carryflag
2178 }
2179 else {
2180 Flags - Flags&(0xFF - FLAG_C); //clear flag
2181 }
2182 set_flag_z((BYTE)temp_word);
2183 set_flag_n((BYTE)temp_word);
2184 Registers[REGISTER_A] = (BYTE)temp_word;
2185 break;
2186
2187
2188
2189 case 0xF5: //AAB
2190 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
2191 if (temp_word >= 100) {
2192 Flags - Flags | FLAG_C; //set carryflag
2193 }
2194 else {
2195 Flags - Flags&(0xFF - FLAG_C); //clear flag
2196 }
2197 set_flag_z((BYTE)temp_word);
2198 set_flag_n((BYTE)temp_word);
2199 Registers[REGISTER_A] = (BYTE)temp_word;
2200 break;
2201
2202
2203 //SAB: Subtract accumulator A form Accumulator B
2204 case 0xF6: //SAB
2205 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_A];
2206 if (temp_word >= 100) {
2207 Flags - Flags | FLAG_C; //set carryflag
2208 }
2209 else {
2210 Flags - Flags&(0xFF - FLAG_C); //clear flag
2211 }
2212 set_flag_z((BYTE)temp_word);
2213 set_flag_n((BYTE)temp_word);
2214 Registers[REGISTER_A] = (BYTE)temp_word;
2215 break;
2216
2217
2218 //MVI: Loads memory into register
2219 case 0x1C: //MVI IMEDIATE
2220 data = fetch(); Registers[REGISTER_L] = data;
2221 break;
2222
2223 case 0x1D: //MVI IMIDIATE
2224 data = fetch(); Registers[REGISTER_H] = data;
2225 break;
2226
2227
2228 //JSR: Jump to subroutine
2229 case 0x21: //JSR
2230 HB = fetch();
2231 LB = fetch();
2232 address = ((WORD)HB << 8) + (WORD)LB;
2233 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
2234 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF); StackPointer--;
2235 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF); StackPointer--;
2236 ProgramCounter = address;
2237 }
2238
2239 //RET: Return from subroutine
2240 case 0x4C: //RET
2241 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
2242 StackPointer++;
2243 HB = Memory[StackPointer];
2244 StackPointer++;
2245 LB = Memory[StackPointer];
2246 }
2247 ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
2248 break;
2249
2250
2251 //JCS: Jump on Carry set
2252 case 0x12: // JCS
2253 HB = fetch();
2254 LB = fetch();
2255 address = (WORD)((WORD)HB << 8) + LB;
2256 if ((Flags & FLAG_C) != 0) {
2257 ProgramCounter = address;
2258 }
2259 break;
2260
2261
2262 //JNE: Jump on result not Zero
2263 case 0x13: //JNE
2264 HB = fetch();
2265 LB = fetch();
2266 address = ((WORD)HB << 8) + (WORD)LB;
2267 if ((Flags&FLAG_Z) == 0) {
2268 ProgramCounter = address;
2269 }
2270 break;
2271
2272
2273 //JEQ: Jump on result equal to Zero
2274 case 0x14: //JEQ
2275 HB = fetch();
2276 LB = fetch();
2277 address = ((WORD)HB << 8) + (WORD)LB;
2278 if ((Flags&FLAG_Z) == FLAG_Z) {
2279 ProgramCounter = address;
2280 }
2281 break;
2282
2283
2284
2285 //JMI: Jump on negative result
2286 case 0x15: // JMI
2287 HB = fetch();
2288 LB = fetch();
2289 address = ((WORD)HB << 8) + (WORD)LB;
2290 if ((Flags & FLAG_Z) < 0)
2291 {
2292 ProgramCounter = address;
2293 }
2294 break;
2295
2296
2297 //STC: Set Carry flag
2298 case 0x06: //STC
2299 Flags = Flags | FLAG_C;
2300 break;
2301
2302
2303 //STI: Set Interupt flag
2304 case 0x08: //STI
2305 Flags = Flags | FLAG_I;
2306 break;
2307 }
2308
2309
2310
2311
2312
2313
2314}
2315
2316
2317void Group_2_Move(BYTE opcode)
2318{
2319 /*
2320 MOVE is like a grid/block
2321 We can untilise this to make our lives simpler
2322 */
2323
2324 //store low nibble and high nibble
2325 //low nibble = source = original location to swap
2326 //high nibble = dest = new location of where swapped
2327 BYTE dest = opcode & 0x0F; //get the last 4 bits --> xxxxyyyy becomes 0000yyyy
2328 BYTE source = opcode & 0xF0; //get the front 4 bits ---> xxxxyyyy becomes 0000xxxx
2329
2330 //temp vars for registers
2331 int destReg = 0, sourceReg = 0;
2332
2333 //address for memory
2334 WORD address;
2335
2336 {
2337
2338 BYTE *registers[] = {
2339
2340 &Registers[REGISTER_A],
2341
2342 &Registers[REGISTER_B],
2343
2344 &Registers[REGISTER_L],
2345
2346 &Registers[REGISTER_H],
2347
2348 &Registers[REGISTER_M]
2349
2350 };
2351
2352
2353
2354 int source = (opcode >> 4) - 0x6;
2355
2356 int dest = (opcode & 0x0F) - 0xB;
2357
2358
2359
2360 *registers[dest] = *registers[source];
2361
2362 }
2363
2364 switch (dest) {
2365 case 0x0B:
2366 destReg = REGISTER_A;
2367 break;
2368 case 0x0C:
2369 destReg = REGISTER_B;
2370 break;
2371 case 0x0D:
2372 destReg = REGISTER_L;
2373 break;
2374 case 0x0E:
2375 destReg = REGISTER_H;
2376 break;
2377 case 0x0F:
2378 destReg = REGISTER_M;
2379 break;
2380 default:
2381 break;
2382 }
2383
2384 switch (source)
2385 {
2386 case 0x60:
2387 sourceReg = REGISTER_A;
2388 break;
2389 case 0x70:
2390 sourceReg = REGISTER_B;
2391 break;
2392 case 0x80:
2393 sourceReg = REGISTER_L;
2394 break;
2395 case 0x90:
2396 sourceReg = REGISTER_H;
2397 break;
2398 case 0xA0:
2399 sourceReg = REGISTER_M;
2400 break;
2401 default:
2402 break;
2403 }
2404
2405 //if ((destReg != REGISTER_M) && (sourceReg != REGISTER_M)) {
2406
2407 if (destReg == REGISTER_M) {
2408 address = Registers[REGISTER_L];
2409 address += (WORD)Registers[REGISTER_H] << 4;
2410 if (address >= 0 && address <= MEMORY_SIZE) {
2411 Memory[address] = Registers[sourceReg];
2412 }
2413 }
2414 else {
2415 //do the swap
2416 Registers[destReg] = Registers[sourceReg];
2417 }
2418
2419 if (sourceReg == REGISTER_M) {
2420 address = Registers[REGISTER_L];
2421 address += (WORD)Registers[REGISTER_H] << 4;
2422 if (address >= 0 && address <= MEMORY_SIZE) {
2423 Memory[address] = Registers[sourceReg];
2424 }
2425 }
2426 else {
2427 //do the swap
2428 Registers[destReg] = Registers[sourceReg];
2429 }
2430}
2431
2432
2433void execute(BYTE opcode)
2434{
2435
2436 if (((opcode >= 0x6B) && (opcode <= 0x6F))
2437 || ((opcode >= 0x7B) && (opcode <= 0x7F))
2438 || ((opcode >= 0x8B) && (opcode <= 0x8F))
2439 || ((opcode >= 0x9B) && (opcode <= 0x9F))
2440 || ((opcode >= 0xAB) && (opcode <= 0xAF)))
2441 {
2442 Group_2_Move(opcode);
2443 }
2444 else
2445 {
2446 Group_1(opcode);
2447 }
2448}
2449
2450
2451void emulate()
2452{
2453 BYTE opcode;
2454 int sanity;
2455
2456 ProgramCounter = 0;
2457 halt = false;
2458 memory_in_range = true;
2459 sanity = 0;
2460
2461 printf(" A B L H X Y SP\n");
2462
2463 while ((!halt) && (memory_in_range) && (sanity < 200))
2464 {
2465 printf("%04X ", ProgramCounter); // Print current address
2466 opcode = fetch();
2467 execute(opcode);
2468
2469 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
2470
2471 printf("%02X ", Registers[REGISTER_A]);
2472 printf("%02X ", Registers[REGISTER_B]);
2473 printf("%02X ", Registers[REGISTER_L]);
2474 printf("%02X ", Registers[REGISTER_H]);
2475 printf("%02X ", Index_Registers[REGISTER_X]);
2476 printf("%02X ", Index_Registers[REGISTER_Y]);
2477 printf("%04X ", StackPointer); // Print Stack Pointer
2478
2479 if ((Flags & FLAG_I) == FLAG_I)
2480 {
2481 printf("I=1 ");
2482 }
2483 else
2484 {
2485 printf("I=0 ");
2486 }
2487 if ((Flags & FLAG_Z) == FLAG_Z)
2488 {
2489 printf("Z=1 ");
2490 }
2491 else
2492 {
2493 printf("Z=0 ");
2494 }
2495 if ((Flags & FLAG_N) == FLAG_N)
2496 {
2497 printf("N=1 ");
2498 }
2499 else
2500 {
2501 printf("N=0 ");
2502 }
2503 if ((Flags & FLAG_C) == FLAG_C)
2504 {
2505 printf("C=1 ");
2506 }
2507 else
2508 {
2509 printf("C=0 ");
2510 }
2511
2512 printf("\n"); // New line
2513 sanity++;
2514 }
2515
2516 printf("\n"); // New line
2517}
2518
2519
2520////////////////////////////////////////////////////////////////////////////////
2521// Simulator/Emulator (End) //
2522////////////////////////////////////////////////////////////////////////////////
2523
2524
2525void initialise_filenames() {
2526 int i;
2527
2528 for (i = 0; i<MAX_FILENAME_SIZE; i++) {
2529 hex_file[i] = '\0';
2530 trc_file[i] = '\0';
2531 }
2532}
2533
2534
2535
2536
2537int find_dot_position(char *filename) {
2538 int dot_position;
2539 int i;
2540 char chr;
2541
2542 dot_position = 0;
2543 i = 0;
2544 chr = filename[i];
2545
2546 while (chr != '\0') {
2547 if (chr == '.') {
2548 dot_position = i;
2549 }
2550 i++;
2551 chr = filename[i];
2552 }
2553
2554 return (dot_position);
2555}
2556
2557
2558int find_end_position(char *filename) {
2559 int end_position;
2560 int i;
2561 char chr;
2562
2563 end_position = 0;
2564 i = 0;
2565 chr = filename[i];
2566
2567 while (chr != '\0') {
2568 end_position = i;
2569 i++;
2570 chr = filename[i];
2571 }
2572
2573 return (end_position);
2574}
2575
2576
2577bool file_exists(char *filename) {
2578 bool exists;
2579 FILE *ifp;
2580
2581 exists = false;
2582
2583 if ((ifp = fopen(filename, "r")) != NULL)
2584 {
2585 exists = true;
2586
2587 fclose(ifp);
2588 }
2589
2590 return (exists);
2591}
2592
2593
2594
2595void create_file(char *filename) {
2596 FILE *ofp;
2597
2598 if ((ofp = fopen(filename, "w")) != NULL) {
2599 fclose(ofp);
2600 }
2601}
2602
2603
2604
2605bool getline(FILE *fp, char *buffer) {
2606 bool rc;
2607 bool collect;
2608 char c;
2609 int i;
2610
2611 rc = false;
2612 collect = true;
2613
2614 i = 0;
2615 while (collect) {
2616 c = getc(fp);
2617
2618 switch (c) {
2619 case EOF:
2620 if (i > 0) {
2621 rc = true;
2622 }
2623 collect = false;
2624 break;
2625
2626 case '\n':
2627 if (i > 0) {
2628 rc = true;
2629 collect = false;
2630 buffer[i] = '\0';
2631 }
2632 break;
2633
2634 default:
2635 buffer[i] = c;
2636 i++;
2637 break;
2638 }
2639 }
2640
2641 return (rc);
2642}
2643
2644
2645
2646
2647
2648
2649void load_and_run(int args, _TCHAR** argv) {
2650 char chr;
2651 int ln;
2652 int dot_position;
2653 int end_position;
2654 long i;
2655 FILE *ifp;
2656 long address;
2657 long load_at;
2658 int code;
2659
2660 // Prompt for the .hex file
2661
2662 printf("\n");
2663 printf("Enter the hex filename (.hex): ");
2664
2665 if (args == 2) {
2666 ln = 0;
2667 chr = argv[1][ln];
2668 while (chr != '\0')
2669 {
2670 if (ln < MAX_FILENAME_SIZE)
2671 {
2672 hex_file[ln] = chr;
2673 trc_file[ln] = chr;
2674 ln++;
2675 }
2676 chr = argv[1][ln];
2677 }
2678 }
2679 else {
2680 ln = 0;
2681 chr = '\0';
2682 while (chr != '\n') {
2683 chr = getchar();
2684
2685 switch (chr) {
2686 case '\n':
2687 break;
2688 default:
2689 if (ln < MAX_FILENAME_SIZE) {
2690 hex_file[ln] = chr;
2691 trc_file[ln] = chr;
2692 ln++;
2693 }
2694 break;
2695 }
2696 }
2697
2698 }
2699 // Tidy up the file names
2700
2701 dot_position = find_dot_position(hex_file);
2702 if (dot_position == 0) {
2703 end_position = find_end_position(hex_file);
2704
2705 hex_file[end_position + 1] = '.';
2706 hex_file[end_position + 2] = 'h';
2707 hex_file[end_position + 3] = 'e';
2708 hex_file[end_position + 4] = 'x';
2709 hex_file[end_position + 5] = '\0';
2710 }
2711 else {
2712 hex_file[dot_position + 0] = '.';
2713 hex_file[dot_position + 1] = 'h';
2714 hex_file[dot_position + 2] = 'e';
2715 hex_file[dot_position + 3] = 'x';
2716 hex_file[dot_position + 4] = '\0';
2717 }
2718
2719 dot_position = find_dot_position(trc_file);
2720 if (dot_position == 0) {
2721 end_position = find_end_position(trc_file);
2722
2723 trc_file[end_position + 1] = '.';
2724 trc_file[end_position + 2] = 't';
2725 trc_file[end_position + 3] = 'r';
2726 trc_file[end_position + 4] = 'c';
2727 trc_file[end_position + 5] = '\0';
2728 }
2729 else {
2730 trc_file[dot_position + 0] = '.';
2731 trc_file[dot_position + 1] = 't';
2732 trc_file[dot_position + 2] = 'r';
2733 trc_file[dot_position + 3] = 'c';
2734 trc_file[dot_position + 4] = '\0';
2735 }
2736
2737 if (file_exists(hex_file)) {
2738 // Clear Registers and Memory
2739
2740 Registers[REGISTER_A] = 0;
2741 Registers[REGISTER_B] = 0;
2742 Registers[REGISTER_L] = 0;
2743 Registers[REGISTER_H] = 0;
2744 Index_Registers[REGISTER_X] = 0;
2745 Index_Registers[REGISTER_Y] = 0;
2746 Flags = 0;
2747 ProgramCounter = 0;
2748 StackPointer = 0;
2749
2750 for (i = 0; i<MEMORY_SIZE; i++) {
2751 Memory[i] = 0x00;
2752 }
2753
2754 // Load hex file
2755
2756 if ((ifp = fopen(hex_file, "r")) != NULL) {
2757 printf("Loading file...\n\n");
2758
2759 load_at = 0;
2760
2761 while (getline(ifp, InputBuffer)) {
2762 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
2763 load_at = address;
2764 }
2765 else if (sscanf(InputBuffer, "%x", &code) == 1) {
2766 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
2767 Memory[load_at] = (BYTE)code;
2768 }
2769 load_at++;
2770 }
2771 else {
2772 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
2773 }
2774 }
2775
2776 fclose(ifp);
2777 }
2778
2779 // Emulate
2780
2781 emulate();
2782 }
2783 else {
2784 printf("\n");
2785 printf("ERROR> Input file %s does not exist!\n", hex_file);
2786 printf("\n");
2787 }
2788}
2789
2790void building(int args, _TCHAR** argv)
2791{
2792 char buffer[1024];
2793 load_and_run(args, argv);
2794 sprintf(buffer, "0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X",
2795 Memory[TEST_ADDRESS_1],
2796 Memory[TEST_ADDRESS_2],
2797 Memory[TEST_ADDRESS_3],
2798 Memory[TEST_ADDRESS_4],
2799 Memory[TEST_ADDRESS_5],
2800 Memory[TEST_ADDRESS_6],
2801 Memory[TEST_ADDRESS_7],
2802 Memory[TEST_ADDRESS_8],
2803 Memory[TEST_ADDRESS_9],
2804 Memory[TEST_ADDRESS_10],
2805 Memory[TEST_ADDRESS_11],
2806 Memory[TEST_ADDRESS_12]
2807 );
2808 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2809}
2810
2811
2812
2813void test_and_mark() {
2814 char buffer[1024];
2815 bool testing_complete;
2816 int len = sizeof(SOCKADDR);
2817 char chr;
2818 int i;
2819 int j;
2820 bool end_of_program;
2821 long address;
2822 long load_at;
2823 int code;
2824 int mark;
2825 int passed;
2826
2827 printf("\n");
2828 printf("Automatic Testing and Marking\n");
2829 printf("\n");
2830
2831 testing_complete = false;
2832
2833 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
2834 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2835
2836 while (!testing_complete) {
2837 memset(buffer, '\0', sizeof(buffer));
2838
2839 if (recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
2840 printf("Incoming Data: %s \n", buffer);
2841
2842 //if (strcmp(buffer, "Testing complete") == 1)
2843 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
2844 testing_complete = true;
2845 printf("Current mark = %d\n", mark);
2846
2847 }
2848 else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
2849 //testing_complete = true;
2850 printf("Passed = %d\n", passed);
2851
2852 }
2853 else if (strcmp(buffer, "Error") == 0) {
2854 printf("ERROR> Testing abnormally terminated\n");
2855 testing_complete = true;
2856 }
2857 else {
2858 // Clear Registers and Memory
2859
2860 Registers[REGISTER_A] = 0;
2861 Registers[REGISTER_B] = 0;
2862 Registers[REGISTER_L] = 0;
2863 Registers[REGISTER_H] = 0;
2864 Index_Registers[REGISTER_X] = 0;
2865 Index_Registers[REGISTER_Y] = 0;
2866 Flags = 0;
2867 ProgramCounter = 0;
2868 StackPointer = 0;
2869 for (i = 0; i<MEMORY_SIZE; i++) {
2870 Memory[i] = 0;
2871 }
2872
2873 // Load hex file
2874
2875 i = 0;
2876 j = 0;
2877 load_at = 0;
2878 end_of_program = false;
2879 FILE *ofp;
2880 fopen_s(&ofp, "branch.txt", "a");
2881
2882 while (!end_of_program) {
2883 chr = buffer[i];
2884 switch (chr) {
2885 case '\0':
2886 end_of_program = true;
2887
2888 case ',':
2889 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
2890 load_at = address;
2891 }
2892 else if (sscanf(InputBuffer, "%x", &code) == 1) {
2893 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
2894 Memory[load_at] = (BYTE)code;
2895 fprintf(ofp, "%02X\n", (BYTE)code);
2896 }
2897 load_at++;
2898 }
2899 else {
2900 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
2901 }
2902 j = 0;
2903 break;
2904
2905 default:
2906 InputBuffer[j] = chr;
2907 j++;
2908 break;
2909 }
2910 i++;
2911 }
2912 fclose(ofp);
2913 // Emulate
2914
2915 if (load_at > 1) {
2916 emulate();
2917 // Send and store results
2918 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
2919 Memory[TEST_ADDRESS_1],
2920 Memory[TEST_ADDRESS_2],
2921 Memory[TEST_ADDRESS_3],
2922 Memory[TEST_ADDRESS_4],
2923 Memory[TEST_ADDRESS_5],
2924 Memory[TEST_ADDRESS_6],
2925 Memory[TEST_ADDRESS_7],
2926 Memory[TEST_ADDRESS_8],
2927 Memory[TEST_ADDRESS_9],
2928 Memory[TEST_ADDRESS_10],
2929 Memory[TEST_ADDRESS_11],
2930 Memory[TEST_ADDRESS_12]
2931 );
2932 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2933 }
2934 }
2935 }
2936 }
2937}
2938
2939
2940
2941int _tmain(int argc, _TCHAR* argv[])
2942{
2943 char chr;
2944 char dummy;
2945
2946 printf("\n");
2947 printf("Microprocessor Emulator\n");
2948 printf("UWE Computer and Network Systems Assignment 1\n");
2949 printf("\n");
2950
2951 initialise_filenames();
2952
2953 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
2954
2955 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
2956 if (!sock) {
2957 // Creation failed!
2958 }
2959
2960 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
2961 server_addr.sin_family = AF_INET;
2962 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
2963 server_addr.sin_port = htons(PORT_SERVER);
2964
2965 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
2966 client_addr.sin_family = AF_INET;
2967 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
2968 client_addr.sin_port = htons(PORT_CLIENT);
2969
2970 chr = '\0';
2971 while ((chr != 'e') && (chr != 'E'))
2972 {
2973 printf("\n");
2974 printf("Please select option\n");
2975 printf("L - Load and run a hex file\n");
2976 printf("T - Have the server test and mark your emulator\n");
2977 printf("E - Exit\n");
2978 if (argc == 2) { building(argc, argv); exit(0); }
2979 printf("Enter option: ");
2980 chr = getchar();
2981 if (chr != 0x0A)
2982 {
2983 dummy = getchar(); // read in the <CR>
2984 }
2985 printf("\n");
2986
2987 switch (chr)
2988 {
2989 case 'L':
2990 case 'l':
2991 load_and_run(argc, argv);
2992 break;
2993
2994 case 'T':
2995 case 't':
2996 test_and_mark();
2997 break;
2998
2999 default:
3000 break;
3001 }
3002 }
3003
3004 closesocket(sock);
3005 WSACleanup();
3006
3007
3008 return 0;
3009}