· 9 years ago · Oct 25, 2016, 09:34 AM
1
2
3#include "stdafx.h"
4#include <winsock2.h>
5
6#pragma comment(lib, "wsock32.lib")
7
8
9#define STUDENT_NUMBER "12016822"
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#define MAX_FILENAME_SIZE 500
21#define MAX_BUFFER_SIZE 500
22
23SOCKADDR_IN server_addr;
24SOCKADDR_IN client_addr;
25
26SOCKET sock; // This is our socket, it is the handle to the IO address to read/write packets
27
28WSADATA data;
29
30char InputBuffer [MAX_BUFFER_SIZE];
31
32char hex_file [MAX_BUFFER_SIZE];
33char trc_file [MAX_BUFFER_SIZE];
34
35//////////////////////////
36// Registers //
37//////////////////////////
38
39#define FLAG_I 0x10
40#define FLAG_Z 0x04
41#define FLAG_N 0x02
42#define FLAG_C 0x01
43#define REGISTER_M 4
44#define REGISTER_A 3
45#define REGISTER_B 2
46#define REGISTER_H 1
47#define REGISTER_L 0
48#define REGISTER_X 0
49#define REGISTER_Y 1
50BYTE Index_Registers[2];
51
52BYTE Registers[5];
53BYTE Flags;
54WORD ProgramCounter;
55WORD StackPointer;
56
57
58////////////
59// Memory //
60////////////
61
62#define MEMORY_SIZE 65536
63
64BYTE Memory[MEMORY_SIZE];
65
66#define TEST_ADDRESS_1 0x01FA
67#define TEST_ADDRESS_2 0x01FB
68#define TEST_ADDRESS_3 0x01FC
69#define TEST_ADDRESS_4 0x01FD
70#define TEST_ADDRESS_5 0x01FE
71#define TEST_ADDRESS_6 0x01FF
72#define TEST_ADDRESS_7 0x0200
73#define TEST_ADDRESS_8 0x0201
74#define TEST_ADDRESS_9 0x0202
75#define TEST_ADDRESS_10 0x0203
76#define TEST_ADDRESS_11 0x0204
77#define TEST_ADDRESS_12 0x0205
78
79
80///////////////////////
81// Control variables //
82///////////////////////
83
84bool memory_in_range = true;
85bool halt = false;
86
87
88///////////////////////
89// Disassembly table //
90///////////////////////
91
92char opcode_mneumonics[][14] =
93{
94"ILLEGAL ",
95"DECX impl ",
96"INCX impl ",
97"DEY impl ",
98"INCY impl ",
99"CLC impl ",
100"STC impl ",
101"CLI impl ",
102"STI impl ",
103"ILLEGAL ",
104"LDAA # ",
105"LDAB # ",
106"LX #,L ",
107"LX #,L ",
108"LDX # ",
109"LDY # ",
110
111"JMP abs ",
112"JCC abs ",
113"JCS abs ",
114"JNE abs ",
115"JEQ abs ",
116"JMI abs ",
117"JPL abs ",
118"JHI abs ",
119"JLE abs ",
120"ILLEGAL ",
121"LDAA abs ",
122"LDAB abs ",
123"MVI #,L ",
124"MVI #,H ",
125"LDX abs ",
126"LDY abs ",
127
128"LODS # ",
129"JSR abs ",
130"CCC abs ",
131"CCS abs ",
132"CNE abs ",
133"CEQ abs ",
134"CMI abs ",
135"CPL abs ",
136"CHI abs ",
137"CLE abs ",
138"LDAA abs,X ",
139"LDAB abs,X ",
140"NOP impl ",
141"HLT impl ",
142"LDX abs,X ",
143"LDY abs,X ",
144
145"LODS abs ",
146"ADC A,L ",
147"SBC A,L ",
148"ADD A,L ",
149"SUB A,L ",
150"CMP A,L ",
151"OR A,L ",
152"AND A,L ",
153"XOR A,L ",
154"BIT A,L ",
155"LDAA abs,Y ",
156"LDAB abs,Y ",
157"ILLEGAL ",
158"ILLEGAL ",
159"LDX abs,Y ",
160"LDY abs,Y ",
161
162"LODS abs,X ",
163"ADC A,H ",
164"SBC A,H ",
165"ADD A,H ",
166"SUB A,H ",
167"CMP A,H ",
168"OR A,H ",
169"AND A,H ",
170"XOR A,H ",
171"BIT A,H ",
172"LDAA (ind) ",
173"LDAB (ind) ",
174"RET impl ",
175"ILLEGAL ",
176"LDX (ind) ",
177"LDY (ind) ",
178
179"LODS abs,Y ",
180"ADC A,M ",
181"SBC A,M ",
182"ADD A,M ",
183"SUB A,M ",
184"CMP A,M ",
185"OR A,M ",
186"AND A,M ",
187"XOR A,M ",
188"BIT A,M ",
189"LDAA (ind,X) ",
190"LDAB (ind,X) ",
191"SWI impl ",
192"RTI impl ",
193"LDX (ind,X) ",
194"LDY (ind,X) ",
195
196"LODS (ind) ",
197"ADC B,L ",
198"SBC B,L ",
199"ADD B,L ",
200"SUB B,L ",
201"CMP B,L ",
202"OR B,L ",
203"AND B,L ",
204"XOR B,L ",
205"BIT B,L ",
206"STOS abs ",
207"MOVE A,A ",
208"MOVE B,A ",
209"MOVE L,A ",
210"MOVE H,A ",
211"MOVE M,A ",
212
213"LODS (ind,X) ",
214"ADC B,H ",
215"SBC B,H ",
216"ADD B,H ",
217"SUB B,H ",
218"CMP B,H ",
219"OR B,H ",
220"AND B,H ",
221"XOR B,H ",
222"BIT B,H ",
223"STOS abs,X ",
224"MOVE A,B ",
225"MOVE B,B ",
226"MOVE L,B ",
227"MOVE H,B ",
228"MOVE M,B ",
229
230"ILLEGAL ",
231"ADC B,M ",
232"SBC B,M ",
233"ADD B,M ",
234"SUB B,M ",
235"CMP B,M ",
236"OR B,M ",
237"AND B,M ",
238"XOR B,M ",
239"BIT B,M ",
240"STOS abs,Y ",
241"MOVE A,L ",
242"MOVE B,L ",
243"MOVE L,L ",
244"MOVE H,L ",
245"MOVE M,L ",
246
247"ILLEGAL ",
248"ILLEGAL ",
249"ILLEGAL ",
250"SBIA # ",
251"SBIB # ",
252"CPIA # ",
253"CPIB # ",
254"ORIA # ",
255"ORIB # ",
256"ILLEGAL ",
257"STOS (ind) ",
258"MOVE A,H ",
259"MOVE B,H ",
260"MOVE L,H ",
261"MOVE H,H ",
262"MOVE M,H ",
263
264"INC abs ",
265"DEC abs ",
266"RRC abs ",
267"RLC abs ",
268"SAL abs ",
269"SAR abs ",
270"LSR abs ",
271"COM abs ",
272"ROL abs ",
273"RR abs ",
274"STOS (ind,X) ",
275"MOVE A,M ",
276"MOVE B,M ",
277"MOVE L,M ",
278"MOVE H,M ",
279"MOVE -,- ",
280
281"INC abs,X ",
282"DEC abs,X ",
283"RRC abs,X ",
284"RLC abs,X ",
285"SAL abs,X ",
286"SAR abs,X ",
287"LSR abs,X ",
288"COM abs,X ",
289"ROL abs,X ",
290"RR abs,X ",
291"STORA abs ",
292"STORB abs ",
293"STOX abs ",
294"STOY abs ",
295"PUSH ,A ",
296"POP A, ",
297
298"INC abs,Y ",
299"DEC abs,Y ",
300"RRC abs,Y ",
301"RLC abs,Y ",
302"SAL abs,Y ",
303"SAR abs,Y ",
304"LSR abs,Y ",
305"COM abs,Y ",
306"ROL abs,Y ",
307"RR abs,Y ",
308"STORA abs,X ",
309"STORB abs,X ",
310"STOX abs,X ",
311"STOY abs,X ",
312"PUSH ,B ",
313"POP B, ",
314
315"INCA A,A ",
316"DECA A,A ",
317"RRCA A,A ",
318"RLCA A,A ",
319"SALA A,A ",
320"SARA A,A ",
321"LSRA A,A ",
322"COMA A,A ",
323"ROLA A,A ",
324"RRA A,A ",
325"STORA abs,Y ",
326"STORB abs,Y ",
327"STOX abs,Y ",
328"STOY abs,Y ",
329"PUSH ,s ",
330"POP s, ",
331
332"INCB B,B ",
333"DECB B,B ",
334"RRCB B,B ",
335"RLCB B,B ",
336"SALB B,B ",
337"SARB B,B ",
338"LSRB B,B ",
339"COMB B,B ",
340"ROLB B,B ",
341"RRB B,B ",
342"STORA (ind) ",
343"STORB (ind) ",
344"STOX (ind) ",
345"STOY (ind) ",
346"PUSH ,L ",
347"POP L, ",
348
349"CAY impl ",
350"MYA impl ",
351"CSA impl ",
352"ABA impl ",
353"SBA impl ",
354"AAB impl ",
355"SAB impl ",
356"ADCP A,L ",
357"SBCP A,L ",
358"XCHG A,L ",
359"STORA (ind,X)",
360"STORB (ind,X)",
361"STOX (ind,X) ",
362"STOY (ind,X) ",
363"PUSH ,H ",
364"POP H, ",
365
366};
367
368////////////////////////////////////////////////////////////////////////////////
369// Simulator/Emulator (Start) //
370////////////////////////////////////////////////////////////////////////////////
371BYTE fetch()
372{
373 BYTE byte = 0;
374
375 if ((ProgramCounter >= 0) && (ProgramCounter <= MEMORY_SIZE))
376 {
377 memory_in_range = true;
378 byte = Memory[ProgramCounter];
379 ProgramCounter++;
380 }
381 else
382 {
383 memory_in_range = false;
384 }
385 return byte;
386}
387void set_flag_n(BYTE inReg) {
388 BYTE reg;
389 reg = inReg;
390
391 if ((reg & 0x80) != 0) // msbit set
392 {
393 Flags = Flags | FLAG_N;
394 }
395 else
396 {
397 Flags = Flags & (0xFF - FLAG_N);
398 }
399}
400
401void set_flag_z(BYTE inReg) {
402 BYTE reg;
403 reg = inReg;
404
405 if ((reg == 0) != 0) // msbit set
406 {
407 Flags = Flags | FLAG_Z;
408 }
409 else
410 {
411 Flags = Flags & (0xFF - FLAG_Z);
412 }
413}
414
415void Group_1(BYTE opcode){
416 BYTE LB = 0;
417 BYTE HB = 0;
418 WORD address = 0;
419 WORD data = 0;
420 WORD temp_word = 0;
421
422 switch (opcode) {
423 case 0x0A: //LDAA Immidiate
424 data = fetch();
425 Registers[REGISTER_A] = data;
426 break;
427 case 0x1A: //LDAA Absolute
428 HB = fetch();
429 LB = fetch();
430 address += (WORD)((WORD)HB << 8) + LB;
431 if (address >= 0 && address < MEMORY_SIZE) {
432 Registers[REGISTER_A] = Memory[address];
433 }
434 break;
435 case 0x2A: //LDAA Absolute with Index X
436 address += Index_Registers[REGISTER_X];
437 HB = fetch();
438 LB = fetch();
439 address += (WORD)((WORD)HB << 8) + LB;
440 if (address >= 0 && address < MEMORY_SIZE) {
441 Registers[REGISTER_A] = Memory[address];
442 }
443 break;
444 case 0x3A: //LDAA Absolute with Index Y
445 address += Index_Registers[REGISTER_Y];
446 HB = fetch();
447 LB = fetch();
448 address += (WORD)((WORD)HB << 8) + LB;
449 if (address >= 0 && address < MEMORY_SIZE) {
450 Registers[REGISTER_A] = Memory[address];
451 }
452 break;
453 case 0x4A: //LDAA Indirect
454 HB = fetch();
455 LB = fetch();
456 address = (WORD)((WORD)HB << 8) + LB;
457 HB = Memory[address];
458 LB = Memory[address + 1];
459 address = (WORD)((WORD)HB << 8) + LB;
460 if (address >= 0 && address < MEMORY_SIZE) {
461 Registers[REGISTER_A] = Memory[address];
462 }
463 break;
464 case 0x5A: //LDAA Indirect with Index X
465 HB = fetch();
466 LB = fetch();
467 address = (WORD)((WORD)HB << 8) + LB;
468 HB = Memory[address];
469 LB = Memory[address + 1];
470 address = (WORD)((WORD)HB << 8) + LB;
471 address += Index_Registers[REGISTER_X];
472 if (address >= 0 && address < MEMORY_SIZE) {
473 Registers[REGISTER_A] = Memory[address];
474 }
475 break;
476 case 0x0B: //LDAB Immidiate
477 data = fetch();
478 Registers[REGISTER_B] = data;
479 break;
480 case 0x1B: //LDAB Absolute
481 HB = fetch();
482 LB = fetch();
483 address += (WORD)((WORD)HB << 8) + LB;
484 if (address >= 0 && address < MEMORY_SIZE) {
485 Registers[REGISTER_B] = Memory[address];
486 }
487 break;
488 case 0x2B: //LDAB Absolute with Index X
489 address += Index_Registers[REGISTER_X];
490 HB = fetch();
491 LB = fetch();
492 address += (WORD)((WORD)HB << 8) + LB;
493 if (address >= 0 && address < MEMORY_SIZE) {
494 Registers[REGISTER_B] = Memory[address];
495 }
496 break;
497 case 0x3B: //LDAB Absolute with Index Y
498 address += Index_Registers[REGISTER_Y];
499 HB = fetch();
500 LB = fetch();
501 address += (WORD)((WORD)HB << 8) + LB;
502 if (address >= 0 && address < MEMORY_SIZE) {
503 Registers[REGISTER_B] = Memory[address];
504 }
505 break;
506 case 0x4B: //LDAB Indirect
507 HB = fetch();
508 LB = fetch();
509 address = (WORD)((WORD)HB << 8) + LB;
510 HB = Memory[address];
511 LB = Memory[address + 1];
512 address = (WORD)((WORD)HB << 8) + LB;
513 if (address >= 0 && address < MEMORY_SIZE) {
514 Registers[REGISTER_B] = Memory[address];
515 }
516 break;
517 case 0x5B: //LDAB Indirect with Index X
518 HB = fetch();
519 LB = fetch();
520 address = (WORD)((WORD)HB << 8) + LB;
521 HB = Memory[address];
522 LB = Memory[address + 1];
523 address = (WORD)((WORD)HB << 8) + LB;
524 address += Index_Registers[REGISTER_X];
525 if (address >= 0 && address < MEMORY_SIZE) {
526 Registers[REGISTER_B] = Memory[address];
527 }
528 break;
529 case 0xBA: //STORA Absolute
530 HB = fetch();
531 LB = fetch();
532 address += (WORD)((WORD)HB << 8) + LB;
533 if (address >= 0 && address < MEMORY_SIZE) {
534 Memory[address] = Registers[REGISTER_A];
535 }
536 break;
537 case 0xCA: //STORA Absolute with Index X
538 address += Index_Registers[REGISTER_X];
539 HB = fetch();
540 LB = fetch();
541 address += (WORD)((WORD)HB << 8) + LB;
542 if (address >= 0 && address < MEMORY_SIZE) {
543 Memory[address] = Registers[REGISTER_A];
544 }
545 break;
546 case 0xDA: //STORA Absolute with Index Y
547 address += Index_Registers[REGISTER_Y];
548 HB = fetch();
549 LB = fetch();
550 address += (WORD)((WORD)HB << 8) + LB;
551 if (address >= 0 && address < MEMORY_SIZE) {
552 Memory[address] = Registers[REGISTER_A];
553 }
554 break;
555 case 0xEA: //STORA Indirect
556 HB = fetch();
557 LB = fetch();
558 address = (WORD)((WORD)HB << 8) + LB;
559 HB = Memory[address];
560 LB = Memory[address + 1];
561 address = (WORD)((WORD)HB << 8) + LB;
562 if (address >= 0 && address < MEMORY_SIZE) {
563 Memory[address] = Registers[REGISTER_A];
564 }
565 break;
566 case 0xFA: //STORA Indirect with Index X
567 HB = fetch();
568 LB = fetch();
569 address = (WORD)((WORD)HB << 8) + LB;
570 HB = Memory[address];
571 LB = Memory[address + 1];
572 address = (WORD)((WORD)HB << 8) + LB;
573 address += Index_Registers[REGISTER_X];
574 if (address >= 0 && address < MEMORY_SIZE) {
575 Memory[address] = Registers[REGISTER_A];
576 }
577 break;
578 case 0xBB: //STORB Absolute
579 HB = fetch();
580 LB = fetch();
581 address += (WORD)((WORD)HB << 8) + LB;
582 if (address >= 0 && address < MEMORY_SIZE) {
583 Memory[address] = Registers[REGISTER_B];
584 }
585 break;
586 case 0xCB: //STORB Absolute with Index X
587 address += Index_Registers[REGISTER_X];
588 HB = fetch();
589 LB = fetch();
590 address += (WORD)((WORD)HB << 8) + LB;
591 if (address >= 0 && address < MEMORY_SIZE) {
592 Memory[address] = Registers[REGISTER_B];
593 }
594 break;
595 case 0xDB: //STORB Absolute with Index Y
596 address += Index_Registers[REGISTER_Y];
597 HB = fetch();
598 LB = fetch();
599 address += (WORD)((WORD)HB << 8) + LB;
600 if (address >= 0 && address < MEMORY_SIZE) {
601 Memory[address] = Registers[REGISTER_B];
602 }
603 break;
604 case 0xEB: //STORB Indirect
605 HB = fetch();
606 LB = fetch();
607 address = (WORD)((WORD)HB << 8) + LB;
608 HB = Memory[address];
609 LB = Memory[address + 1];
610 address = (WORD)((WORD)HB << 8) + LB;
611 if (address >= 0 && address < MEMORY_SIZE) {
612 Memory[address] = Registers[REGISTER_B];
613 }
614 break;
615 case 0xFB: //STORB Indirect with Index X
616 HB = fetch();
617 LB = fetch();
618 address = (WORD)((WORD)HB << 8) + LB;
619 HB = Memory[address];
620 LB = Memory[address + 1];
621 address = (WORD)((WORD)HB << 8) + LB;
622 address += Index_Registers[REGISTER_X];
623 if (address >= 0 && address < MEMORY_SIZE) {
624 Memory[address] = Registers[REGISTER_B];
625 }
626 break;
627 case 0xBC: //STOX Absolute
628 HB = fetch();
629 LB = fetch();
630 address += (WORD)((WORD)HB << 8) + LB;
631 if (address >= 0 && address < MEMORY_SIZE) {
632 Memory[address] = Registers[REGISTER_X];
633 }
634 break;
635 case 0xCC: //STOX Absolute with Index X
636 address += Index_Registers[REGISTER_X];
637 HB = fetch();
638 LB = fetch();
639 address += (WORD)((WORD)HB << 8) + LB;
640 if (address >= 0 && address < MEMORY_SIZE) {
641 Memory[address] = Registers[REGISTER_X];
642 }
643 break;
644 case 0xDC: //STOX Absolute with Index Y
645 address += Index_Registers[REGISTER_Y];
646 HB = fetch();
647 LB = fetch();
648 address += (WORD)((WORD)HB << 8) + LB;
649 if (address >= 0 && address < MEMORY_SIZE) {
650 Memory[address] = Registers[REGISTER_X];
651 }
652 break;
653 case 0xEC: //STOX 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_X];
662 }
663 break;
664 case 0xFC: //STOX Indirect with Index X
665 HB = fetch();
666 LB = fetch();
667 address = (WORD)((WORD)HB << 8) + LB;
668 HB = Memory[address];
669 LB = Memory[address + 1];
670 address = (WORD)((WORD)HB << 8) + LB;
671 address += Index_Registers[REGISTER_X];
672 if (address >= 0 && address < MEMORY_SIZE) {
673 Memory[address] = Registers[REGISTER_X];
674 }
675 break;
676 case 0xBD: //STOY Absolute
677 HB = fetch();
678 LB = fetch();
679 address += (WORD)((WORD)HB << 8) + LB;
680 if (address >= 0 && address < MEMORY_SIZE) {
681 Memory[address] = Registers[REGISTER_Y];
682 }
683 break;
684 case 0xCD: //STOY Absolute with Index X
685 address += Index_Registers[REGISTER_X];
686 HB = fetch();
687 LB = fetch();
688 address += (WORD)((WORD)HB << 8) + LB;
689 if (address >= 0 && address < MEMORY_SIZE) {
690 Memory[address] = Registers[REGISTER_Y];
691 }
692 break;
693 case 0xDD: //STOY Absolute with Index Y
694 address += Index_Registers[REGISTER_Y];
695 HB = fetch();
696 LB = fetch();
697 address += (WORD)((WORD)HB << 8) + LB;
698 if (address >= 0 && address < MEMORY_SIZE) {
699 Memory[address] = Registers[REGISTER_Y];
700 }
701 break;
702 case 0xED: //STOY Indirect
703 HB = fetch();
704 LB = fetch();
705 address = (WORD)((WORD)HB << 8) + LB;
706 HB = Memory[address];
707 LB = Memory[address + 1];
708 address = (WORD)((WORD)HB << 8) + LB;
709 if (address >= 0 && address < MEMORY_SIZE) {
710 Memory[address] = Registers[REGISTER_Y];
711 }
712 break;
713 case 0xFD: //STOY Indirect with Index X
714 HB = fetch();
715 LB = fetch();
716 address = (WORD)((WORD)HB << 8) + LB;
717 HB = Memory[address];
718 LB = Memory[address + 1];
719 address = (WORD)((WORD)HB << 8) + LB;
720 address += Index_Registers[REGISTER_X];
721 if (address >= 0 && address < MEMORY_SIZE) {
722 Memory[address] = Registers[REGISTER_Y];
723 }
724 break;
725 case 0xF2: //CSA
726 Registers[REGISTER_A] = Flags;
727 break;
728
729 case 0x1C: //MVI Loads Memory into register L
730 data = fetch();
731 Registers[REGISTER_L] = data;
732 break;
733 case 0x1D: //MVI Loads Memory into register L
734 data = fetch();
735 Registers[REGISTER_H] = data;
736 break;
737 case 0x20: // LODS Immediate
738 data = fetch();
739 StackPointer = data << 8; StackPointer += fetch();
740 break;
741 case 0x30: // LODS Immediate
742 HB = fetch();
743 LB = fetch();
744 address += (WORD)((WORD)HB << 8) + LB;
745 if (address >= 0 && address < MEMORY_SIZE) {
746 StackPointer =(WORD)Memory[address]<< 8;
747 StackPointer += Memory[address + 1];
748 }
749 break;
750
751 case 0x31: // ADC A:L
752 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
753 if ((Flags & FLAG_C) != 0)
754 {
755 temp_word++;
756 }
757 if (temp_word >= 0x100)
758 {
759 //Set carry flag
760 Flags = Flags | FLAG_C;
761 }
762 else
763 {
764 //Clear carry flag
765 Flags = Flags & (0xFF - FLAG_C);
766 }
767 set_flag_n((BYTE)temp_word);
768 set_flag_z((BYTE)temp_word);
769 Registers[REGISTER_A] = (BYTE)temp_word;
770 break;
771 case 0x41: // ADC A:H
772 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
773 if ((Flags & FLAG_C) != 0)
774 {
775 temp_word++;
776 }
777 if (temp_word >= 0x100)
778 {
779 //Set carry flag
780 Flags = Flags | FLAG_C;
781 }
782 else
783 {
784 //Clear carry flag
785 Flags = Flags & (0xFF - FLAG_C);
786 }
787 set_flag_n((BYTE)temp_word);
788 set_flag_z((BYTE)temp_word);
789 Registers[REGISTER_A] = (BYTE)temp_word;
790 break;
791 case 0x51: // ADC A:M
792 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_M];
793 if ((Flags & FLAG_C) != 0)
794 {
795 temp_word++;
796 }
797 if (temp_word >= 0x100)
798 {
799 //Set carry flag
800 Flags = Flags | FLAG_C;
801 }
802 else
803 {
804 //Clear carry flag
805 Flags = Flags & (0xFF - FLAG_C);
806 }
807 set_flag_n((BYTE)temp_word);
808 set_flag_z((BYTE)temp_word);
809 Registers[REGISTER_A] = (BYTE)temp_word;
810 break;
811 case 0x61: // ADC B:L
812 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_L];
813 if ((Flags & FLAG_C) != 0)
814 {
815 temp_word++;
816 }
817 if (temp_word >= 0x100)
818 {
819 //Set carry flag
820 Flags = Flags | FLAG_C;
821 }
822 else
823 {
824 //Clear carry flag
825 Flags = Flags & (0xFF - FLAG_C);
826 }
827 set_flag_n((BYTE)temp_word);
828 set_flag_z((BYTE)temp_word);
829 Registers[REGISTER_B] = (BYTE)temp_word;
830 break;
831 case 0x71: // ADC B:H
832 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_H];
833 if ((Flags & FLAG_C) != 0)
834 {
835 temp_word++;
836 }
837 if (temp_word >= 0x100)
838 {
839 //Set carry flag
840 Flags = Flags | FLAG_C;
841 }
842 else
843 {
844 //Clear carry flag
845 Flags = Flags & (0xFF - FLAG_C);
846 }
847 set_flag_n((BYTE)temp_word);
848 set_flag_z((BYTE)temp_word);
849 Registers[REGISTER_B] = (BYTE)temp_word;
850 break;
851 case 0x81: // ADC B:M
852 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_M];
853 if ((Flags & FLAG_C) != 0)
854 {
855 temp_word++;
856 }
857 if (temp_word >= 0x100)
858 {
859 //Set carry flag
860 Flags = Flags | FLAG_C;
861 }
862 else
863 {
864 //Clear carry flag
865 Flags = Flags & (0xFF - FLAG_C);
866 }
867 set_flag_n((BYTE)temp_word);
868 set_flag_z((BYTE)temp_word);
869 Registers[REGISTER_B] = (BYTE)temp_word;
870 break;
871
872
873
874 case 0x32: // SBC A:L
875 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
876 if ((Flags & FLAG_C) != 0)
877 {
878 temp_word--;
879 }
880 if (temp_word >= 0x100)
881 {
882 //Set carry flag
883 Flags = Flags | FLAG_C;
884 }
885 else
886 {
887 //Clear carry flag
888 Flags = Flags & (0xFF - FLAG_C);
889 }
890 set_flag_n((BYTE)temp_word);
891 set_flag_z((BYTE)temp_word);
892 Registers[REGISTER_A] = (BYTE)temp_word;
893 break;
894 case 0x42: // SBC A:H
895 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
896 if ((Flags & FLAG_C) != 0)
897 {
898 temp_word--;
899 }
900 if (temp_word >= 0x100)
901 {
902 //Set carry flag
903 Flags = Flags | FLAG_C;
904 }
905 else
906 {
907 //Clear carry flag
908 Flags = Flags & (0xFF - FLAG_C);
909 }
910 set_flag_n((BYTE)temp_word);
911 set_flag_z((BYTE)temp_word);
912 Registers[REGISTER_A] = (BYTE)temp_word;
913 break;
914 case 0x52: // SBC A:M
915 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
916 if ((Flags & FLAG_C) != 0)
917 {
918 temp_word--;
919 }
920 if (temp_word >= 0x100)
921 {
922 //Set carry flag
923 Flags = Flags | FLAG_C;
924 }
925 else
926 {
927 //Clear carry flag
928 Flags = Flags & (0xFF - FLAG_C);
929 }
930 set_flag_n((BYTE)temp_word);
931 set_flag_z((BYTE)temp_word);
932 Registers[REGISTER_A] = (BYTE)temp_word;
933 break;
934 case 0x62: // SBC B:L
935 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_L];
936 if ((Flags & FLAG_C) != 0)
937 {
938 temp_word--;
939 }
940 if (temp_word >= 0x100)
941 {
942 //Set carry flag
943 Flags = Flags | FLAG_C;
944 }
945 else
946 {
947 //Clear carry flag
948 Flags = Flags & (0xFF - FLAG_C);
949 }
950 set_flag_n((BYTE)temp_word);
951 set_flag_z((BYTE)temp_word);
952 Registers[REGISTER_B] = (BYTE)temp_word;
953 break;
954 case 0x72: // SBC B:H
955 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_H];
956 if ((Flags & FLAG_C) != 0)
957 {
958 temp_word--;
959 }
960 if (temp_word >= 0x100)
961 {
962 //Set carry flag
963 Flags = Flags | FLAG_C;
964 }
965 else
966 {
967 //Clear carry flag
968 Flags = Flags & (0xFF - FLAG_C);
969 }
970 set_flag_n((BYTE)temp_word);
971 set_flag_z((BYTE)temp_word);
972 Registers[REGISTER_B] = (BYTE)temp_word;
973 break;
974 case 0x82: // SBC B:M
975 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_M];
976 if ((Flags & FLAG_C) != 0)
977 {
978 temp_word--;
979 }
980 if (temp_word >= 0x100)
981 {
982 //Set carry flag
983 Flags = Flags | FLAG_C;
984 }
985 else
986 {
987 //Clear carry flag
988 Flags = Flags & (0xFF - FLAG_C);
989 }
990 set_flag_n((BYTE)temp_word);
991 set_flag_z((BYTE)temp_word);
992 Registers[REGISTER_B] = (BYTE)temp_word;
993 break;
994
995 case 0x33: // ADD A:L
996 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
997
998 if (temp_word >= 0x100)
999 {
1000 Flags = Flags | FLAG_C; //Set
1001 }
1002 else
1003 {
1004 //Clear carry flag
1005 Flags = Flags & (0xFF - FLAG_C);
1006 }
1007
1008
1009 set_flag_n((BYTE)temp_word);
1010 set_flag_z((BYTE)temp_word);
1011 Registers[REGISTER_A] = (BYTE)temp_word;
1012 break;
1013
1014 case 0x43: // ADD A:H
1015 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
1016
1017 if (temp_word >= 0x100)
1018 {
1019 Flags = Flags | FLAG_C; //Set
1020 }
1021 else
1022 {
1023 //Clear carry flag
1024 Flags = Flags & (0xFF - FLAG_C);
1025 }
1026
1027 set_flag_n((BYTE)temp_word);
1028 set_flag_z((BYTE)temp_word);
1029 Registers[REGISTER_A] = (BYTE)temp_word;
1030 break;
1031
1032 case 0x53: // ADD A:M
1033 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_M];
1034
1035 if (temp_word >= 0x100)
1036 {
1037 Flags = Flags | FLAG_C; //Set
1038 }
1039 else
1040 {
1041 //Clear carry flag
1042 Flags = Flags & (0xFF - FLAG_C);
1043 }
1044
1045 set_flag_n((BYTE)temp_word);
1046 set_flag_z((BYTE)temp_word);
1047 Registers[REGISTER_A] = (BYTE)temp_word;
1048 break;
1049
1050 case 0x63: // ADD B:L
1051 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_L];
1052
1053 if (temp_word >= 0x100)
1054 {
1055 Flags = Flags | FLAG_C; //Set
1056 }
1057 else
1058 {
1059 //Clear carry flag
1060 Flags = Flags & (0xFF - FLAG_C);
1061 }
1062
1063 set_flag_n((BYTE)temp_word);
1064 set_flag_z((BYTE)temp_word);
1065 Registers[REGISTER_B] = (BYTE)temp_word;
1066 break;
1067
1068 case 0x73: // ADD B:H
1069 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_H];
1070
1071 if (temp_word >= 0x100)
1072 {
1073 Flags = Flags | FLAG_C; //Set
1074 }
1075 else
1076 {
1077 //Clear carry flag
1078 Flags = Flags & (0xFF - FLAG_C);
1079 }
1080
1081 set_flag_n((BYTE)temp_word);
1082 set_flag_z((BYTE)temp_word);
1083 Registers[REGISTER_B] = (BYTE)temp_word;
1084 break;
1085 case 0x83: // ADD B:M
1086 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_M];
1087
1088 if (temp_word >= 0x100)
1089 {
1090 Flags = Flags | FLAG_C; //Set
1091 }
1092 else
1093 {
1094 //Clear carry flag
1095 Flags = Flags & (0xFF - FLAG_C);
1096 }
1097
1098 set_flag_n((BYTE)temp_word);
1099 set_flag_z((BYTE)temp_word);
1100 Registers[REGISTER_B] = (BYTE)temp_word;
1101 break;
1102
1103 case 0x34: // SUB A:L
1104 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1105
1106 if (temp_word >= 0x100)
1107 {
1108 Flags = Flags | FLAG_C; //Set
1109 }
1110 else
1111 {
1112 //Clear carry flag
1113 Flags = Flags & (0xFF - FLAG_C);
1114 }
1115
1116 set_flag_n((BYTE)temp_word);
1117 set_flag_z((BYTE)temp_word);
1118 Registers[REGISTER_A] = (BYTE)temp_word;
1119 break;
1120
1121 case 0x44: // SUB A:H
1122 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1123
1124 if (temp_word >= 0x100)
1125 {
1126 Flags = Flags | FLAG_C; //Set
1127 }
1128 else
1129 {
1130 //Clear carry flag
1131 Flags = Flags & (0xFF - FLAG_C);
1132 }
1133
1134 set_flag_n((BYTE)temp_word);
1135 set_flag_z((BYTE)temp_word);
1136 Registers[REGISTER_A] = (BYTE)temp_word;
1137 break;
1138
1139 case 0x54: // SUB A:M
1140 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
1141
1142 if (temp_word >= 0x100)
1143 {
1144 Flags = Flags | FLAG_C; //Set
1145 }
1146 else
1147 {
1148 //Clear carry flag
1149 Flags = Flags & (0xFF - FLAG_C);
1150 }
1151
1152 set_flag_n((BYTE)temp_word);
1153 set_flag_z((BYTE)temp_word);
1154 Registers[REGISTER_A] = (BYTE)temp_word;
1155 break;
1156
1157 case 0x64: // SUB B:L
1158 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_L];
1159
1160 if (temp_word >= 0x100)
1161 {
1162 Flags = Flags | FLAG_C; //Set
1163 }
1164 else
1165 {
1166 //Clear carry flag
1167 Flags = Flags & (0xFF - FLAG_C);
1168 }
1169
1170 set_flag_n((BYTE)temp_word);
1171 set_flag_z((BYTE)temp_word);
1172 Registers[REGISTER_B] = (BYTE)temp_word;
1173 break;
1174
1175 case 0x74: // SUB B:H
1176 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_H];
1177
1178 if (temp_word >= 0x100)
1179 {
1180 Flags = Flags | FLAG_C; //Set
1181 }
1182 else
1183 {
1184 //Clear carry flag
1185 Flags = Flags & (0xFF - FLAG_C);
1186 }
1187
1188 set_flag_n((BYTE)temp_word);
1189 set_flag_z((BYTE)temp_word);
1190 Registers[REGISTER_B] = (BYTE)temp_word;
1191 break;
1192
1193 case 0x84: // SUB B:M
1194 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_M];
1195
1196 if (temp_word >= 0x100)
1197 {
1198 Flags = Flags | FLAG_C; //Set
1199 }
1200 else
1201 {
1202 //Clear carry flag
1203 Flags = Flags & (0xFF - FLAG_C);
1204 }
1205
1206 set_flag_n((BYTE)temp_word);
1207 set_flag_z((BYTE)temp_word);
1208 Registers[REGISTER_B] = (BYTE)temp_word;
1209 break;
1210
1211
1212 case 0x35: // CMP A:L
1213 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1214 if (temp_word >= 0x100)
1215 {
1216 Flags = Flags | FLAG_C; //Set
1217 }
1218 else
1219 {
1220 //Clear carry flag
1221 Flags = Flags & (0xFF - FLAG_C);
1222 }
1223 set_flag_n((BYTE)temp_word);
1224 set_flag_z((BYTE)temp_word);
1225 break;
1226 case 0x45: // CMP A:H
1227 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1228 if (temp_word >= 0x100)
1229 {
1230 Flags = Flags | FLAG_C; //Set
1231 }
1232 else
1233 {
1234 //Clear carry flag
1235 Flags = Flags & (0xFF - FLAG_C);
1236 }
1237 set_flag_n((BYTE)temp_word);
1238 set_flag_z((BYTE)temp_word);
1239 break;
1240
1241 case 0x55: // CMP A:M
1242 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
1243 if (temp_word >= 0x100)
1244 {
1245 Flags = Flags | FLAG_C; //Set
1246 }
1247 else
1248 {
1249 //Clear carry flag
1250 Flags = Flags & (0xFF - FLAG_C);
1251 }
1252 set_flag_n((BYTE)temp_word);
1253 set_flag_z((BYTE)temp_word);
1254 break;
1255
1256 case 0x65: // CMP B:L
1257 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_L];
1258 if (temp_word >= 0x100)
1259 {
1260 Flags = Flags | FLAG_C; //Set
1261 }
1262 else
1263 {
1264 //Clear carry flag
1265 Flags = Flags & (0xFF - FLAG_C);
1266 }
1267 set_flag_n((BYTE)temp_word);
1268 set_flag_z((BYTE)temp_word);
1269 break;
1270
1271 case 0x75: // CMP B:H
1272 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_H];
1273 if (temp_word >= 0x100)
1274 {
1275 Flags = Flags | FLAG_C; //Set
1276 }
1277 else
1278 {
1279 //Clear carry flag
1280 Flags = Flags & (0xFF - FLAG_C);
1281 }
1282 set_flag_n((BYTE)temp_word);
1283 set_flag_z((BYTE)temp_word);
1284 break;
1285
1286 case 0x85: // CMP B:M
1287 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_M];
1288 if (temp_word >= 0x100)
1289 {
1290 Flags = Flags | FLAG_C; //Set
1291 }
1292 else
1293 {
1294 //Clear carry flag
1295 Flags = Flags & (0xFF - FLAG_C);
1296 }
1297 set_flag_n((BYTE)temp_word);
1298 set_flag_z((BYTE)temp_word);
1299 break;
1300
1301 case 0x36: // OR A:L
1302 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_L];
1303
1304 set_flag_n((BYTE)temp_word);
1305 set_flag_z((BYTE)temp_word);
1306 Registers[REGISTER_A] = (BYTE)temp_word;
1307 break;
1308
1309 case 0x46: // OR A:H
1310 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_H];
1311
1312 set_flag_n((BYTE)temp_word);
1313 set_flag_z((BYTE)temp_word);
1314 Registers[REGISTER_A] = (BYTE)temp_word;
1315 break;
1316
1317 case 0x56: // COR A:M
1318 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_M];
1319
1320 set_flag_n((BYTE)temp_word);
1321 set_flag_z((BYTE)temp_word);
1322 Registers[REGISTER_A] = (BYTE)temp_word;
1323 break;
1324
1325 case 0x66: // OR B:L
1326 temp_word = (WORD)Registers[REGISTER_B] | (WORD)Registers[REGISTER_L];
1327
1328 set_flag_n((BYTE)temp_word);
1329 set_flag_z((BYTE)temp_word);
1330 Registers[REGISTER_B] = (BYTE)temp_word;
1331 break;
1332
1333 case 0x76: // OR B:H
1334 temp_word = (WORD)Registers[REGISTER_B] | (WORD)Registers[REGISTER_H];
1335
1336 set_flag_n((BYTE)temp_word);
1337 set_flag_z((BYTE)temp_word);
1338 Registers[REGISTER_B] = (BYTE)temp_word;
1339 break;
1340
1341 case 0x86: // OR B:M
1342 temp_word = (WORD)Registers[REGISTER_B] | (WORD)Registers[REGISTER_M];
1343
1344 set_flag_n((BYTE)temp_word);
1345 set_flag_z((BYTE)temp_word);
1346 Registers[REGISTER_B] = (BYTE)temp_word;
1347 break;
1348
1349 case 0x37: // AND A:L
1350 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_L];
1351
1352 set_flag_n((BYTE)temp_word);
1353 set_flag_z((BYTE)temp_word);
1354 Registers[REGISTER_A] = (BYTE)temp_word;
1355 break;
1356
1357 case 0x47: // AND A:H
1358 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_H];
1359
1360 set_flag_n((BYTE)temp_word);
1361 set_flag_z((BYTE)temp_word);
1362 Registers[REGISTER_A] = (BYTE)temp_word;
1363 break;
1364
1365 case 0x57: // AND A:M
1366 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_M];
1367
1368 set_flag_n((BYTE)temp_word);
1369 set_flag_z((BYTE)temp_word);
1370 Registers[REGISTER_A] = (BYTE)temp_word;
1371 break;
1372
1373 case 0x67: // AND B:L
1374 temp_word = (WORD)Registers[REGISTER_B] & (WORD)Registers[REGISTER_L];
1375
1376 set_flag_n((BYTE)temp_word);
1377 set_flag_z((BYTE)temp_word);
1378 Registers[REGISTER_B] = (BYTE)temp_word;
1379 break;
1380
1381 case 0x77: // AND B:H
1382 temp_word = (WORD)Registers[REGISTER_B] & (WORD)Registers[REGISTER_H];
1383
1384 set_flag_n((BYTE)temp_word);
1385 set_flag_z((BYTE)temp_word);
1386 Registers[REGISTER_B] = (BYTE)temp_word;
1387 break;
1388
1389 case 0x87: // AND B:M
1390 temp_word = (WORD)Registers[REGISTER_B] & (WORD)Registers[REGISTER_M];
1391
1392 set_flag_n((BYTE)temp_word);
1393 set_flag_z((BYTE)temp_word);
1394 Registers[REGISTER_B] = (BYTE)temp_word;
1395 break;
1396
1397 case 0x38: // XOR A:L
1398 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_L];
1399
1400 set_flag_n((BYTE)temp_word);
1401 set_flag_z((BYTE)temp_word);
1402 Registers[REGISTER_A] = (BYTE)temp_word;
1403 break;
1404
1405 case 0x48: // OR A:H
1406 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_H];
1407
1408 set_flag_n((BYTE)temp_word);
1409 set_flag_z((BYTE)temp_word);
1410 Registers[REGISTER_A] = (BYTE)temp_word;
1411 break;
1412
1413 case 0x58: // XOR A:M
1414 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_M];
1415
1416 set_flag_n((BYTE)temp_word);
1417 set_flag_z((BYTE)temp_word);
1418 Registers[REGISTER_A] = (BYTE)temp_word;
1419 break;
1420
1421 case 0x68: // XOR B:L
1422 temp_word = (WORD)Registers[REGISTER_B] ^ (WORD)Registers[REGISTER_L];
1423
1424 set_flag_n((BYTE)temp_word);
1425 set_flag_z((BYTE)temp_word);
1426 Registers[REGISTER_B] = (BYTE)temp_word;
1427 break;
1428
1429 case 0x78: // XOR B:H
1430 temp_word = (WORD)Registers[REGISTER_B] ^ (WORD)Registers[REGISTER_H];
1431
1432 set_flag_n((BYTE)temp_word);
1433 set_flag_z((BYTE)temp_word);
1434 Registers[REGISTER_B] = (BYTE)temp_word;
1435 break;
1436
1437 case 0x88: // XOR B:M
1438 temp_word = (WORD)Registers[REGISTER_B] ^ (WORD)Registers[REGISTER_M];
1439
1440 set_flag_n((BYTE)temp_word);
1441 set_flag_z((BYTE)temp_word);
1442 Registers[REGISTER_B] = (BYTE)temp_word;
1443 break;
1444
1445 case 0x40: // LODS Absoulte with Index X
1446 address += Index_Registers[REGISTER_X];
1447 HB = fetch();
1448 LB = fetch();
1449 address += (WORD)((WORD)HB << 8) + LB;
1450 if (address >= 0 && address < MEMORY_SIZE) {
1451 StackPointer = (WORD)Memory[address] << 8;
1452 StackPointer += Memory[address + 1];
1453 }
1454 break;
1455 case 0x50: // LODS Absoulte with Index Y
1456 address += Index_Registers[REGISTER_Y];
1457 HB = fetch();
1458 LB = fetch();
1459 address += (WORD)((WORD)HB << 8) + LB;
1460 if (address >= 0 && address < MEMORY_SIZE) {
1461 StackPointer = (WORD)Memory[address] << 8;
1462 StackPointer += Memory[address + 1];
1463 }
1464 break;
1465 case 0x60: // LODS Indirect
1466 HB = fetch();
1467 LB = fetch();
1468 address = (WORD)((WORD)HB << 8) + LB;
1469 HB = Memory[address];
1470 LB = Memory[address + 1];
1471 address = (WORD)((WORD)HB << 8) + LB;
1472 if (address >= 0 && address < MEMORY_SIZE -1) {
1473 StackPointer = (WORD)Memory[address] << 8;
1474 StackPointer += Memory[address + 1];
1475 }
1476 break;
1477 case 0x70: // LODS Indirect with Index X
1478 HB = fetch();
1479 LB = fetch();
1480 address = (WORD)((WORD)HB << 8) + LB;
1481 HB = Memory[address];
1482 LB = Memory[address + 1];
1483 address = (WORD)((WORD)HB << 8) + LB;
1484 address += Index_Registers[REGISTER_X];
1485 if (address >= 0 && address < MEMORY_SIZE - 1) {
1486 StackPointer = (WORD)Memory[address] << 8;
1487 StackPointer += Memory[address + 1];
1488 }
1489 break;
1490
1491 case 0x6A: //STOX Absolute
1492
1493 data = fetch();
1494 data = StackPointer << 8; StackPointer += fetch();
1495
1496 break;
1497
1498 case 0x7A: //STOX Absolute with Index X
1499
1500 HB = fetch();
1501 LB = fetch();
1502 address += (WORD)((WORD)HB << 8) + LB;
1503 if (address >= 0 && address < MEMORY_SIZE) {
1504 data = (WORD)StackPointer << 8;
1505 StackPointer += Memory[address + 1];
1506 }
1507
1508 break;
1509
1510 case 0x8A: //STOX Absolute with Index Y
1511
1512 address += Index_Registers[REGISTER_X];
1513 HB = fetch();
1514 LB = fetch();
1515 address += (WORD)((WORD)HB << 8) + LB;
1516 if (address >= 0 && address < MEMORY_SIZE) {
1517 StackPointer = (WORD)Memory[address] << 8;
1518 StackPointer += Memory[address + 1];
1519 }
1520
1521
1522 break;
1523
1524 case 0x9A: //STOX Indirect
1525
1526 address += Index_Registers[REGISTER_Y];
1527 HB = fetch();
1528 LB = fetch();
1529 address += (WORD)((WORD)HB << 8) + LB;
1530 if (address >= 0 && address < MEMORY_SIZE) {
1531 StackPointer = (WORD)Memory[address] << 8;
1532 StackPointer += Memory[address + 1];
1533 }
1534
1535
1536 break;
1537
1538 case 0xAA: //STOX Indirect with Index X
1539
1540 HB = fetch();
1541 LB = fetch();
1542 address = (WORD)((WORD)HB << 8) + LB;
1543 HB = Memory[address];
1544 LB = Memory[address + 1];
1545 address = (WORD)((WORD)HB << 8) + LB;
1546 address += Index_Registers[REGISTER_X];
1547 if (address >= 0 && address < MEMORY_SIZE - 1) {
1548 StackPointer = (WORD)Memory[address] << 8;
1549 StackPointer += Memory[address + 1];
1550 }
1551
1552 break;
1553
1554
1555 default:
1556 opcode = opcode;
1557 halt = true;
1558 break;
1559 }
1560}
1561
1562void Group_2_Move(BYTE opcode)
1563{
1564 BYTE destination = opcode >> 4;
1565 BYTE source = opcode & 0x0F;
1566
1567 int destReg;
1568 int sourceReg;
1569
1570 switch (destination) {
1571 case 0x06:
1572 destReg = REGISTER_A;
1573 break;
1574 case 0x07:
1575 destReg = REGISTER_B;
1576 break;
1577 case 0x08:
1578 destReg = REGISTER_L;
1579 break;
1580 case 0x09:
1581 destReg = REGISTER_H;
1582 break;
1583 case 0x0A:
1584 destReg = REGISTER_M;
1585 break;
1586
1587 default:
1588 break;
1589 }
1590
1591 switch (source)
1592 {
1593 case 0x0B:
1594 sourceReg = REGISTER_A;
1595 break;
1596 case 0x0C:
1597 sourceReg = REGISTER_B;
1598 break;
1599 case 0x0D:
1600 sourceReg = REGISTER_L;
1601 break;
1602 case 0x0E:
1603 sourceReg = REGISTER_H;
1604 break;
1605 case 0x0F:
1606 sourceReg = REGISTER_M;
1607 break;
1608
1609 default:
1610 break;
1611 }
1612
1613 Registers[destReg] = Registers[sourceReg];
1614
1615}
1616
1617
1618void execute(BYTE opcode)
1619{
1620
1621 if(((opcode >= 0x6B) && (opcode <= 0x6F))
1622 || ((opcode >= 0x7B) && (opcode <= 0x7F))
1623 || ((opcode >= 0x8B) && (opcode <= 0x8F))
1624 || ((opcode >= 0x9B) && (opcode <= 0x9F))
1625 || ((opcode >= 0xAB) && (opcode <= 0xAF)))
1626 {
1627 Group_2_Move(opcode);
1628 }
1629 else
1630 {
1631 Group_1(opcode);
1632 }
1633}
1634
1635void emulate()
1636{
1637 BYTE opcode;
1638 int sanity;
1639
1640 ProgramCounter = 0;
1641 halt = false;
1642 memory_in_range = true;
1643 sanity = 0;
1644
1645 printf(" A B L H X Y SP\n");
1646
1647 while ((!halt) && (memory_in_range) && (sanity < 200))
1648 {
1649 printf("%04X ", ProgramCounter); // Print current address
1650 opcode = fetch();
1651 execute(opcode);
1652
1653 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
1654
1655 printf("%02X ", Registers[REGISTER_A]);
1656 printf("%02X ", Registers[REGISTER_B]);
1657 printf("%02X ", Registers[REGISTER_L]);
1658 printf("%02X ", Registers[REGISTER_H]);
1659 printf("%02X ", Index_Registers[REGISTER_X]);
1660 printf("%02X ", Index_Registers[REGISTER_Y]);
1661 printf("%04X ", StackPointer); // Print Stack Pointer
1662
1663 if ((Flags & FLAG_I) == FLAG_I)
1664 {
1665 printf("I=1 ");
1666 }
1667 else
1668 {
1669 printf("I=0 ");
1670 }
1671 if ((Flags & FLAG_Z) == FLAG_Z)
1672 {
1673 printf("Z=1 ");
1674 }
1675 else
1676 {
1677 printf("Z=0 ");
1678 }
1679 if ((Flags & FLAG_N) == FLAG_N)
1680 {
1681 printf("N=1 ");
1682 }
1683 else
1684 {
1685 printf("N=0 ");
1686 }
1687 if ((Flags & FLAG_C) == FLAG_C)
1688 {
1689 printf("C=1 ");
1690 }
1691 else
1692 {
1693 printf("C=0 ");
1694 }
1695
1696 printf("\n"); // New line
1697 sanity++;
1698 }
1699
1700 printf("\n"); // New line
1701}
1702
1703
1704////////////////////////////////////////////////////////////////////////////////
1705// Simulator/Emulator (End) //
1706////////////////////////////////////////////////////////////////////////////////
1707
1708
1709void initialise_filenames() {
1710 int i;
1711
1712 for (i=0; i<MAX_FILENAME_SIZE; i++) {
1713 hex_file [i] = '\0';
1714 trc_file [i] = '\0';
1715 }
1716}
1717
1718
1719
1720
1721int find_dot_position(char *filename) {
1722 int dot_position;
1723 int i;
1724 char chr;
1725
1726 dot_position = 0;
1727 i = 0;
1728 chr = filename[i];
1729
1730 while (chr != '\0') {
1731 if (chr == '.') {
1732 dot_position = i;
1733 }
1734 i++;
1735 chr = filename[i];
1736 }
1737
1738 return (dot_position);
1739}
1740
1741
1742int find_end_position(char *filename) {
1743 int end_position;
1744 int i;
1745 char chr;
1746
1747 end_position = 0;
1748 i = 0;
1749 chr = filename[i];
1750
1751 while (chr != '\0') {
1752 end_position = i;
1753 i++;
1754 chr = filename[i];
1755 }
1756
1757 return (end_position);
1758}
1759
1760
1761bool file_exists(char *filename) {
1762 bool exists;
1763 FILE *ifp;
1764
1765 exists = false;
1766
1767 if ( ( ifp = fopen( filename, "r" ) ) != NULL )
1768 {
1769 exists = true;
1770
1771 fclose(ifp);
1772 }
1773
1774 return (exists);
1775}
1776
1777
1778
1779void create_file(char *filename) {
1780 FILE *ofp;
1781
1782 if ( ( ofp = fopen( filename, "w" ) ) != NULL ) {
1783 fclose(ofp);
1784 }
1785}
1786
1787
1788
1789bool getline(FILE *fp, char *buffer) {
1790 bool rc;
1791 bool collect;
1792 char c;
1793 int i;
1794
1795 rc = false;
1796 collect = true;
1797
1798 i = 0;
1799 while (collect) {
1800 c = getc(fp);
1801
1802 switch (c) {
1803 case EOF:
1804 if (i > 0) {
1805 rc = true;
1806 }
1807 collect = false;
1808 break;
1809
1810 case '\n':
1811 if (i > 0) {
1812 rc = true;
1813 collect = false;
1814 buffer[i] = '\0';
1815 }
1816 break;
1817
1818 default:
1819 buffer[i] = c;
1820 i++;
1821 break;
1822 }
1823 }
1824
1825 return (rc);
1826}
1827
1828
1829
1830
1831
1832
1833void load_and_run(int args,_TCHAR** argv) {
1834 char chr;
1835 int ln;
1836 int dot_position;
1837 int end_position;
1838 long i;
1839 FILE *ifp;
1840 long address;
1841 long load_at;
1842 int code;
1843
1844 // Prompt for the .hex file
1845
1846 printf("\n");
1847 printf("Enter the hex filename (.hex): ");
1848
1849 if(args == 2){
1850 ln = 0;
1851 chr = argv[1][ln];
1852 while (chr != '\0')
1853 {
1854 if (ln < MAX_FILENAME_SIZE)
1855 {
1856 hex_file [ln] = chr;
1857 trc_file [ln] = chr;
1858 ln++;
1859 }
1860 chr = argv[1][ln];
1861 }
1862 } else {
1863 ln = 0;
1864 chr = '\0';
1865 while (chr != '\n') {
1866 chr = getchar();
1867
1868 switch(chr) {
1869 case '\n':
1870 break;
1871 default:
1872 if (ln < MAX_FILENAME_SIZE) {
1873 hex_file [ln] = chr;
1874 trc_file [ln] = chr;
1875 ln++;
1876 }
1877 break;
1878 }
1879 }
1880
1881 }
1882 // Tidy up the file names
1883
1884 dot_position = find_dot_position(hex_file);
1885 if (dot_position == 0) {
1886 end_position = find_end_position(hex_file);
1887
1888 hex_file[end_position + 1] = '.';
1889 hex_file[end_position + 2] = 'h';
1890 hex_file[end_position + 3] = 'e';
1891 hex_file[end_position + 4] = 'x';
1892 hex_file[end_position + 5] = '\0';
1893 } else {
1894 hex_file[dot_position + 0] = '.';
1895 hex_file[dot_position + 1] = 'h';
1896 hex_file[dot_position + 2] = 'e';
1897 hex_file[dot_position + 3] = 'x';
1898 hex_file[dot_position + 4] = '\0';
1899 }
1900
1901 dot_position = find_dot_position(trc_file);
1902 if (dot_position == 0) {
1903 end_position = find_end_position(trc_file);
1904
1905 trc_file[end_position + 1] = '.';
1906 trc_file[end_position + 2] = 't';
1907 trc_file[end_position + 3] = 'r';
1908 trc_file[end_position + 4] = 'c';
1909 trc_file[end_position + 5] = '\0';
1910 } else {
1911 trc_file[dot_position + 0] = '.';
1912 trc_file[dot_position + 1] = 't';
1913 trc_file[dot_position + 2] = 'r';
1914 trc_file[dot_position + 3] = 'c';
1915 trc_file[dot_position + 4] = '\0';
1916 }
1917
1918 if (file_exists(hex_file)) {
1919 // Clear Registers and Memory
1920
1921 Registers[REGISTER_A] = 0;
1922 Registers[REGISTER_B] = 0;
1923 Registers[REGISTER_L] = 0;
1924 Registers[REGISTER_H] = 0;
1925 Index_Registers[REGISTER_X] = 0;
1926 Index_Registers[REGISTER_Y] = 0;
1927 Flags = 0;
1928 ProgramCounter = 0;
1929 StackPointer = 0;
1930
1931 for (i=0; i<MEMORY_SIZE; i++) {
1932 Memory[i] = 0x00;
1933 }
1934
1935 // Load hex file
1936
1937 if ( ( ifp = fopen( hex_file, "r" ) ) != NULL ) {
1938 printf("Loading file...\n\n");
1939
1940 load_at = 0;
1941
1942 while (getline(ifp, InputBuffer)) {
1943 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
1944 load_at = address;
1945 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
1946 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
1947 Memory[load_at] = (BYTE)code;
1948 }
1949 load_at++;
1950 } else {
1951 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
1952 }
1953 }
1954
1955 fclose(ifp);
1956 }
1957
1958 // Emulate
1959
1960 emulate();
1961 } else {
1962 printf("\n");
1963 printf("ERROR> Input file %s does not exist!\n", hex_file);
1964 printf("\n");
1965 }
1966}
1967
1968void building(int args,_TCHAR** argv)
1969{
1970 char buffer[1024];
1971 load_and_run(args,argv);
1972 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",
1973 Memory[TEST_ADDRESS_1],
1974 Memory[TEST_ADDRESS_2],
1975 Memory[TEST_ADDRESS_3],
1976 Memory[TEST_ADDRESS_4],
1977 Memory[TEST_ADDRESS_5],
1978 Memory[TEST_ADDRESS_6],
1979 Memory[TEST_ADDRESS_7],
1980 Memory[TEST_ADDRESS_8],
1981 Memory[TEST_ADDRESS_9],
1982 Memory[TEST_ADDRESS_10],
1983 Memory[TEST_ADDRESS_11],
1984 Memory[TEST_ADDRESS_12]
1985 );
1986 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1987}
1988
1989
1990
1991void test_and_mark() {
1992 char buffer[1024];
1993 bool testing_complete;
1994 int len = sizeof(SOCKADDR);
1995 char chr;
1996 int i;
1997 int j;
1998 bool end_of_program;
1999 long address;
2000 long load_at;
2001 int code;
2002 int mark;
2003 int passed;
2004
2005 printf("\n");
2006 printf("Automatic Testing and Marking\n");
2007 printf("\n");
2008
2009 testing_complete = false;
2010
2011 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
2012 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2013
2014 while (!testing_complete) {
2015 memset(buffer, '\0', sizeof(buffer));
2016
2017 if (recvfrom(sock, buffer, sizeof(buffer)-1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
2018 printf("Incoming Data: %s \n", buffer);
2019
2020 //if (strcmp(buffer, "Testing complete") == 1)
2021 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
2022 testing_complete = true;
2023 printf("Current mark = %d\n", mark);
2024
2025 }else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
2026 //testing_complete = true;
2027 printf("Passed = %d\n", passed);
2028
2029 } else if (strcmp(buffer, "Error") == 0) {
2030 printf("ERROR> Testing abnormally terminated\n");
2031 testing_complete = true;
2032 } else {
2033 // Clear Registers and Memory
2034
2035 Registers[REGISTER_A] = 0;
2036 Registers[REGISTER_B] = 0;
2037 Registers[REGISTER_L] = 0;
2038 Registers[REGISTER_H] = 0;
2039 Index_Registers[REGISTER_X] = 0;
2040 Index_Registers[REGISTER_Y] = 0;
2041 Flags = 0;
2042 ProgramCounter = 0;
2043 StackPointer = 0;
2044 for (i=0; i<MEMORY_SIZE; i++) {
2045 Memory[i] = 0;
2046 }
2047
2048 // Load hex file
2049
2050 i = 0;
2051 j = 0;
2052 load_at = 0;
2053 end_of_program = false;
2054 FILE *ofp;
2055 fopen_s(&ofp ,"branch.txt", "a");
2056
2057 while (!end_of_program) {
2058 chr = buffer[i];
2059 switch (chr) {
2060 case '\0':
2061 end_of_program = true;
2062
2063 case ',':
2064 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
2065 load_at = address;
2066 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
2067 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
2068 Memory[load_at] = (BYTE)code;
2069 fprintf(ofp, "%02X\n", (BYTE)code);
2070 }
2071 load_at++;
2072 } else {
2073 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
2074 }
2075 j = 0;
2076 break;
2077
2078 default:
2079 InputBuffer[j] = chr;
2080 j++;
2081 break;
2082 }
2083 i++;
2084 }
2085 fclose(ofp);
2086 // Emulate
2087
2088 if (load_at > 1) {
2089 emulate();
2090 // Send and store results
2091 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
2092 Memory[TEST_ADDRESS_1],
2093 Memory[TEST_ADDRESS_2],
2094 Memory[TEST_ADDRESS_3],
2095 Memory[TEST_ADDRESS_4],
2096 Memory[TEST_ADDRESS_5],
2097 Memory[TEST_ADDRESS_6],
2098 Memory[TEST_ADDRESS_7],
2099 Memory[TEST_ADDRESS_8],
2100 Memory[TEST_ADDRESS_9],
2101 Memory[TEST_ADDRESS_10],
2102 Memory[TEST_ADDRESS_11],
2103 Memory[TEST_ADDRESS_12]
2104 );
2105 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2106 }
2107 }
2108 }
2109 }
2110}
2111
2112
2113
2114int _tmain(int argc, _TCHAR* argv[])
2115{
2116 char chr;
2117 char dummy;
2118
2119 printf("\n");
2120 printf("Microprocessor Emulator\n");
2121 printf("UWE Computer and Network Systems Assignment 1\n");
2122 printf("\n");
2123
2124 initialise_filenames();
2125
2126 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
2127
2128 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
2129 if (!sock) {
2130 // Creation failed!
2131 }
2132
2133 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
2134 server_addr.sin_family = AF_INET;
2135 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
2136 server_addr.sin_port = htons(PORT_SERVER);
2137
2138 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
2139 client_addr.sin_family = AF_INET;
2140 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
2141 client_addr.sin_port = htons(PORT_CLIENT);
2142
2143 chr = '\0';
2144 while ((chr != 'e') && (chr != 'E'))
2145 {
2146 printf("\n");
2147 printf("Please select option\n");
2148 printf("L - Load and run a hex file\n");
2149 printf("T - Have the server test and mark your emulator\n");
2150 printf("E - Exit\n");
2151 if(argc == 2){ building(argc,argv); exit(0);}
2152 printf("Enter option: ");
2153 chr = getchar();
2154 if (chr != 0x0A)
2155 {
2156 dummy = getchar(); // read in the <CR>
2157 }
2158 printf("\n");
2159
2160 switch (chr)
2161 {
2162 case 'L':
2163 case 'l':
2164 load_and_run(argc,argv);
2165 break;
2166
2167 case 'T':
2168 case 't':
2169 test_and_mark();
2170 break;
2171
2172 default:
2173 break;
2174 }
2175 }
2176
2177 closesocket(sock);
2178 WSACleanup();
2179
2180
2181 return 0;
2182}