· 5 years ago · Feb 12, 2020, 01:50 PM
1
2
3#include "stdafx.h"
4#include <winsock2.h>
5
6#pragma comment(lib, "wsock32.lib")
7
8
9#define STUDENT_NUMBER "18022288"
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 //Add memory register
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]; //Changed from 7 to 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}
389void set_flag_z(BYTE inReg) {
390 BYTE reg;
391 reg = inReg;
392
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
403void Group_1(BYTE opcode){
404 BYTE LB = 0;
405 BYTE HB = 0;
406 WORD address = 0;
407 WORD data = 0;
408 WORD temp_word;
409 switch(opcode) {
410 case 0x10: //ST Absolute
411 HB = fetch();
412 LB = fetch();
413 address += (WORD)((WORD)HB<< 8) + LB;
414 if (address >= 0 && address < MEMORY_SIZE) {
415 Memory[address] = Registers[REGISTER_A];
416 }
417 break;
418
419 case 0x20:
420 address += IndexRegister;
421 HB = fetch();
422 LB = fetch();
423 address += (WORD)((WORD)HB << 8) + LB;
424 if (address >= 0 && address < MEMORY_SIZE) {
425 Memory[address] = Registers[REGISTER_A];
426 }
427 break;
428
429 case 0x2A: // MVI Immediate REGISTER B
430 data = fetch();
431 Registers[REGISTER_B] = data;
432 break;
433
434 case 0x2B: // MVI Immediate REGISTER C
435 data = fetch();
436 Registers[REGISTER_C] = data;
437 break;
438
439 case 0x2C: // MVI Immediate REGISTER D
440 data = fetch();
441 Registers[REGISTER_D] = data;
442 break;
443
444 case 0x2D: // MVI Immediate REGISTER E
445 data = fetch();
446 Registers[REGISTER_E] = data;
447 break;
448
449 case 0x2E: // MVI Immediate REGISTER L
450 data = fetch();
451 Registers[REGISTER_L] = data;
452 break;
453
454 case 0x2F: // MVI Immediate REGISTER H
455 data = fetch();
456 Registers[REGISTER_H] = data;
457 break;
458
459
460 case 0x90: // ADC A,B
461 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
462 if ((Flags & FLAG_C) != 0)
463 {
464 temp_word++;
465 }
466 if (temp_word >= 0x100)
467 {
468 Flags = Flags | FLAG_C; // Set carry flag
469 }
470 else
471 {
472 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
473 }
474 Registers[REGISTER_A] = (BYTE)temp_word;
475 break;
476
477 case 0xA0: // ADC A,C
478 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
479 if ((Flags & FLAG_C) != 0)
480 {
481 temp_word++;
482 }
483 if (temp_word >= 0x100)
484 {
485 Flags = Flags | FLAG_C; // Set carry flag
486 }
487 else
488 {
489 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
490 }
491 break;
492
493 case 0xB0: // ADC A,D
494 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_D];
495 if ((Flags & FLAG_C) != 0)
496 {
497 temp_word++;
498 }
499 if (temp_word >= 0x100)
500 {
501 Flags = Flags | FLAG_C; // Set carry flag
502 }
503 else
504 {
505 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
506 }
507 break;
508
509 case 0xC0: // ADC A,E
510 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_E];
511 if ((Flags & FLAG_C) != 0)
512 {
513 temp_word++;
514 }
515 if (temp_word >= 0x100)
516 {
517 Flags = Flags | FLAG_C; // Set carry flag
518 }
519 else
520 {
521 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
522 }
523 break;
524
525 case 0xD0: // ADC A,L
526 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
527 if ((Flags & FLAG_C) != 0)
528 {
529 temp_word++;
530 }
531 if (temp_word >= 0x100)
532 {
533 Flags = Flags | FLAG_C; // Set carry flag
534 }
535 else
536 {
537 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
538 }
539 break;
540
541 case 0xE0: // ADC A,H
542 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
543 if ((Flags & FLAG_C) != 0)
544 {
545 temp_word++;
546 }
547 if (temp_word >= 0x100)
548 {
549 Flags = Flags | FLAG_C; // Set carry flag
550 }
551 else
552 {
553 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
554 }
555 break;
556
557 case 0xB7: //LD Immidiate
558 data = fetch();
559 Registers[REGISTER_A] = data;
560 break;
561
562 case 0xC7: //LD Absolute
563 HB = fetch();
564 LB = fetch();
565 address += (WORD)((WORD)HB << 8) + LB;
566 if (address >= 0 && address < MEMORY_SIZE) {
567 Registers[REGISTER_A] = Memory[address];
568 }
569 break;
570
571 case 0xD7: //LD Absolute Indexed
572 address += IndexRegister;
573 HB = fetch();
574 LB = fetch();
575 address += (WORD)((WORD)HB << 8) + LB;
576 if (address >= 0 && address < MEMORY_SIZE) {
577 Registers[REGISTER_A] = Memory[address];
578 }
579 break;
580 }
581}
582
583void Group_2_Move(BYTE opcode){
584 BYTE destination = opcode >> 4;
585 BYTE source = opcode & 0x0F;
586 int destReg;
587 int sourceReg;
588
589 switch(destination) {
590 case 0x08: // MOVE Destination
591 destReg = REGISTER_A;
592 break;
593 case 0x09:
594 destReg = REGISTER_B;
595 break;
596 case 0x0A:
597 destReg = REGISTER_C;
598 break;
599 case 0x0B:
600 destReg = REGISTER_D;
601 break;
602 case 0x0C:
603 destReg = REGISTER_E;
604 break;
605 case 0x0D:
606 destReg = REGISTER_L;
607 break;
608 case 0x0E:
609 destReg = REGISTER_H;
610 break;
611 case 0x0F:
612 destReg = REGISTER_M;
613 break;
614 }
615
616 switch (source) {
617 case 0x07: //MOVE source
618 sourceReg = REGISTER_A;
619 break;
620 case 0x08:
621 sourceReg = REGISTER_B;
622 break;
623 case 0x09:
624 sourceReg = REGISTER_C;
625 break;
626 case 0x0A:
627 sourceReg = REGISTER_D;
628 break;
629 case 0x0B:
630 sourceReg = REGISTER_E;
631 break;
632 case 0x0C:
633 sourceReg = REGISTER_L;
634 break;
635 case 0x0D:
636 sourceReg = REGISTER_H;
637 break;
638 case 0x0E:
639 sourceReg = REGISTER_M;
640 break;
641 }
642 switch(opcode) {
643
644 }
645}
646void execute(BYTE opcode)
647{
648 if (((opcode >= 0x78) && (opcode <= 0x7F))
649 || ((opcode >= 0x88) && (opcode <= 0x8F))
650 || ((opcode >= 0x98) && (opcode <= 0x9F))
651 || ((opcode >= 0xA8) && (opcode <= 0xAF))
652 || ((opcode >= 0xB8) && (opcode <= 0xBF))
653 || ((opcode >= 0xC8) && (opcode <= 0xCF))
654 || ((opcode >= 0xD8) && (opcode <= 0xDF))
655 || ((opcode >= 0xE8) && (opcode <= 0xEF)))
656 {
657 Group_2_Move(opcode);
658 }
659 else
660 {
661 Group_1(opcode);
662 }
663}
664
665void emulate()
666{
667 BYTE opcode;
668
669 int sanity;
670
671 ProgramCounter = 0;
672 halt = false;
673 memory_in_range = true;
674
675 sanity = 0;
676
677 printf(" A B C D E L H X SP\n");
678
679 while ((!halt) && (memory_in_range)) {
680 sanity++;
681 if (sanity > 500) halt = true;
682 printf("%04X ", ProgramCounter); // Print current address
683 opcode = fetch();
684 execute(opcode);
685
686 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
687
688 printf("%02X ", Registers[REGISTER_A]);
689 printf("%02X ", Registers[REGISTER_B]);
690 printf("%02X ", Registers[REGISTER_C]);
691 printf("%02X ", Registers[REGISTER_D]);
692 printf("%02X ", Registers[REGISTER_E]);
693 printf("%02X ", Registers[REGISTER_L]);
694 printf("%02X ", Registers[REGISTER_H]);
695 printf("%04X ", IndexRegister);
696 printf("%04X ", StackPointer); // Print Stack Pointer
697
698 if ((Flags & FLAG_I) == FLAG_I)
699 {
700 printf("I=1 ");
701 }
702 else
703 {
704 printf("I=0 ");
705 }
706 if ((Flags & FLAG_N) == FLAG_N)
707 {
708 printf("N=1 ");
709 }
710 else
711 {
712 printf("N=0 ");
713 }
714 if ((Flags & FLAG_V) == FLAG_V)
715 {
716 printf("V=1 ");
717 }
718 else
719 {
720 printf("V=0 ");
721 }
722 if ((Flags & FLAG_Z) == FLAG_Z)
723 {
724 printf("Z=1 ");
725 }
726 else
727 {
728 printf("Z=0 ");
729 }
730 if ((Flags & FLAG_C) == FLAG_C)
731 {
732 printf("C=1 ");
733 }
734 else
735 {
736 printf("C=0 ");
737 }
738
739 printf("\n"); // New line
740 }
741
742 printf("\n"); // New line
743}
744
745
746////////////////////////////////////////////////////////////////////////////////
747// Simulator/Emulator (End) //
748////////////////////////////////////////////////////////////////////////////////
749
750
751void initialise_filenames() {
752 int i;
753
754 for (i=0; i<MAX_FILENAME_SIZE; i++) {
755 hex_file [i] = '\0';
756 trc_file [i] = '\0';
757 }
758}
759
760
761
762
763int find_dot_position(char *filename) {
764 int dot_position;
765 int i;
766 char chr;
767
768 dot_position = 0;
769 i = 0;
770 chr = filename[i];
771
772 while (chr != '\0') {
773 if (chr == '.') {
774 dot_position = i;
775 }
776 i++;
777 chr = filename[i];
778 }
779
780 return (dot_position);
781}
782
783
784int find_end_position(char *filename) {
785 int end_position;
786 int i;
787 char chr;
788
789 end_position = 0;
790 i = 0;
791 chr = filename[i];
792
793 while (chr != '\0') {
794 end_position = i;
795 i++;
796 chr = filename[i];
797 }
798
799 return (end_position);
800}
801
802
803bool file_exists(char *filename) {
804 bool exists;
805 FILE *ifp;
806
807 exists = false;
808
809 if ( ( ifp = fopen( filename, "r" ) ) != NULL ) {
810 exists = true;
811
812 fclose(ifp);
813 }
814
815 return (exists);
816}
817
818
819
820void create_file(char *filename) {
821 FILE *ofp;
822
823 if ( ( ofp = fopen( filename, "w" ) ) != NULL ) {
824 fclose(ofp);
825 }
826}
827
828
829
830bool getline(FILE *fp, char *buffer) {
831 bool rc;
832 bool collect;
833 char c;
834 int i;
835
836 rc = false;
837 collect = true;
838
839 i = 0;
840 while (collect) {
841 c = getc(fp);
842
843 switch (c) {
844 case EOF:
845 if (i > 0) {
846 rc = true;
847 }
848 collect = false;
849 break;
850
851 case '\n':
852 if (i > 0) {
853 rc = true;
854 collect = false;
855 buffer[i] = '\0';
856 }
857 break;
858
859 default:
860 buffer[i] = c;
861 i++;
862 break;
863 }
864 }
865
866 return (rc);
867}
868
869
870
871
872
873
874void load_and_run(int args,_TCHAR** argv) {
875 char chr;
876 int ln;
877 int dot_position;
878 int end_position;
879 long i;
880 FILE *ifp;
881 long address;
882 long load_at;
883 int code;
884
885 // Prompt for the .hex file
886
887 printf("\n");
888 printf("Enter the hex filename (.hex): ");
889
890 if(args == 2){
891 ln = 0;
892 chr = argv[1][ln];
893 while (chr != '\0')
894 {
895 if (ln < MAX_FILENAME_SIZE)
896 {
897 hex_file [ln] = chr;
898 trc_file [ln] = chr;
899 ln++;
900 }
901 chr = argv[1][ln];
902 }
903 } else {
904 ln = 0;
905 chr = '\0';
906 while (chr != '\n') {
907 chr = getchar();
908
909 switch(chr) {
910 case '\n':
911 break;
912 default:
913 if (ln < MAX_FILENAME_SIZE) {
914 hex_file [ln] = chr;
915 trc_file [ln] = chr;
916 ln++;
917 }
918 break;
919 }
920 }
921
922 }
923 // Tidy up the file names
924
925 dot_position = find_dot_position(hex_file);
926 if (dot_position == 0) {
927 end_position = find_end_position(hex_file);
928
929 hex_file[end_position + 1] = '.';
930 hex_file[end_position + 2] = 'h';
931 hex_file[end_position + 3] = 'e';
932 hex_file[end_position + 4] = 'x';
933 hex_file[end_position + 5] = '\0';
934 } else {
935 hex_file[dot_position + 0] = '.';
936 hex_file[dot_position + 1] = 'h';
937 hex_file[dot_position + 2] = 'e';
938 hex_file[dot_position + 3] = 'x';
939 hex_file[dot_position + 4] = '\0';
940 }
941
942 dot_position = find_dot_position(trc_file);
943 if (dot_position == 0) {
944 end_position = find_end_position(trc_file);
945
946 trc_file[end_position + 1] = '.';
947 trc_file[end_position + 2] = 't';
948 trc_file[end_position + 3] = 'r';
949 trc_file[end_position + 4] = 'c';
950 trc_file[end_position + 5] = '\0';
951 } else {
952 trc_file[dot_position + 0] = '.';
953 trc_file[dot_position + 1] = 't';
954 trc_file[dot_position + 2] = 'r';
955 trc_file[dot_position + 3] = 'c';
956 trc_file[dot_position + 4] = '\0';
957 }
958
959 if (file_exists(hex_file)) {
960 // Clear Registers and Memory
961
962 Registers[REGISTER_A] = 0;
963 Registers[REGISTER_B] = 0;
964 Registers[REGISTER_C] = 0;
965 Registers[REGISTER_D] = 0;
966 Registers[REGISTER_E] = 0;
967 Registers[REGISTER_L] = 0;
968 Registers[REGISTER_H] = 0;
969 IndexRegister = 0;
970 Flags = 0;
971 ProgramCounter = 0;
972 StackPointer = 0;
973
974 for (i=0; i<MEMORY_SIZE; i++) {
975 Memory[i] = 0x00;
976 }
977
978 // Load hex file
979
980 if ( ( ifp = fopen( hex_file, "r" ) ) != NULL ) {
981 printf("Loading file...\n\n");
982
983 load_at = 0;
984
985 while (getline(ifp, InputBuffer)) {
986 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
987 load_at = address;
988 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
989 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
990 Memory[load_at] = (BYTE)code;
991 }
992 load_at++;
993 } else {
994 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
995 }
996 }
997
998 fclose(ifp);
999 }
1000
1001 // Emulate
1002
1003 emulate();
1004 } else {
1005 printf("\n");
1006 printf("ERROR> Input file %s does not exist!\n", hex_file);
1007 printf("\n");
1008 }
1009}
1010
1011void building(int args,_TCHAR** argv){
1012 char buffer[1024];
1013 load_and_run(args,argv);
1014 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",
1015 Memory[TEST_ADDRESS_1],
1016 Memory[TEST_ADDRESS_2],
1017 Memory[TEST_ADDRESS_3],
1018 Memory[TEST_ADDRESS_4],
1019 Memory[TEST_ADDRESS_5],
1020 Memory[TEST_ADDRESS_6],
1021 Memory[TEST_ADDRESS_7],
1022 Memory[TEST_ADDRESS_8],
1023 Memory[TEST_ADDRESS_9],
1024 Memory[TEST_ADDRESS_10],
1025 Memory[TEST_ADDRESS_11],
1026 Memory[TEST_ADDRESS_12]
1027 );
1028 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1029}
1030
1031
1032
1033void test_and_mark() {
1034 char buffer[1024];
1035 bool testing_complete;
1036 int len = sizeof(SOCKADDR);
1037 char chr;
1038 int i;
1039 int j;
1040 bool end_of_program;
1041 long address;
1042 long load_at;
1043 int code;
1044 int mark;
1045 int passed;
1046
1047 printf("\n");
1048 printf("Automatic Testing and Marking\n");
1049 printf("\n");
1050
1051 testing_complete = false;
1052
1053 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
1054 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1055
1056 while (!testing_complete) {
1057 memset(buffer, '\0', sizeof(buffer));
1058
1059 if (recvfrom(sock, buffer, sizeof(buffer)-1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
1060 printf("Incoming Data: %s \n", buffer);
1061
1062 //if (strcmp(buffer, "Testing complete") == 1)
1063 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
1064 testing_complete = true;
1065 printf("Current mark = %d\n", mark);
1066
1067 }else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
1068 //testing_complete = true;
1069 printf("Passed = %d\n", passed);
1070
1071 } else if (strcmp(buffer, "Error") == 0) {
1072 printf("ERROR> Testing abnormally terminated\n");
1073 testing_complete = true;
1074 } else {
1075 // Clear Registers and Memory
1076
1077 Registers[REGISTER_A] = 0;
1078 Registers[REGISTER_B] = 0;
1079 Registers[REGISTER_C] = 0;
1080 Registers[REGISTER_D] = 0;
1081 Registers[REGISTER_E] = 0;
1082 Registers[REGISTER_L] = 0;
1083 Registers[REGISTER_H] = 0;
1084 IndexRegister = 0;
1085 Flags = 0;
1086 ProgramCounter = 0;
1087 StackPointer = 0;
1088 for (i=0; i<MEMORY_SIZE; i++) {
1089 Memory[i] = 0;
1090 }
1091
1092 // Load hex file
1093
1094 i = 0;
1095 j = 0;
1096 load_at = 0;
1097 end_of_program = false;
1098 FILE *ofp;
1099 fopen_s(&ofp ,"branch.txt", "a");
1100
1101 while (!end_of_program) {
1102 chr = buffer[i];
1103 switch (chr) {
1104 case '\0':
1105 end_of_program = true;
1106
1107 case ',':
1108 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
1109 load_at = address;
1110 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
1111 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
1112 Memory[load_at] = (BYTE)code;
1113 fprintf(ofp, "%02X\n", (BYTE)code);
1114 }
1115 load_at++;
1116 } else {
1117 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
1118 }
1119 j = 0;
1120 break;
1121
1122 default:
1123 InputBuffer[j] = chr;
1124 j++;
1125 break;
1126 }
1127 i++;
1128 }
1129 fclose(ofp);
1130 // Emulate
1131
1132 if (load_at > 1) {
1133 emulate();
1134 // Send and store results
1135 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
1136 Memory[TEST_ADDRESS_1],
1137 Memory[TEST_ADDRESS_2],
1138 Memory[TEST_ADDRESS_3],
1139 Memory[TEST_ADDRESS_4],
1140 Memory[TEST_ADDRESS_5],
1141 Memory[TEST_ADDRESS_6],
1142 Memory[TEST_ADDRESS_7],
1143 Memory[TEST_ADDRESS_8],
1144 Memory[TEST_ADDRESS_9],
1145 Memory[TEST_ADDRESS_10],
1146 Memory[TEST_ADDRESS_11],
1147 Memory[TEST_ADDRESS_12]
1148 );
1149 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1150 }
1151 }
1152 }
1153 }
1154}
1155
1156
1157
1158int _tmain(int argc, _TCHAR* argv[])
1159{
1160 char chr;
1161 char dummy;
1162
1163 printf("\n");
1164 printf("Microprocessor Emulator\n");
1165 printf("UWE Computer and Network Systems Assignment 1\n");
1166 printf("\n");
1167
1168 initialise_filenames();
1169
1170 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
1171
1172 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
1173 if (!sock) {
1174 // Creation failed!
1175 }
1176
1177 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
1178 server_addr.sin_family = AF_INET;
1179 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
1180 server_addr.sin_port = htons(PORT_SERVER);
1181
1182 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
1183 client_addr.sin_family = AF_INET;
1184 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
1185 client_addr.sin_port = htons(PORT_CLIENT);
1186
1187 chr = '\0';
1188 while ((chr != 'e') && (chr != 'E'))
1189 {
1190 printf("\n");
1191 printf("Please select option\n");
1192 printf("L - Load and run a hex file\n");
1193 printf("T - Have the server test and mark your emulator\n");
1194 printf("E - Exit\n");
1195 if(argc == 2){ building(argc,argv); exit(0);}
1196 printf("Enter option: ");
1197 chr = getchar();
1198 if (chr != 0x0A)
1199 {
1200 dummy = getchar(); // read in the <CR>
1201 }
1202 printf("\n");
1203
1204 switch (chr)
1205 {
1206 case 'L':
1207 case 'l':
1208 load_and_run(argc,argv);
1209 break;
1210
1211 case 'T':
1212 case 't':
1213 test_and_mark();
1214 break;
1215
1216 default:
1217 break;
1218 }
1219 }
1220
1221 closesocket(sock);
1222 WSACleanup();
1223
1224
1225 return 0;
1226}