· 9 years ago · Oct 18, 2016, 03:02 PM
1
2
3#include "stdafx.h"
4#include <winsock2.h>
5
6#pragma comment(lib, "wsock32.lib")
7
8
9#define STUDENT_NUMBER "14023371"
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
23
24SOCKADDR_IN server_addr;
25SOCKADDR_IN client_addr;
26
27SOCKET sock; // This is our socket, it is the handle to the IO address to read/write packets
28
29WSADATA data;
30
31char InputBuffer [MAX_BUFFER_SIZE];
32
33char hex_file [MAX_BUFFER_SIZE];
34char trc_file [MAX_BUFFER_SIZE];
35
36//////////////////////////
37// Registers //
38//////////////////////////
39
40#define FLAG_I 0x10
41#define FLAG_Z 0x04
42#define FLAG_N 0x02
43#define FLAG_C 0x01
44#define REGISTER_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
50#define REGISTER_M 4
51BYTE Index_Registers[2];
52
53BYTE Registers[5];
54BYTE Flags;
55WORD ProgramCounter;
56WORD StackPointer;
57
58
59////////////
60// Memory //
61////////////
62
63#define MEMORY_SIZE 65536
64
65BYTE Memory[MEMORY_SIZE];
66
67#define TEST_ADDRESS_1 0x01FA
68#define TEST_ADDRESS_2 0x01FB
69#define TEST_ADDRESS_3 0x01FC
70#define TEST_ADDRESS_4 0x01FD
71#define TEST_ADDRESS_5 0x01FE
72#define TEST_ADDRESS_6 0x01FF
73#define TEST_ADDRESS_7 0x0200
74#define TEST_ADDRESS_8 0x0201
75#define TEST_ADDRESS_9 0x0202
76#define TEST_ADDRESS_10 0x0203
77#define TEST_ADDRESS_11 0x0204
78#define TEST_ADDRESS_12 0x0205
79
80
81///////////////////////
82// Control variables //
83///////////////////////
84
85bool memory_in_range = true;
86bool halt = false;
87
88
89///////////////////////
90// Disassembly table //
91///////////////////////
92
93char opcode_mneumonics[][14] =
94{
95"ILLEGAL ",
96"DECX impl ",
97"INCX impl ",
98"DEY impl ",
99"INCY impl ",
100"CLC impl ",
101"STC impl ",
102"CLI impl ",
103"STI impl ",
104"ILLEGAL ",
105"LDAA # ",
106"LDAB # ",
107"LX #,L ",
108"LX #,L ",
109"LDX # ",
110"LDY # ",
111
112"JMP abs ",
113"JCC abs ",
114"JCS abs ",
115"JNE abs ",
116"JEQ abs ",
117"JMI abs ",
118"JPL abs ",
119"JHI abs ",
120"JLE abs ",
121"ILLEGAL ",
122"LDAA abs ",
123"LDAB abs ",
124"MVI #,L ",
125"MVI #,H ",
126"LDX abs ",
127"LDY abs ",
128
129"LODS # ",
130"JSR abs ",
131"CCC abs ",
132"CCS abs ",
133"CNE abs ",
134"CEQ abs ",
135"CMI abs ",
136"CPL abs ",
137"CHI abs ",
138"CLE abs ",
139"LDAA abs,X ",
140"LDAB abs,X ",
141"NOP impl ",
142"HLT impl ",
143"LDX abs,X ",
144"LDY abs,X ",
145
146"LODS abs ",
147"ADC A,L ",
148"SBC A,L ",
149"ADD A,L ",
150"SUB A,L ",
151"CMP A,L ",
152"OR A,L ",
153"AND A,L ",
154"XOR A,L ",
155"BIT A,L ",
156"LDAA abs,Y ",
157"LDAB abs,Y ",
158"ILLEGAL ",
159"ILLEGAL ",
160"LDX abs,Y ",
161"LDY abs,Y ",
162
163"LODS abs,X ",
164"ADC A,H ",
165"SBC A,H ",
166"ADD A,H ",
167"SUB A,H ",
168"CMP A,H ",
169"OR A,H ",
170"AND A,H ",
171"XOR A,H ",
172"BIT A,H ",
173"LDAA (ind) ",
174"LDAB (ind) ",
175"RET impl ",
176"ILLEGAL ",
177"LDX (ind) ",
178"LDY (ind) ",
179
180"LODS abs,Y ",
181"ADC A,M ",
182"SBC A,M ",
183"ADD A,M ",
184"SUB A,M ",
185"CMP A,M ",
186"OR A,M ",
187"AND A,M ",
188"XOR A,M ",
189"BIT A,M ",
190"LDAA (ind,X) ",
191"LDAB (ind,X) ",
192"SWI impl ",
193"RTI impl ",
194"LDX (ind,X) ",
195"LDY (ind,X) ",
196
197"LODS (ind) ",
198"ADC B,L ",
199"SBC B,L ",
200"ADD B,L ",
201"SUB B,L ",
202"CMP B,L ",
203"OR B,L ",
204"AND B,L ",
205"XOR B,L ",
206"BIT B,L ",
207"STOS abs ",
208"MOVE A,A ",
209"MOVE B,A ",
210"MOVE L,A ",
211"MOVE H,A ",
212"MOVE M,A ",
213
214"LODS (ind,X) ",
215"ADC B,H ",
216"SBC B,H ",
217"ADD B,H ",
218"SUB B,H ",
219"CMP B,H ",
220"OR B,H ",
221"AND B,H ",
222"XOR B,H ",
223"BIT B,H ",
224"STOS abs,X ",
225"MOVE A,B ",
226"MOVE B,B ",
227"MOVE L,B ",
228"MOVE H,B ",
229"MOVE M,B ",
230
231"ILLEGAL ",
232"ADC B,M ",
233"SBC B,M ",
234"ADD B,M ",
235"SUB B,M ",
236"CMP B,M ",
237"OR B,M ",
238"AND B,M ",
239"XOR B,M ",
240"BIT B,M ",
241"STOS abs,Y ",
242"MOVE A,L ",
243"MOVE B,L ",
244"MOVE L,L ",
245"MOVE H,L ",
246"MOVE M,L ",
247
248"ILLEGAL ",
249"ILLEGAL ",
250"ILLEGAL ",
251"SBIA # ",
252"SBIB # ",
253"CPIA # ",
254"CPIB # ",
255"ORIA # ",
256"ORIB # ",
257"ILLEGAL ",
258"STOS (ind) ",
259"MOVE A,H ",
260"MOVE B,H ",
261"MOVE L,H ",
262"MOVE H,H ",
263"MOVE M,H ",
264
265"INC abs ",
266"DEC abs ",
267"RRC abs ",
268"RLC abs ",
269"SAL abs ",
270"SAR abs ",
271"LSR abs ",
272"COM abs ",
273"ROL abs ",
274"RR abs ",
275"STOS (ind,X) ",
276"MOVE A,M ",
277"MOVE B,M ",
278"MOVE L,M ",
279"MOVE H,M ",
280"MOVE -,- ",
281
282"INC abs,X ",
283"DEC abs,X ",
284"RRC abs,X ",
285"RLC abs,X ",
286"SAL abs,X ",
287"SAR abs,X ",
288"LSR abs,X ",
289"COM abs,X ",
290"ROL abs,X ",
291"RR abs,X ",
292"STORA abs ",
293"STORB abs ",
294"STOX abs ",
295"STOY abs ",
296"PUSH ,A ",
297"POP A, ",
298
299"INC abs,Y ",
300"DEC abs,Y ",
301"RRC abs,Y ",
302"RLC abs,Y ",
303"SAL abs,Y ",
304"SAR abs,Y ",
305"LSR abs,Y ",
306"COM abs,Y ",
307"ROL abs,Y ",
308"RR abs,Y ",
309"STORA abs,X ",
310"STORB abs,X ",
311"STOX abs,X ",
312"STOY abs,X ",
313"PUSH ,B ",
314"POP B, ",
315
316"INCA A,A ",
317"DECA A,A ",
318"RRCA A,A ",
319"RLCA A,A ",
320"SALA A,A ",
321"SARA A,A ",
322"LSRA A,A ",
323"COMA A,A ",
324"ROLA A,A ",
325"RRA A,A ",
326"STORA abs,Y ",
327"STORB abs,Y ",
328"STOX abs,Y ",
329"STOY abs,Y ",
330"PUSH ,s ",
331"POP s, ",
332
333"INCB B,B ",
334"DECB B,B ",
335"RRCB B,B ",
336"RLCB B,B ",
337"SALB B,B ",
338"SARB B,B ",
339"LSRB B,B ",
340"COMB B,B ",
341"ROLB B,B ",
342"RRB B,B ",
343"STORA (ind) ",
344"STORB (ind) ",
345"STOX (ind) ",
346"STOY (ind) ",
347"PUSH ,L ",
348"POP L, ",
349
350"CAY impl ",
351"MYA impl ",
352"CSA impl ",
353"ABA impl ",
354"SBA impl ",
355"AAB impl ",
356"SAB impl ",
357"ADCP A,L ",
358"SBCP A,L ",
359"XCHG A,L ",
360"STORA (ind,X)",
361"STORB (ind,X)",
362"STOX (ind,X) ",
363"STOY (ind,X) ",
364"PUSH ,H ",
365"POP H, ",
366
367};
368
369////////////////////////////////////////////////////////////////////////////////
370// Simulator/Emulator (Start) //
371////////////////////////////////////////////////////////////////////////////////
372BYTE fetch()
373{
374 BYTE byte = 0;
375
376 if ((ProgramCounter >= 0) && (ProgramCounter <= MEMORY_SIZE))
377 {
378 memory_in_range = true;
379 byte = Memory[ProgramCounter];
380 ProgramCounter++;
381 }
382 else
383 {
384 memory_in_range = false;
385 }
386 return byte;
387}
388void set_flag_z(BYTE inReg) {
389 BYTE reg;
390 reg = inReg;
391
392 if ((reg & 0x80) != 0) // msbit set
393 {
394 Flags = Flags | FLAG_N;
395 }
396 else
397 {
398 Flags = Flags & (0xFF - FLAG_N);
399 }
400}
401
402void Group_1(BYTE opcode){
403 BYTE LB = 0;
404 BYTE HB = 0;
405 WORD address = 0;
406 WORD data = 0;
407 switch (opcode) {
408 case 0x0A: //LDAA Immidiate(#)
409 data = fetch();
410 Registers[REGISTER_A] = data; //fetch data and assign it to LDAA(REGISTER_A)
411 break;
412 case 0x01A:
413 HB = fetch();
414 LB = fetch();
415 address += (WORD)((WORD)HB << 8) + LB;
416 if (address >= 0 && address < MEMORY_SIZE) {
417 Registers[REGISTER_A] = Memory[address];
418 }
419 break;
420 case 0x02A:
421 address += Index_Registers[REGISTER_X];
422 HB = fetch();
423 LB = fetch();
424 address+= (WORD)((WORD)HB << 8) + LB;
425 if (address >= 0 && address < MEMORY_SIZE) {
426 Registers[REGISTER_A] = Memory[address];
427 }
428 break;
429 case 0x03A: //LDAA(abs,Y)
430 address += Index_Registers[REGISTER_Y];
431 HB = fetch();
432 LB = fetch();
433 address += (WORD)((WORD)HB << 8) + LB;
434 if (address >= 0 && address < MEMORY_SIZE) {
435 Registers[REGISTER_A] = Memory[address];
436 }
437 break;
438 case 0x04A: //LDAA(ind)
439 HB = fetch();
440 LB = fetch();
441 address = (WORD)((WORD)HB << 8) + LB;
442 HB = Memory[address];
443 LB = Memory[address+1];
444 address = (WORD)((WORD)HB << 8) + LB;
445 if (address >= 0 && address < MEMORY_SIZE) {
446 Registers[REGISTER_A] = Memory[address];
447 }
448 break;
449 case 0x05A: //LDAA (ind, X)
450 HB = fetch();
451 LB = fetch();
452 address = (WORD)((WORD)HB << 8) + LB;
453 HB = Memory[address];
454 LB = Memory[address + 1];
455 address = (WORD)((WORD)HB << 8) + LB;
456 address += Index_Registers[REGISTER_X];
457 if (address >= 0 && address < MEMORY_SIZE) {
458 Registers[REGISTER_A] = Memory[address];
459 }
460 break;
461 case 0xBA:
462 HB = fetch();
463 LB = fetch();
464 address += (WORD)((WORD)HB << 8) + LB;
465 if (address >= 0 && address < MEMORY_SIZE) {
466 Memory[address] = Registers[REGISTER_A];
467 }
468 break;
469 case 0xCA:
470 address += Index_Registers[REGISTER_X];
471 HB = fetch();
472 LB = fetch();
473 address += (WORD)((WORD)HB << 8) + LB;
474 if (address >= 0 && address < MEMORY_SIZE) {
475 Memory[address] = Registers[REGISTER_A];
476 }
477 break;
478 case 0xDA: //STORA (abs,Y)
479 address += Index_Registers[REGISTER_Y];
480 HB = fetch();
481 LB = fetch();
482 address += (WORD)((WORD)HB << 8) + LB;
483 if (address >= 0 && address < MEMORY_SIZE) {
484 Memory[address] = Registers[REGISTER_A];
485 }
486 break;
487 case 0xEA: //STORA (ind)
488 HB = fetch();
489 LB = fetch();
490 address = (WORD)((WORD)HB << 8) + LB;
491 HB = Memory[address];
492 LB = Memory[address + 1];
493 address = (WORD)((WORD)HB << 8) + LB;
494 if (address >= 0 && address < MEMORY_SIZE) {
495 Memory[address] = Registers[REGISTER_A];
496 }
497 break;
498 case 0xFA: //STORA (ind,X)
499 HB = fetch();
500 LB = fetch();
501 address = (WORD)((WORD)HB << 8) + LB;
502 HB = Memory[address];
503 LB = Memory[address + 1];
504 address = (WORD)((WORD)HB << 8) + LB;
505 address += Index_Registers[REGISTER_X];
506 if (address >= 0 && address < MEMORY_SIZE) {
507 Memory[address] = Registers[REGISTER_A];
508 }
509 break;
510 case 0x1C: //MOVE(#)
511 data = fetch();
512 Registers[REGISTER_L] = data;
513 break;
514 }
515
516}
517
518void Group_2_Move(BYTE opcode)
519{
520 BYTE LB = 0;
521 BYTE HB = 0;
522 WORD address = 0;
523 WORD data = 0;
524 BYTE destination = opcode >> 4;
525 BYTE source = opcode & 0x0F;
526 int destReg;
527 int sourceReg;
528 switch (destination) {
529 case 0x06:
530 destReg = REGISTER_A;
531 break;
532 case 0x07:
533 destReg = REGISTER_B;
534 break;
535 case 0x08:
536 destReg = REGISTER_L;
537 break;
538 case 0x09:
539 destReg = REGISTER_H;
540 break;
541 case 0x0A:
542 destReg = REGISTER_M;
543 break;
544 Registers[destReg] = Registers[sourceReg];
545 if (destReg == REGISTER_M) {
546 address = Registers[REGISTER_L];
547 address += (WORD)Registers[REGISTER_H] << 4;
548 if (address >= 0 && address <= MEMORY_SIZE) {
549 Memory[address] = Registers[sourceReg];
550 }
551 }
552 else {
553 Registers[destReg] = Registers[sourceReg];
554 }
555 case 0x20: //LODS(#)
556 data = fetch();
557 StackPointer = data << 8; StackPointer += fetch();
558 break;
559 case 0x30:
560 HB = fetch();
561 LB = fetch();
562 address += (WORD)((WORD)HB << 8) + LB;
563 if (address >= 0 && address < MEMORY_SIZE-1) {
564 StackPointer=(WORD)Memory[address]<<8;
565 StackPointer += Memory[address + 1];
566 }
567 break;
568 case 0x40: //LODS(abs,X)
569 address += Index_Registers[REGISTER_X];
570 HB = fetch();
571 LB = fetch();
572 address += (WORD)((WORD)HB << 8) + LB;
573 if (address >= 0 && address < MEMORY_SIZE - 1) {
574 StackPointer = (WORD)Memory[address] << 8;
575 StackPointer += Memory[address + 1];
576 }
577 break;
578 case 0x50: //LODS(abs,Y)
579 address += Index_Registers[REGISTER_Y];
580 HB = fetch();
581 LB = fetch();
582 address += (WORD)((WORD)HB << 8) + LB;
583 if (address >= 0 && address < MEMORY_SIZE - 1) {
584 StackPointer = (WORD)Memory[address] << 8;
585 StackPointer += Memory[address + 1];
586 }
587 break;
588 case 0x60://LODS(ind)
589 HB = fetch();
590 LB = fetch();
591 address = (WORD)((WORD)HB << 8) + LB;
592 HB = Memory[address];
593 LB = Memory[address + 1];
594 address = (WORD)((WORD)HB << 8) + LB;
595 if (address >= 0 && address < MEMORY_SIZE - 1) {
596 StackPointer = (WORD)Memory[address] << 8;
597 StackPointer += Memory[address + 1];
598 }
599 break;
600 case 0x70://LODS(ind,x)
601 HB = fetch();
602 LB = fetch();
603 address = (WORD)((WORD)HB << 8) + LB;
604 HB = Memory[address];
605 LB = Memory[address + 1];
606 address = (WORD)((WORD)HB << 8) + LB;
607 address += Index_Registers[REGISTER_X];
608 if (address >= 0 && address < MEMORY_SIZE - 1) {
609 StackPointer = (WORD)Memory[address] << 8;
610 StackPointer += Memory[address + 1];
611 }
612 break;
613
614 }
615
616 switch(opcode) {
617
618 default:
619 break;
620 }
621}
622
623
624void execute(BYTE opcode)
625{
626
627 if((opcode >= 0x6B) && (opcode <= 0xAF))
628 {
629 Group_2_Move(opcode);
630 }
631 else
632 {
633 Group_1(opcode);
634 }
635}
636
637void emulate()
638{
639 BYTE opcode;
640 int sanity;
641
642 ProgramCounter = 0;
643 halt = false;
644 memory_in_range = true;
645 sanity = 0;
646
647 printf(" A B L H X Y SP\n");
648
649 while ((!halt) && (memory_in_range) && (sanity < 200))
650 {
651 printf("%04X ", ProgramCounter); // Print current address
652 opcode = fetch();
653 execute(opcode);
654
655 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
656
657 printf("%02X ", Registers[REGISTER_A]);
658 printf("%02X ", Registers[REGISTER_B]);
659 printf("%02X ", Registers[REGISTER_L]);
660 printf("%02X ", Registers[REGISTER_H]);
661 printf("%02X ", Index_Registers[REGISTER_X]);
662 printf("%02X ", Index_Registers[REGISTER_Y]);
663 printf("%04X ", StackPointer); // Print Stack Pointer
664
665 if ((Flags & FLAG_I) == FLAG_I)
666 {
667 printf("I=1 ");
668 }
669 else
670 {
671 printf("I=0 ");
672 }
673 if ((Flags & FLAG_Z) == FLAG_Z)
674 {
675 printf("Z=1 ");
676 }
677 else
678 {
679 printf("Z=0 ");
680 }
681 if ((Flags & FLAG_N) == FLAG_N)
682 {
683 printf("N=1 ");
684 }
685 else
686 {
687 printf("N=0 ");
688 }
689 if ((Flags & FLAG_C) == FLAG_C)
690 {
691 printf("C=1 ");
692 }
693 else
694 {
695 printf("C=0 ");
696 }
697
698 printf("\n"); // New line
699 sanity++;
700 }
701
702 printf("\n"); // New line
703}
704
705
706////////////////////////////////////////////////////////////////////////////////
707// Simulator/Emulator (End) //
708////////////////////////////////////////////////////////////////////////////////
709
710
711void initialise_filenames() {
712 int i;
713
714 for (i=0; i<MAX_FILENAME_SIZE; i++) {
715 hex_file [i] = '\0';
716 trc_file [i] = '\0';
717 }
718}
719
720
721
722
723int find_dot_position(char *filename) {
724 int dot_position;
725 int i;
726 char chr;
727
728 dot_position = 0;
729 i = 0;
730 chr = filename[i];
731
732 while (chr != '\0') {
733 if (chr == '.') {
734 dot_position = i;
735 }
736 i++;
737 chr = filename[i];
738 }
739
740 return (dot_position);
741}
742
743
744int find_end_position(char *filename) {
745 int end_position;
746 int i;
747 char chr;
748
749 end_position = 0;
750 i = 0;
751 chr = filename[i];
752
753 while (chr != '\0') {
754 end_position = i;
755 i++;
756 chr = filename[i];
757 }
758
759 return (end_position);
760}
761
762
763bool file_exists(char *filename) {
764 bool exists;
765 FILE *ifp;
766
767 exists = false;
768
769 if ( ( ifp = fopen( filename, "r" ) ) != NULL )
770 {
771 exists = true;
772
773 fclose(ifp);
774 }
775
776 return (exists);
777}
778
779
780
781void create_file(char *filename) {
782 FILE *ofp;
783
784 if ( ( ofp = fopen( filename, "w" ) ) != NULL ) {
785 fclose(ofp);
786 }
787}
788
789
790
791bool getline(FILE *fp, char *buffer) {
792 bool rc;
793 bool collect;
794 char c;
795 int i;
796
797 rc = false;
798 collect = true;
799
800 i = 0;
801 while (collect) {
802 c = getc(fp);
803
804 switch (c) {
805 case EOF:
806 if (i > 0) {
807 rc = true;
808 }
809 collect = false;
810 break;
811
812 case '\n':
813 if (i > 0) {
814 rc = true;
815 collect = false;
816 buffer[i] = '\0';
817 }
818 break;
819
820 default:
821 buffer[i] = c;
822 i++;
823 break;
824 }
825 }
826
827 return (rc);
828}
829
830
831
832
833
834
835void load_and_run(int args,_TCHAR** argv) {
836 char chr;
837 int ln;
838 int dot_position;
839 int end_position;
840 long i;
841 FILE *ifp;
842 long address;
843 long load_at;
844 int code;
845
846 // Prompt for the .hex file
847
848 printf("\n");
849 printf("Enter the hex filename (.hex): ");
850
851 if(args == 2){
852 ln = 0;
853 chr = argv[1][ln];
854 while (chr != '\0')
855 {
856 if (ln < MAX_FILENAME_SIZE)
857 {
858 hex_file [ln] = chr;
859 trc_file [ln] = chr;
860 ln++;
861 }
862 chr = argv[1][ln];
863 }
864 } else {
865 ln = 0;
866 chr = '\0';
867 while (chr != '\n') {
868 chr = getchar();
869
870 switch(chr) {
871 case '\n':
872 break;
873 default:
874 if (ln < MAX_FILENAME_SIZE) {
875 hex_file [ln] = chr;
876 trc_file [ln] = chr;
877 ln++;
878 }
879 break;
880 }
881 }
882
883 }
884 // Tidy up the file names
885
886 dot_position = find_dot_position(hex_file);
887 if (dot_position == 0) {
888 end_position = find_end_position(hex_file);
889
890 hex_file[end_position + 1] = '.';
891 hex_file[end_position + 2] = 'h';
892 hex_file[end_position + 3] = 'e';
893 hex_file[end_position + 4] = 'x';
894 hex_file[end_position + 5] = '\0';
895 } else {
896 hex_file[dot_position + 0] = '.';
897 hex_file[dot_position + 1] = 'h';
898 hex_file[dot_position + 2] = 'e';
899 hex_file[dot_position + 3] = 'x';
900 hex_file[dot_position + 4] = '\0';
901 }
902
903 dot_position = find_dot_position(trc_file);
904 if (dot_position == 0) {
905 end_position = find_end_position(trc_file);
906
907 trc_file[end_position + 1] = '.';
908 trc_file[end_position + 2] = 't';
909 trc_file[end_position + 3] = 'r';
910 trc_file[end_position + 4] = 'c';
911 trc_file[end_position + 5] = '\0';
912 } else {
913 trc_file[dot_position + 0] = '.';
914 trc_file[dot_position + 1] = 't';
915 trc_file[dot_position + 2] = 'r';
916 trc_file[dot_position + 3] = 'c';
917 trc_file[dot_position + 4] = '\0';
918 }
919
920 if (file_exists(hex_file)) {
921 // Clear Registers and Memory
922
923 Registers[REGISTER_A] = 0;
924 Registers[REGISTER_B] = 0;
925 Registers[REGISTER_L] = 0;
926 Registers[REGISTER_H] = 0;
927 Index_Registers[REGISTER_X] = 0;
928 Index_Registers[REGISTER_Y] = 0;
929 Flags = 0;
930 ProgramCounter = 0;
931 StackPointer = 0;
932
933 for (i=0; i<MEMORY_SIZE; i++) {
934 Memory[i] = 0x00;
935 }
936
937 // Load hex file
938
939 if ( ( ifp = fopen( hex_file, "r" ) ) != NULL ) {
940 printf("Loading file...\n\n");
941
942 load_at = 0;
943
944 while (getline(ifp, InputBuffer)) {
945 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
946 load_at = address;
947 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
948 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
949 Memory[load_at] = (BYTE)code;
950 }
951 load_at++;
952 } else {
953 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
954 }
955 }
956
957 fclose(ifp);
958 }
959
960 // Emulate
961
962 emulate();
963 } else {
964 printf("\n");
965 printf("ERROR> Input file %s does not exist!\n", hex_file);
966 printf("\n");
967 }
968}
969
970void building(int args,_TCHAR** argv)
971{
972 char buffer[1024];
973 load_and_run(args,argv);
974 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",
975 Memory[TEST_ADDRESS_1],
976 Memory[TEST_ADDRESS_2],
977 Memory[TEST_ADDRESS_3],
978 Memory[TEST_ADDRESS_4],
979 Memory[TEST_ADDRESS_5],
980 Memory[TEST_ADDRESS_6],
981 Memory[TEST_ADDRESS_7],
982 Memory[TEST_ADDRESS_8],
983 Memory[TEST_ADDRESS_9],
984 Memory[TEST_ADDRESS_10],
985 Memory[TEST_ADDRESS_11],
986 Memory[TEST_ADDRESS_12]
987 );
988 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
989}
990
991
992
993void test_and_mark() {
994 char buffer[1024];
995 bool testing_complete;
996 int len = sizeof(SOCKADDR);
997 char chr;
998 int i;
999 int j;
1000 bool end_of_program;
1001 long address;
1002 long load_at;
1003 int code;
1004 int mark;
1005 int passed;
1006
1007 printf("\n");
1008 printf("Automatic Testing and Marking\n");
1009 printf("\n");
1010
1011 testing_complete = false;
1012
1013 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
1014 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1015
1016 while (!testing_complete) {
1017 memset(buffer, '\0', sizeof(buffer));
1018
1019 if (recvfrom(sock, buffer, sizeof(buffer)-1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
1020 printf("Incoming Data: %s \n", buffer);
1021
1022 //if (strcmp(buffer, "Testing complete") == 1)
1023 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
1024 testing_complete = true;
1025 printf("Current mark = %d\n", mark);
1026
1027 }else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
1028 //testing_complete = true;
1029 printf("Passed = %d\n", passed);
1030
1031 } else if (strcmp(buffer, "Error") == 0) {
1032 printf("ERROR> Testing abnormally terminated\n");
1033 testing_complete = true;
1034 } else {
1035 // Clear Registers and Memory
1036
1037 Registers[REGISTER_A] = 0;
1038 Registers[REGISTER_B] = 0;
1039 Registers[REGISTER_L] = 0;
1040 Registers[REGISTER_H] = 0;
1041 Index_Registers[REGISTER_X] = 0;
1042 Index_Registers[REGISTER_Y] = 0;
1043 Flags = 0;
1044 ProgramCounter = 0;
1045 StackPointer = 0;
1046 for (i=0; i<MEMORY_SIZE; i++) {
1047 Memory[i] = 0;
1048 }
1049
1050 // Load hex file
1051
1052 i = 0;
1053 j = 0;
1054 load_at = 0;
1055 end_of_program = false;
1056 FILE *ofp;
1057 fopen_s(&ofp ,"branch.txt", "a");
1058
1059 while (!end_of_program) {
1060 chr = buffer[i];
1061 switch (chr) {
1062 case '\0':
1063 end_of_program = true;
1064
1065 case ',':
1066 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
1067 load_at = address;
1068 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
1069 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
1070 Memory[load_at] = (BYTE)code;
1071 fprintf(ofp, "%02X\n", (BYTE)code);
1072 }
1073 load_at++;
1074 } else {
1075 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
1076 }
1077 j = 0;
1078 break;
1079
1080 default:
1081 InputBuffer[j] = chr;
1082 j++;
1083 break;
1084 }
1085 i++;
1086 }
1087 fclose(ofp);
1088 // Emulate
1089
1090 if (load_at > 1) {
1091 emulate();
1092 // Send and store results
1093 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
1094 Memory[TEST_ADDRESS_1],
1095 Memory[TEST_ADDRESS_2],
1096 Memory[TEST_ADDRESS_3],
1097 Memory[TEST_ADDRESS_4],
1098 Memory[TEST_ADDRESS_5],
1099 Memory[TEST_ADDRESS_6],
1100 Memory[TEST_ADDRESS_7],
1101 Memory[TEST_ADDRESS_8],
1102 Memory[TEST_ADDRESS_9],
1103 Memory[TEST_ADDRESS_10],
1104 Memory[TEST_ADDRESS_11],
1105 Memory[TEST_ADDRESS_12]
1106 );
1107 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1108 }
1109 }
1110 }
1111 }
1112}
1113
1114
1115
1116int _tmain(int argc, _TCHAR* argv[])
1117{
1118 char chr;
1119 char dummy;
1120
1121 printf("\n");
1122 printf("Microprocessor Emulator\n");
1123 printf("UWE Computer and Network Systems Assignment 1\n");
1124 printf("\n");
1125
1126 initialise_filenames();
1127
1128 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
1129
1130 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
1131 if (!sock) {
1132 // Creation failed!
1133 }
1134
1135 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
1136 server_addr.sin_family = AF_INET;
1137 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
1138 server_addr.sin_port = htons(PORT_SERVER);
1139
1140 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
1141 client_addr.sin_family = AF_INET;
1142 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
1143 client_addr.sin_port = htons(PORT_CLIENT);
1144
1145 chr = '\0';
1146 while ((chr != 'e') && (chr != 'E'))
1147 {
1148 printf("\n");
1149 printf("Please select option\n");
1150 printf("L - Load and run a hex file\n");
1151 printf("T - Have the server test and mark your emulator\n");
1152 printf("E - Exit\n");
1153 if(argc == 2){ building(argc,argv); exit(0);}
1154 printf("Enter option: ");
1155 chr = getchar();
1156 if (chr != 0x0A)
1157 {
1158 dummy = getchar(); // read in the <CR>
1159 }
1160 printf("\n");
1161
1162 switch (chr)
1163 {
1164 case 'L':
1165 case 'l':
1166 load_and_run(argc,argv);
1167 break;
1168
1169 case 'T':
1170 case 't':
1171 test_and_mark();
1172 break;
1173
1174 default:
1175 break;
1176 }
1177 }
1178
1179 closesocket(sock);
1180 WSACleanup();
1181
1182
1183 return 0;
1184}