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