· 5 years ago · Feb 18, 2020, 06:22 PM
1
2
3#include "stdafx.h"
4#include <winsock2.h>
5
6#pragma comment(lib, "wsock32.lib")
7
8
9#define STUDENT_NUMBER "18007506"
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 0x80
40#define FLAG_N 0x20
41#define FLAG_V 0x10
42#define FLAG_Z 0x08
43#define FLAG_C 0x01
44#define REGISTER_M 7
45#define REGISTER_A 6
46#define REGISTER_H 5
47#define REGISTER_L 4
48#define REGISTER_E 3
49#define REGISTER_D 2
50#define REGISTER_C 1
51#define REGISTER_B 0
52WORD IndexRegister;
53
54BYTE Registers[8];
55BYTE Flags;
56WORD ProgramCounter;
57WORD StackPointer;
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"BRA rel ",
97"BCC rel ",
98"BCS rel ",
99"BNE rel ",
100"BEQ rel ",
101"BVC rel ",
102"BVS rel ",
103"BMI rel ",
104"BPL rel ",
105"BGE rel ",
106"BLE rel ",
107"BLS rel ",
108"BHI rel ",
109"ILLEGAL ",
110"RTN impl ",
111"ILLEGAL ",
112
113"ST abs ",
114"PSH ,A ",
115"POP A, ",
116"ILLEGAL ",
117"ILLEGAL ",
118"CLC impl ",
119"SEC impl ",
120"CLI impl ",
121"STI impl ",
122"SEV impl ",
123"CLV impl ",
124"DEX impl ",
125"INX impl ",
126"NOP impl ",
127"WAI impl ",
128"ILLEGAL ",
129
130"ST abs,X ",
131"PSH ,s ",
132"POP s, ",
133"ILLEGAL ",
134"ILLEGAL ",
135"ADI # ",
136"SBI # ",
137"CPI # ",
138"ANI # ",
139"XRI # ",
140"MVI #,B ",
141"MVI #,C ",
142"MVI #,D ",
143"MVI #,E ",
144"MVI #,L ",
145"MVI #,H ",
146
147"ILLEGAL ",
148"PSH ,B ",
149"POP B, ",
150"JPR abs ",
151"CCC abs ",
152"CCS abs ",
153"CNE abs ",
154"CEQ abs ",
155"CVC abs ",
156"CVS abs ",
157"CMI abs ",
158"CPL abs ",
159"CHI abs ",
160"CLE abs ",
161"ILLEGAL ",
162"ILLEGAL ",
163
164"ILLEGAL ",
165"PSH ,C ",
166"POP C, ",
167"TST abs ",
168"INC abs ",
169"DEC abs ",
170"RCR abs ",
171"RCL abs ",
172"SAL abs ",
173"ASR abs ",
174"NOT abs ",
175"ROL abs ",
176"ROR abs ",
177"ILLEGAL ",
178"LDX # ",
179"LODS # ",
180
181"STOX abs ",
182"PSH ,D ",
183"POP D, ",
184"TST abs,X ",
185"INC abs,X ",
186"DEC abs,X ",
187"RCR abs,X ",
188"RCL abs,X ",
189"SAL abs,X ",
190"ASR abs,X ",
191"NOT abs,X ",
192"ROL abs,X ",
193"ROR abs,X ",
194"ILLEGAL ",
195"LDX abs ",
196"LODS abs ",
197
198"STOX abs,X ",
199"PSH ,E ",
200"POP E, ",
201"TSTA A,A ",
202"INCA A,A ",
203"DECA A,A ",
204"RCRA A,A ",
205"RCLA A,A ",
206"SALA A,A ",
207"ASRA A,A ",
208"NOTA A,A ",
209"ROLA A,A ",
210"RORA A,A ",
211"ILLEGAL ",
212"LDX abs,X ",
213"LODS abs,X ",
214
215"ILLEGAL ",
216"PSH ,L ",
217"POP L, ",
218"ILLEGAL ",
219"TAS impl ",
220"TSA impl ",
221"ILLEGAL ",
222"ILLEGAL ",
223"MOVE A,A ",
224"MOVE B,A ",
225"MOVE C,A ",
226"MOVE D,A ",
227"MOVE E,A ",
228"MOVE L,A ",
229"MOVE H,A ",
230"MOVE M,A ",
231
232"ILLEGAL ",
233"PSH ,H ",
234"POP H, ",
235"ILLEGAL ",
236"ILLEGAL ",
237"SWI impl ",
238"RTI impl ",
239"ILLEGAL ",
240"MOVE A,B ",
241"MOVE B,B ",
242"MOVE C,B ",
243"MOVE D,B ",
244"MOVE E,B ",
245"MOVE L,B ",
246"MOVE H,B ",
247"MOVE M,B ",
248
249"ADC A,B ",
250"SBC A,B ",
251"CMP A,B ",
252"IOR A,B ",
253"AND A,B ",
254"XOR A,B ",
255"BT A,B ",
256"ILLEGAL ",
257"MOVE A,C ",
258"MOVE B,C ",
259"MOVE C,C ",
260"MOVE D,C ",
261"MOVE E,C ",
262"MOVE L,C ",
263"MOVE H,C ",
264"MOVE M,C ",
265
266"ADC A,C ",
267"SBC A,C ",
268"CMP A,C ",
269"IOR A,C ",
270"AND A,C ",
271"XOR A,C ",
272"BT A,C ",
273"ILLEGAL ",
274"MOVE A,D ",
275"MOVE B,D ",
276"MOVE C,D ",
277"MOVE D,D ",
278"MOVE E,D ",
279"MOVE L,D ",
280"MOVE H,D ",
281"MOVE M,D ",
282
283"ADC A,D ",
284"SBC A,D ",
285"CMP A,D ",
286"IOR A,D ",
287"AND A,D ",
288"XOR A,D ",
289"BT A,D ",
290"LD # ",
291"MOVE A,E ",
292"MOVE B,E ",
293"MOVE C,E ",
294"MOVE D,E ",
295"MOVE E,E ",
296"MOVE L,E ",
297"MOVE H,E ",
298"MOVE M,E ",
299
300"ADC A,E ",
301"SBC A,E ",
302"CMP A,E ",
303"IOR A,E ",
304"AND A,E ",
305"XOR A,E ",
306"BT A,E ",
307"LD abs ",
308"MOVE A,L ",
309"MOVE B,L ",
310"MOVE C,L ",
311"MOVE D,L ",
312"MOVE E,L ",
313"MOVE L,L ",
314"MOVE H,L ",
315"MOVE M,L ",
316
317"ADC A,L ",
318"SBC A,L ",
319"CMP A,L ",
320"IOR A,L ",
321"AND A,L ",
322"XOR A,L ",
323"BT A,L ",
324"LD abs,X ",
325"MOVE A,H ",
326"MOVE B,H ",
327"MOVE C,H ",
328"MOVE D,H ",
329"MOVE E,H ",
330"MOVE L,H ",
331"MOVE H,H ",
332"MOVE M,H ",
333
334"ADC A,H ",
335"SBC A,H ",
336"CMP A,H ",
337"IOR A,H ",
338"AND A,H ",
339"XOR A,H ",
340"BT A,H ",
341"ILLEGAL ",
342"MOVE A,M ",
343"MOVE B,M ",
344"MOVE C,M ",
345"MOVE D,M ",
346"MOVE E,M ",
347"MOVE L,M ",
348"MOVE H,M ",
349"MOVE -,- ",
350
351"ADC A,M ",
352"SBC A,M ",
353"CMP A,M ",
354"IOR A,M ",
355"AND A,M ",
356"XOR A,M ",
357"BT A,M ",
358"ILLEGAL ",
359"ILLEGAL ",
360"ILLEGAL ",
361"JMP abs ",
362"ILLEGAL ",
363"ILLEGAL ",
364"ILLEGAL ",
365"ILLEGAL ",
366"ILLEGAL ",
367
368};
369
370////////////////////////////////////////////////////////////////////////////////
371// Simulator/Emulator (Start) //
372////////////////////////////////////////////////////////////////////////////////
373BYTE fetch()
374{
375 BYTE byte = 0;
376
377 if ((ProgramCounter >= 0) && (ProgramCounter <= MEMORY_SIZE))
378 {
379 memory_in_range = true;
380 byte = Memory[ProgramCounter];
381 ProgramCounter++;
382 }
383 else
384 {
385 memory_in_range = false;
386 }
387 return byte;
388}
389
390void set_flag_n(BYTE inReg) {
391 BYTE reg;
392 reg = inReg;
393 if ((reg & 0x80) != 0) // msbit set
394 {
395 Flags = Flags | FLAG_N;
396 }
397 else
398 {
399 Flags = Flags & (0xFF - FLAG_N);
400 }
401}
402
403
404void set_flag_v(BYTE in1, BYTE in2, BYTE out1)
405{
406 BYTE reg1in;
407 BYTE reg2in;
408 BYTE regOut;
409
410 reg1in = in1;
411 reg2in = in2;
412 regOut = out1;
413
414
415
416 if ((((reg1in & 0x80) == 0x80) && ((reg2in & 0x80) == 0x80) && ((regOut & 0x80) != 0x80)) //overflow
417
418 || (((reg1in & 0x80) != 0x80) && ((reg2in & 0x80) != 0x80) && ((regOut & 0x80) == 0x80))) //overflow
419 {
420 Flags = Flags | FLAG_V;
421 }
422
423 else
424 {
425 Flags = Flags & (0xFF - FLAG_V);
426 }
427
428
429}
430
431
432void set_flag_z(BYTE inReg) {
433 BYTE reg;
434 reg = inReg;
435 if (reg == 0) // zero set
436 {
437 Flags = Flags | FLAG_Z;
438 }
439 else
440 {
441 Flags = Flags & (0xFF - FLAG_Z);
442 }
443}
444
445
446
447
448
449void Group_1(BYTE opcode){
450 BYTE LB = 0;
451 BYTE HB = 0;
452 WORD address = 0;
453 WORD data = 0;
454 WORD param1;
455 WORD param2;
456 WORD temp_word;
457 switch (opcode) {
458 case 0xB7: //LD Immidiate
459 data = fetch();
460 Registers[REGISTER_A] = data;
461 break;
462
463 case 0xC7:
464 HB = fetch();
465 LB = fetch();
466 address += (WORD)((WORD)HB << 8) + LB;
467 if (address >= 0 && address < MEMORY_SIZE) {
468 Registers[REGISTER_A] = Memory[address];
469 }
470 break;
471
472 case 0xD7:
473 address += IndexRegister;
474 HB = fetch(); LB = fetch();
475 address += (WORD)((WORD)HB << 8) + LB;
476 if (address >= 0 && address < MEMORY_SIZE) {
477 Registers[REGISTER_A] = Memory[address];
478 }
479 break;
480
481 ///-------------ST------------///
482
483 case 0x10:
484 HB = fetch();
485 LB = fetch(); address += (WORD)((WORD)HB << 8) + LB;
486 if (address >= 0 && address < MEMORY_SIZE) {
487 Memory[address] = Registers[REGISTER_A];
488 }
489 break;
490
491 case 0x20:
492 address += IndexRegister;
493 HB = fetch();
494 LB = fetch();
495 address += (WORD)((WORD)HB << 8) + LB
496 ; if (address >= 0 && address < MEMORY_SIZE) {
497 Memory[address] = Registers[REGISTER_A];
498 }
499 break;
500
501 ////------MVI------///
502
503 case 0x2A:
504 data = fetch();
505 Registers[REGISTER_B] = data;
506 break;
507
508 case 0x2B:
509 data = fetch();
510 Registers[REGISTER_C] = data;
511 break;
512
513 case 0x2C:
514 data = fetch();
515 Registers[REGISTER_D] = data;
516 break;
517
518 case 0x2D:
519 data = fetch();
520 Registers[REGISTER_E] = data;
521 break;
522
523 case 0x2E:
524 data = fetch();
525 Registers[REGISTER_L] = data;
526 break;
527
528 case 0x2F:
529 data = fetch();
530 Registers[REGISTER_H] = data;
531 break;
532 ////----LODS-----///
533 case 0x4F:
534 data = fetch();
535 StackPointer = data << 8; StackPointer += fetch();
536 break;
537
538 case 0x5f:
539 HB = fetch();
540 LB = fetch();
541 address += (WORD)((WORD)HB << 8) + LB;
542 if (address >= 0 && address < MEMORY_SIZE - 1) {
543 StackPointer = (WORD)Memory[address] << 8;
544 StackPointer += Memory[address + 1];
545 }
546 break;
547
548 case 0x6f:
549 address += IndexRegister;
550 HB = fetch();
551 LB = fetch();
552 address += (WORD)((WORD)HB << 8) + LB;
553 if (address >= 0 && address < MEMORY_SIZE - 1) {
554 StackPointer = (WORD)Memory[address] << 8;
555 StackPointer += Memory[address + 1];
556 }
557 break;
558
559
560 /////-----ADC-----/////
561
562 case 0x90:
563 param1 = Registers[REGISTER_A];
564 param2 = Registers[REGISTER_B];
565 temp_word = (WORD)param1 + (WORD)param2;
566 if ((Flags & FLAG_C) != 0) {
567 temp_word++;
568 }
569 if (temp_word >= 0x100) {
570 Flags = Flags | FLAG_C; // Set carry flag
571 }
572 else {
573 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
574 }
575 set_flag_n((BYTE)temp_word);
576 set_flag_z((BYTE)temp_word);
577 set_flag_v(param1, param2, (BYTE)temp_word);
578 Registers[REGISTER_A] = (BYTE)temp_word;
579 break;
580
581 case 0xA0:
582 param1 = Registers[REGISTER_A];
583 param2 = Registers[REGISTER_C];
584 temp_word = (WORD)param1 + (WORD)param2;
585 if ((Flags & FLAG_C) != 0) {
586 temp_word++;
587 }
588 if (temp_word >= 0x100) {
589 Flags = Flags | FLAG_C; // Set carry flag
590 }
591 else {
592 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
593 }
594 set_flag_n((BYTE)temp_word);
595 set_flag_z((BYTE)temp_word);
596 set_flag_v(param1, param2, (BYTE)temp_word);
597 Registers[REGISTER_A] = (BYTE)temp_word;
598 break;
599
600 case 0xB0:
601 param1 = Registers[REGISTER_A];
602 param2 = Registers[REGISTER_D];
603 temp_word = (WORD)param1 + (WORD)param2;
604 if ((Flags & FLAG_C) != 0) {
605 temp_word++;
606 }
607 if (temp_word >= 0x100) {
608 Flags = Flags | FLAG_C; // Set carry flag
609 }
610 else {
611 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
612 }
613 set_flag_n((BYTE)temp_word);
614 set_flag_z((BYTE)temp_word);
615 set_flag_v(param1, param2, (BYTE)temp_word);
616 Registers[REGISTER_A] = (BYTE)temp_word;
617 break;
618
619 case 0xC0:
620 param1 = Registers[REGISTER_A];
621 param2 = Registers[REGISTER_E];
622 temp_word = (WORD)param1 + (WORD)param2;
623 if ((Flags & FLAG_C) != 0) {
624 temp_word++;
625 }
626 if (temp_word >= 0x100) {
627 Flags = Flags | FLAG_C; // Set carry flag
628 }
629 else {
630 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
631 }
632 set_flag_n((BYTE)temp_word);
633 set_flag_z((BYTE)temp_word);
634 set_flag_v(param1, param2, (BYTE)temp_word);
635 Registers[REGISTER_A] = (BYTE)temp_word;
636 break;
637
638 case 0xD0:
639 param1 = Registers[REGISTER_A];
640 param2 = Registers[REGISTER_L];
641 temp_word = (WORD)param1 + (WORD)param2;
642 if ((Flags & FLAG_C) != 0) {
643 temp_word++;
644 }
645 if (temp_word >= 0x100) {
646 Flags = Flags | FLAG_C; // Set carry flag
647 }
648 else {
649 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
650 }
651 set_flag_n((BYTE)temp_word);
652 set_flag_z((BYTE)temp_word);
653 set_flag_v(param1, param2, (BYTE)temp_word);
654 Registers[REGISTER_A] = (BYTE)temp_word;
655 break;
656
657 case 0xE0:
658 param1 = Registers[REGISTER_A];
659 param2 = Registers[REGISTER_H];
660 temp_word = (WORD)param1 + (WORD)param2;
661 if ((Flags & FLAG_C) != 0) {
662 temp_word++;
663 }
664 if (temp_word >= 0x100) {
665 Flags = Flags | FLAG_C; // Set carry flag
666 }
667 else {
668 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
669 }
670 set_flag_n((BYTE)temp_word);
671 set_flag_z((BYTE)temp_word);
672 set_flag_v(param1, param2, (BYTE)temp_word);
673 Registers[REGISTER_A] = (BYTE)temp_word;
674 break;
675
676 case 0xF0:
677 param1 = Registers[REGISTER_A];
678 param2 = Registers[REGISTER_M];
679 temp_word = (WORD)param1 + (WORD)param2;
680 if ((Flags & FLAG_C) != 0) {
681 temp_word++;
682 }
683 if (temp_word >= 0x100) {
684 Flags = Flags | FLAG_C; // Set carry flag
685 }
686 else {
687 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
688 }
689 set_flag_n((BYTE)temp_word);
690 set_flag_z((BYTE)temp_word);
691 set_flag_v(param1, param2, (BYTE)temp_word);
692 Registers[REGISTER_A] = (BYTE)temp_word;
693 break;
694
695 /////-------CMP--------/////
696
697 case 0x92:
698 param1 = Registers[REGISTER_A];
699 param2 = Registers[REGISTER_B];
700 temp_word = (WORD)param1 - (WORD)param2;
701 if (temp_word >= 0x100) {
702 Flags = Flags | FLAG_C; // Set carry flag
703 }
704 else {
705 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
706 }
707 set_flag_n((BYTE)temp_word);
708 set_flag_z((BYTE)temp_word);
709 set_flag_v(param1, param2, (BYTE)temp_word);
710 break;
711
712 case 0xA2:
713 param1 = Registers[REGISTER_A];
714 param2 = Registers[REGISTER_C];
715 temp_word = (WORD)param1 - (WORD)param2;
716 if (temp_word >= 0x100) {
717 Flags = Flags | FLAG_C; // Set carry flag
718 }
719 else {
720 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
721 }
722 set_flag_n((BYTE)temp_word);
723 set_flag_z((BYTE)temp_word);
724 set_flag_v(param1, param2, (BYTE)temp_word);
725 break;
726
727 case 0xB2:
728 param1 = Registers[REGISTER_A];
729 param2 = Registers[REGISTER_D];
730 temp_word = (WORD)param1 - (WORD)param2;
731 if (temp_word >= 0x100) {
732 Flags = Flags | FLAG_C; // Set carry flag
733 }
734 else {
735 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
736 }
737 set_flag_n((BYTE)temp_word);
738 set_flag_z((BYTE)temp_word);
739 set_flag_v(param1, param2, (BYTE)temp_word);
740 break;
741
742 case 0xC2:
743 param1 = Registers[REGISTER_A];
744 param2 = Registers[REGISTER_E];
745 temp_word = (WORD)param1 - (WORD)param2;
746 if (temp_word >= 0x100) {
747 Flags = Flags | FLAG_C; // Set carry flag
748 }
749 else {
750 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
751 }
752 set_flag_n((BYTE)temp_word);
753 set_flag_z((BYTE)temp_word);
754 set_flag_v(param1, param2, (BYTE)temp_word);
755 break;
756
757 case 0xD2:
758 param1 = Registers[REGISTER_A];
759 param2 = Registers[REGISTER_L];
760 temp_word = (WORD)param1 - (WORD)param2;
761 if (temp_word >= 0x100) {
762 Flags = Flags | FLAG_C; // Set carry flag
763 }
764 else {
765 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
766 }
767 set_flag_n((BYTE)temp_word);
768 set_flag_z((BYTE)temp_word);
769 set_flag_v(param1, param2, (BYTE)temp_word);
770 break;
771
772 case 0xE2:
773 param1 = Registers[REGISTER_A];
774 param2 = Registers[REGISTER_H];
775 temp_word = (WORD)param1 - (WORD)param2;
776 if (temp_word >= 0x100) {
777 Flags = Flags | FLAG_C; // Set carry flag
778 }
779 else {
780 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
781 }
782 set_flag_n((BYTE)temp_word);
783 set_flag_z((BYTE)temp_word);
784 set_flag_v(param1, param2, (BYTE)temp_word);
785 break;
786
787 case 0xF2:
788 param1 = Registers[REGISTER_A];
789 param2 = Registers[REGISTER_M];
790 temp_word = (WORD)param1 - (WORD)param2;
791 if (temp_word >= 0x100) {
792 Flags = Flags | FLAG_C; // Set carry flag
793 }
794 else {
795 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
796 }
797 set_flag_n((BYTE)temp_word);
798 set_flag_z((BYTE)temp_word);
799 set_flag_v(param1, param2, (BYTE)temp_word);
800 break;
801
802
803 //////-----------TSA-------------//////
804
805 case 0x75:
806 Registers[REGISTER_A] = Flags;
807 break;
808
809
810 //////-----------TAS-------------//////
811
812 case 0x74:
813 Flags = Registers[REGISTER_A];
814 break;
815
816 //////-----------SEC-------------//////
817 case 0x16:
818 Flags = Flags | FLAG_C;
819 break;
820
821 /////-----------CLC----------/////
822
823 case 0x15:
824 Flags = Flags & (0xFF - FLAG_C);
825 break;
826
827 /////----------CLI------------/////
828 case 0x17:
829 Flags = Flags & (0xFF - FLAG_I);
830 break;
831 /////----------STI------------/////
832 case 0x18:
833 Flags = Flags | FLAG_I;
834 break;
835
836 /////----------SEV------------/////
837 Flags = Flags | FLAG_V;
838
839 /////----------CLV------------/////
840 Flags = Flags & (0xFF - FLAG_V);
841
842 /////-----------PSH-----------/////
843 case 0x11:
844 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
845 Memory[StackPointer] = Registers[REGISTER_A];
846 StackPointer--;
847 }
848 break;
849
850 case 0x21:
851 Memory[StackPointer] = Flags;
852 StackPointer--;
853 break;
854
855 case 0x31:
856 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
857 Memory[StackPointer] = Registers[REGISTER_B];
858 StackPointer--;
859 }
860 break;
861
862 case 0x41:
863 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
864 Memory[StackPointer] = Registers[REGISTER_C];
865 StackPointer--;
866 }
867 break;
868
869 case 0x51:
870 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
871 Memory[StackPointer] = Registers[REGISTER_D];
872 StackPointer--;
873 }
874 break;
875
876 case 0x61:
877 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
878 Memory[StackPointer] = Registers[REGISTER_E];
879 StackPointer--;
880 }
881 break;
882
883 case 0x71:
884 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
885 Memory[StackPointer] = Registers[REGISTER_L];
886 StackPointer--;
887 }
888 break;
889
890 case 0x81:
891 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
892 Memory[StackPointer] = Registers[REGISTER_H];
893 StackPointer--;
894 }
895 break;
896
897 /////-----------POP------------////
898
899 case 0x12:
900 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
901 StackPointer ++;
902 Registers[REGISTER_A] = Memory[StackPointer];
903 }
904 break;
905
906 case 0x22:
907 StackPointer++;
908 Flags = Memory[StackPointer];
909 break;
910
911 case 0x32:
912 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
913 StackPointer++;
914 Registers[REGISTER_B] = Memory[StackPointer];
915 }
916 break;
917
918 case 0x42:
919 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
920 StackPointer++;
921 Registers[REGISTER_C] = Memory[StackPointer];
922 }
923 break;
924
925 case 0x52:
926 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
927 StackPointer++;
928 Registers[REGISTER_D] = Memory[StackPointer];
929 }
930 break;
931
932 case 0x62:
933 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
934 StackPointer++;
935 Registers[REGISTER_E] = Memory[StackPointer];
936 }
937 break;
938
939 case 0x72:
940 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
941 StackPointer++;
942 Registers[REGISTER_L] = Memory[StackPointer];
943 }
944 break;
945
946 case 0x82:
947 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
948 StackPointer++;
949 Registers[REGISTER_H] = Memory[StackPointer];
950 }
951 break;
952
953 //////------JMP------//////
954 case 0xFA:
955 HB = fetch();
956 LB = fetch();
957 address = ((WORD)HB << 8) + (WORD)LB;
958 ProgramCounter = address;
959 break;
960
961 //////-----JPR-----------////
962 case 0x33:
963 HB = fetch();
964 LB = fetch();
965 address = ((WORD)HB << 8) + (WORD)LB;
966 ProgramCounter = address;
967 break;
968
969 /////------RTN---------/////
970 case 0x0E:
971 HB = fetch();
972 LB = fetch();
973 address = ((WORD)HB << 8) + (WORD)LB;
974 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
975 StackPointer++;
976 HB = Memory[StackPointer];
977 StackPointer++;
978 LB = Memory[StackPointer];
979 }
980 ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
981 break;
982
983 /////------BRA-------/////
984
985
986
987 }
988}
989
990void Group_2_Move(BYTE opcode) {
991 switch (opcode) {
992 int destination;
993 int source;
994
995 int destReg;
996 int sourceReg;
997
998 WORD address;
999
1000 destination = opcode & 0x0F;
1001
1002 switch (destination)
1003 {
1004 case 0x08:
1005 destReg = REGISTER_A;
1006 break;
1007
1008 case 0x09:
1009 destReg = REGISTER_B;
1010 break;
1011
1012 case 0x0A:
1013 destReg = REGISTER_C;
1014 break;
1015
1016 case 0x0B:
1017 destReg = REGISTER_D;
1018 break;
1019
1020 case 0x0C:
1021 destReg = REGISTER_E;
1022 break;
1023
1024 case 0x0D:
1025 destReg = REGISTER_L;
1026 break;
1027
1028 case 0x0E:
1029 destReg = REGISTER_H;
1030 break;
1031
1032 case 0x0F:
1033 destReg = REGISTER_M;
1034 break;
1035 }
1036
1037 source = (opcode >> 4) & 0x0F;
1038
1039 switch (source)
1040 {
1041 case 0x07:
1042 sourceReg = REGISTER_A;
1043 break;
1044
1045 case 0x08:
1046 sourceReg = REGISTER_B;
1047 break;
1048
1049 case 0x09:
1050 sourceReg = REGISTER_C;
1051 break;
1052
1053 case 0x0A:
1054 sourceReg = REGISTER_D;
1055 break;
1056
1057 case 0x0B:
1058 sourceReg = REGISTER_E;
1059 break;
1060
1061 case 0x0C:
1062 sourceReg = REGISTER_L;
1063 break;
1064 case 0x0D:
1065 sourceReg = REGISTER_H;
1066 break;
1067
1068 case 0x0E:
1069 sourceReg = REGISTER_M;
1070 break;
1071 }
1072
1073 if (sourceReg == REGISTER_M)
1074 {
1075 address = (WORD)Registers[REGISTER_H] << 8 + (WORD)Registers[REGISTER_L];
1076 Registers[REGISTER_M] = Memory[address];
1077 }
1078
1079 Registers[destReg] = Registers[sourceReg];
1080
1081 if (destReg == REGISTER_M)
1082 {
1083 address = (WORD)Registers[REGISTER_H] << 8 + (WORD)Registers[REGISTER_L];
1084 Memory[address] = Registers[REGISTER_M];
1085 }
1086 break;
1087
1088 //////---------MOVE-----------//////
1089
1090
1091
1092
1093
1094
1095 }
1096}
1097
1098
1099
1100void execute(BYTE opcode)
1101{
1102 if (((opcode >= 0x78) && (opcode <= 0x7F))
1103 || ((opcode >= 0x88) && (opcode <= 0x8F))
1104 || ((opcode >= 0x98) && (opcode <= 0x9F))
1105 || ((opcode >= 0xA8) && (opcode <= 0xAF))
1106 || ((opcode >= 0xB8) && (opcode <= 0xBF))
1107 || ((opcode >= 0xC8) && (opcode <= 0xCF))
1108 || ((opcode >= 0xD8) && (opcode <= 0xDF))
1109 || ((opcode >= 0xE8) && (opcode <= 0xEF)))
1110 {
1111 Group_2_Move(opcode);
1112 }
1113 else
1114 {
1115 Group_1(opcode);
1116 }
1117}
1118
1119void emulate()
1120{
1121 BYTE opcode;
1122 int sanity;
1123 ProgramCounter = 0;
1124 halt = false;
1125 memory_in_range = true;
1126 sanity = 0;
1127
1128 printf(" A B C D E L H X SP\n");
1129 while ((!halt) && (memory_in_range)) {
1130 sanity++;
1131 if (sanity > 500) halt = true;
1132 printf("%04X ", ProgramCounter); // Print current address
1133 opcode = fetch();
1134 execute(opcode);
1135
1136 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
1137
1138 printf("%02X ", Registers[REGISTER_A]);
1139 printf("%02X ", Registers[REGISTER_B]);
1140 printf("%02X ", Registers[REGISTER_C]);
1141 printf("%02X ", Registers[REGISTER_D]);
1142 printf("%02X ", Registers[REGISTER_E]);
1143 printf("%02X ", Registers[REGISTER_L]);
1144 printf("%02X ", Registers[REGISTER_H]);
1145 printf("%04X ", IndexRegister);
1146 printf("%04X ", StackPointer); // Print Stack Pointer
1147
1148 if ((Flags & FLAG_I) == FLAG_I)
1149 {
1150 printf("I=1 ");
1151 }
1152 else
1153 {
1154 printf("I=0 ");
1155 }
1156 if ((Flags & FLAG_N) == FLAG_N)
1157 {
1158 printf("N=1 ");
1159 }
1160 else
1161 {
1162 printf("N=0 ");
1163 }
1164 if ((Flags & FLAG_V) == FLAG_V)
1165 {
1166 printf("V=1 ");
1167 }
1168 else
1169 {
1170 printf("V=0 ");
1171 }
1172 if ((Flags & FLAG_Z) == FLAG_Z)
1173 {
1174 printf("Z=1 ");
1175 }
1176 else
1177 {
1178 printf("Z=0 ");
1179 }
1180 if ((Flags & FLAG_C) == FLAG_C)
1181 {
1182 printf("C=1 ");
1183 }
1184 else
1185 {
1186 printf("C=0 ");
1187 }
1188
1189 printf("\n"); // New line
1190 }
1191
1192 printf("\n"); // New line
1193}
1194
1195
1196////////////////////////////////////////////////////////////////////////////////
1197// Simulator/Emulator (End) //
1198////////////////////////////////////////////////////////////////////////////////
1199
1200
1201void initialise_filenames() {
1202 int i;
1203
1204 for (i=0; i<MAX_FILENAME_SIZE; i++) {
1205 hex_file [i] = '\0';
1206 trc_file [i] = '\0';
1207 }
1208}
1209
1210
1211
1212
1213int find_dot_position(char *filename) {
1214 int dot_position;
1215 int i;
1216 char chr;
1217
1218 dot_position = 0;
1219 i = 0;
1220 chr = filename[i];
1221
1222 while (chr != '\0') {
1223 if (chr == '.') {
1224 dot_position = i;
1225 }
1226 i++;
1227 chr = filename[i];
1228 }
1229
1230 return (dot_position);
1231}
1232
1233
1234int find_end_position(char *filename) {
1235 int end_position;
1236 int i;
1237 char chr;
1238
1239 end_position = 0;
1240 i = 0;
1241 chr = filename[i];
1242
1243 while (chr != '\0') {
1244 end_position = i;
1245 i++;
1246 chr = filename[i];
1247 }
1248
1249 return (end_position);
1250}
1251
1252
1253bool file_exists(char *filename) {
1254 bool exists;
1255 FILE *ifp;
1256
1257 exists = false;
1258
1259 if ( ( ifp = fopen( filename, "r" ) ) != NULL ) {
1260 exists = true;
1261
1262 fclose(ifp);
1263 }
1264
1265 return (exists);
1266}
1267
1268
1269
1270void create_file(char *filename) {
1271 FILE *ofp;
1272
1273 if ( ( ofp = fopen( filename, "w" ) ) != NULL ) {
1274 fclose(ofp);
1275 }
1276}
1277
1278
1279
1280bool getline(FILE *fp, char *buffer) {
1281 bool rc;
1282 bool collect;
1283 char c;
1284 int i;
1285
1286 rc = false;
1287 collect = true;
1288
1289 i = 0;
1290 while (collect) {
1291 c = getc(fp);
1292
1293 switch (c) {
1294 case EOF:
1295 if (i > 0) {
1296 rc = true;
1297 }
1298 collect = false;
1299 break;
1300
1301 case '\n':
1302 if (i > 0) {
1303 rc = true;
1304 collect = false;
1305 buffer[i] = '\0';
1306 }
1307 break;
1308
1309 default:
1310 buffer[i] = c;
1311 i++;
1312 break;
1313 }
1314 }
1315
1316 return (rc);
1317}
1318
1319
1320
1321
1322
1323
1324void load_and_run(int args,_TCHAR** argv) {
1325 char chr;
1326 int ln;
1327 int dot_position;
1328 int end_position;
1329 long i;
1330 FILE *ifp;
1331 long address;
1332 long load_at;
1333 int code;
1334
1335 // Prompt for the .hex file
1336
1337 printf("\n");
1338 printf("Enter the hex filename (.hex): ");
1339
1340 if(args == 2){
1341 ln = 0;
1342 chr = argv[1][ln];
1343 while (chr != '\0')
1344 {
1345 if (ln < MAX_FILENAME_SIZE)
1346 {
1347 hex_file [ln] = chr;
1348 trc_file [ln] = chr;
1349 ln++;
1350 }
1351 chr = argv[1][ln];
1352 }
1353 } else {
1354 ln = 0;
1355 chr = '\0';
1356 while (chr != '\n') {
1357 chr = getchar();
1358
1359 switch(chr) {
1360 case '\n':
1361 break;
1362 default:
1363 if (ln < MAX_FILENAME_SIZE) {
1364 hex_file [ln] = chr;
1365 trc_file [ln] = chr;
1366 ln++;
1367 }
1368 break;
1369 }
1370 }
1371
1372 }
1373 // Tidy up the file names
1374
1375 dot_position = find_dot_position(hex_file);
1376 if (dot_position == 0) {
1377 end_position = find_end_position(hex_file);
1378
1379 hex_file[end_position + 1] = '.';
1380 hex_file[end_position + 2] = 'h';
1381 hex_file[end_position + 3] = 'e';
1382 hex_file[end_position + 4] = 'x';
1383 hex_file[end_position + 5] = '\0';
1384 } else {
1385 hex_file[dot_position + 0] = '.';
1386 hex_file[dot_position + 1] = 'h';
1387 hex_file[dot_position + 2] = 'e';
1388 hex_file[dot_position + 3] = 'x';
1389 hex_file[dot_position + 4] = '\0';
1390 }
1391
1392 dot_position = find_dot_position(trc_file);
1393 if (dot_position == 0) {
1394 end_position = find_end_position(trc_file);
1395
1396 trc_file[end_position + 1] = '.';
1397 trc_file[end_position + 2] = 't';
1398 trc_file[end_position + 3] = 'r';
1399 trc_file[end_position + 4] = 'c';
1400 trc_file[end_position + 5] = '\0';
1401 } else {
1402 trc_file[dot_position + 0] = '.';
1403 trc_file[dot_position + 1] = 't';
1404 trc_file[dot_position + 2] = 'r';
1405 trc_file[dot_position + 3] = 'c';
1406 trc_file[dot_position + 4] = '\0';
1407 }
1408
1409 if (file_exists(hex_file)) {
1410 // Clear Registers and Memory
1411
1412 Registers[REGISTER_A] = 0;
1413 Registers[REGISTER_B] = 0;
1414 Registers[REGISTER_C] = 0;
1415 Registers[REGISTER_D] = 0;
1416 Registers[REGISTER_E] = 0;
1417 Registers[REGISTER_L] = 0;
1418 Registers[REGISTER_H] = 0;
1419 IndexRegister = 0;
1420 Flags = 0;
1421 ProgramCounter = 0;
1422 StackPointer = 0;
1423
1424 for (i=0; i<MEMORY_SIZE; i++) {
1425 Memory[i] = 0x00;
1426 }
1427
1428 // Load hex file
1429
1430 if ( ( ifp = fopen( hex_file, "r" ) ) != NULL ) {
1431 printf("Loading file...\n\n");
1432
1433 load_at = 0;
1434
1435 while (getline(ifp, InputBuffer)) {
1436 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
1437 load_at = address;
1438 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
1439 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
1440 Memory[load_at] = (BYTE)code;
1441 }
1442 load_at++;
1443 } else {
1444 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
1445 }
1446 }
1447
1448 fclose(ifp);
1449 }
1450
1451 // Emulate
1452
1453 emulate();
1454 } else {
1455 printf("\n");
1456 printf("ERROR> Input file %s does not exist!\n", hex_file);
1457 printf("\n");
1458 }
1459}
1460
1461void building(int args, _TCHAR** argv) {
1462 char buffer[1024];
1463 load_and_run(args,argv);
1464 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",
1465 Memory[TEST_ADDRESS_1],
1466 Memory[TEST_ADDRESS_2],
1467 Memory[TEST_ADDRESS_3],
1468 Memory[TEST_ADDRESS_4],
1469 Memory[TEST_ADDRESS_5],
1470 Memory[TEST_ADDRESS_6],
1471 Memory[TEST_ADDRESS_7],
1472 Memory[TEST_ADDRESS_8],
1473 Memory[TEST_ADDRESS_9],
1474 Memory[TEST_ADDRESS_10],
1475 Memory[TEST_ADDRESS_11],
1476 Memory[TEST_ADDRESS_12]
1477 );
1478 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1479}
1480
1481
1482
1483void test_and_mark() {
1484 char buffer[1024];
1485 bool testing_complete;
1486 int len = sizeof(SOCKADDR);
1487 char chr;
1488 int i;
1489 int j;
1490 bool end_of_program;
1491 long address;
1492 long load_at;
1493 int code;
1494 int mark;
1495 int passed;
1496
1497 printf("\n");
1498 printf("Automatic Testing and Marking\n");
1499 printf("\n");
1500
1501 testing_complete = false;
1502
1503 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
1504 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1505
1506 while (!testing_complete) {
1507 memset(buffer, '\0', sizeof(buffer));
1508
1509 if (recvfrom(sock, buffer, sizeof(buffer)-1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
1510 printf("Incoming Data: %s \n", buffer);
1511
1512 //if (strcmp(buffer, "Testing complete") == 1)
1513 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
1514 testing_complete = true;
1515 printf("Current mark = %d\n", mark);
1516
1517 }else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
1518 //testing_complete = true;
1519 printf("Passed = %d\n", passed);
1520
1521 } else if (strcmp(buffer, "Error") == 0) {
1522 printf("ERROR> Testing abnormally terminated\n");
1523 testing_complete = true;
1524 } else {
1525 // Clear Registers and Memory
1526
1527 Registers[REGISTER_A] = 0;
1528 Registers[REGISTER_B] = 0;
1529 Registers[REGISTER_C] = 0;
1530 Registers[REGISTER_D] = 0;
1531 Registers[REGISTER_E] = 0;
1532 Registers[REGISTER_L] = 0;
1533 Registers[REGISTER_H] = 0;
1534 IndexRegister = 0;
1535 Flags = 0;
1536 ProgramCounter = 0;
1537 StackPointer = 0;
1538 for (i=0; i<MEMORY_SIZE; i++) {
1539 Memory[i] = 0;
1540 }
1541
1542 // Load hex file
1543
1544 i = 0;
1545 j = 0;
1546 load_at = 0;
1547 end_of_program = false;
1548 FILE *ofp;
1549 fopen_s(&ofp ,"branch.txt", "a");
1550
1551 while (!end_of_program) {
1552 chr = buffer[i];
1553 switch (chr) {
1554 case '\0':
1555 end_of_program = true;
1556
1557 case ',':
1558 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
1559 load_at = address;
1560 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
1561 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
1562 Memory[load_at] = (BYTE)code;
1563 fprintf(ofp, "%02X\n", (BYTE)code);
1564 }
1565 load_at++;
1566 } else {
1567 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
1568 }
1569 j = 0;
1570 break;
1571
1572 default:
1573 InputBuffer[j] = chr;
1574 j++;
1575 break;
1576 }
1577 i++;
1578 }
1579 fclose(ofp);
1580 // Emulate
1581
1582 if (load_at > 1) {
1583 emulate();
1584 // Send and store results
1585 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
1586 Memory[TEST_ADDRESS_1],
1587 Memory[TEST_ADDRESS_2],
1588 Memory[TEST_ADDRESS_3],
1589 Memory[TEST_ADDRESS_4],
1590 Memory[TEST_ADDRESS_5],
1591 Memory[TEST_ADDRESS_6],
1592 Memory[TEST_ADDRESS_7],
1593 Memory[TEST_ADDRESS_8],
1594 Memory[TEST_ADDRESS_9],
1595 Memory[TEST_ADDRESS_10],
1596 Memory[TEST_ADDRESS_11],
1597 Memory[TEST_ADDRESS_12]
1598 );
1599 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1600 }
1601 }
1602 }
1603 }
1604}
1605
1606
1607
1608int _tmain(int argc, _TCHAR* argv[])
1609{
1610 char chr;
1611 char dummy;
1612
1613 printf("\n");
1614 printf("Microprocessor Emulator\n");
1615 printf("UWE Computer and Network Systems Assignment 1\n");
1616 printf("\n");
1617
1618 initialise_filenames();
1619
1620 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
1621
1622 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
1623 if (!sock) {
1624 // Creation failed!
1625 }
1626
1627 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
1628 server_addr.sin_family = AF_INET;
1629 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
1630 server_addr.sin_port = htons(PORT_SERVER);
1631
1632 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
1633 client_addr.sin_family = AF_INET;
1634 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
1635 client_addr.sin_port = htons(PORT_CLIENT);
1636
1637 chr = '\0';
1638 while ((chr != 'e') && (chr != 'E'))
1639 {
1640 printf("\n");
1641 printf("Please select option\n");
1642 printf("L - Load and run a hex file\n");
1643 printf("T - Have the server test and mark your emulator\n");
1644 printf("E - Exit\n");
1645 if(argc == 2){ building(argc,argv); exit(0);}
1646 printf("Enter option: ");
1647 chr = getchar();
1648 if (chr != 0x0A)
1649 {
1650 dummy = getchar(); // read in the <CR>
1651 }
1652 printf("\n");
1653
1654 switch (chr)
1655 {
1656 case 'L':
1657 case 'l':
1658 load_and_run(argc,argv);
1659 break;
1660
1661 case 'T':
1662 case 't':
1663 test_and_mark();
1664 break;
1665
1666 default:
1667 break;
1668 }
1669 }
1670
1671 closesocket(sock);
1672 WSACleanup();
1673
1674
1675 return 0;
1676}