· 8 years ago · Feb 06, 2018, 05:44 PM
1
2
3#include "stdafx.h"
4#include <winsock2.h>
5
6#pragma comment(lib, "wsock32.lib")
7
8
9#define STUDENT_NUMBER "17043574"
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
374BYTE fetch()
375{
376 BYTE byte = 0;
377
378 if ((ProgramCounter >= 0) && (ProgramCounter <= MEMORY_SIZE))
379 {
380 memory_in_range = true;
381 byte = Memory[ProgramCounter];
382 ProgramCounter++;
383 }
384 else
385 {
386 memory_in_range = false;
387 }
388 return byte;
389}
390
391
392void set_flag_n(BYTE inReg)
393{
394 BYTE reg;
395 reg = inReg;
396
397 if ((reg & 0x80) != 0) // msbit set
398 {
399 Flags = Flags | FLAG_N;
400 }
401 else
402 {
403 Flags = Flags & (0xFF - FLAG_N);
404 }
405}
406
407void set_flag_z(BYTE inReg)
408{
409
410}
411
412void set_flag_v(BYTE in1, BYTE in2, BYTE out1)
413{
414 BYTE reg1in;
415 BYTE reg2in;
416 BYTE regOut;
417 reg1in = in1;
418 reg2in = in2;
419 regOut = out1;
420 //Add code for overflow flag here (ASK PAL LEADERS)
421}
422
423void Group_1(BYTE opcode)
424{
425 BYTE LB = 0;
426 BYTE HB = 0;
427 WORD address = 0;
428 WORD data = 0;
429 WORD temp_word = 0;
430
431 switch (opcode)
432 {
433 case 0x90: //LDA Immed
434 data = fetch();
435 Registers[REGISTER_A] = data;
436
437 break;
438
439 case 0xA0: //LDA Abs
440 HB = fetch();
441 LB = fetch();
442 address += (WORD)((WORD)HB << 8) + LB;
443 if (address >= 0 && address < MEMORY_SIZE) {
444 Registers[REGISTER_A] = Memory[address];
445 }
446
447 break;
448
449 case 0xB0: //LDA Abs Index X
450 address += Index_Registers[REGISTER_X];
451 HB = fetch();
452 LB = fetch();
453 address += (WORD)((WORD)HB << 8) + LB;
454 if (address >= 0 && address < MEMORY_SIZE) {
455 Registers[REGISTER_A] = Memory[address];
456 }
457
458 break;
459
460 case 0xC0: //LDA Abs Index Y
461 address += Index_Registers[REGISTER_Y];
462 HB = fetch();
463 LB = fetch();
464 address += (WORD)((WORD)HB << 8) + LB;
465 if (address >= 0 && address < MEMORY_SIZE) {
466 Registers[REGISTER_A] = Memory[address];
467 }
468
469 break;
470
471 case 0xD0: //LDA Abs Index XY
472 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
473 HB = fetch();
474 LB = fetch();
475 address += (WORD)((WORD)HB << 8) + LB;
476 if (address >= 0 && address < MEMORY_SIZE) {
477 Registers[REGISTER_A] = Memory[address];
478 }
479
480 break;
481
482 case 0xE0: //LDA Ind XY
483 HB = fetch();
484 LB = fetch();
485 address = (WORD)((WORD)HB << 8) + LB;
486 HB = Memory[address];
487 LB = Memory[address + 1];
488 address = (WORD)((WORD)HB << 8) + LB;
489 address += Index_Registers[REGISTER_X];
490 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8);
491 if (address >= 0 && address < MEMORY_SIZE) {
492 Registers[REGISTER_A] = Memory[address];
493 }
494
495 break;
496
497
498 case 0xAC: //STO Abs
499 HB = fetch();
500 LB = fetch();
501 address += (WORD)((WORD)HB << 8) + LB;
502 if (address >= 0 && address < MEMORY_SIZE) {
503 Memory[address] = Registers[REGISTER_A];
504 }
505
506 break;
507
508 case 0xBC: //STO Abs Index X
509 address += Index_Registers[REGISTER_X];
510 HB = fetch();
511 LB = fetch();
512 address += (WORD)((WORD)HB << 8) + LB;
513 if (address >= 0 && address < MEMORY_SIZE) {
514 Memory[address] = Registers[REGISTER_A];
515 }
516
517 break;
518
519 case 0xCC: //STO Abs Index Y
520 address += Index_Registers[REGISTER_Y];
521 HB = fetch();
522 LB = fetch();
523 address += (WORD)((WORD)HB << 8) + LB;
524 if (address >= 0 && address < MEMORY_SIZE) {
525 Memory[address] = Registers[REGISTER_A];
526 }
527
528 break;
529
530 case 0xDC: //STO Abs Index XY
531 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
532 HB = fetch();
533 LB = fetch();
534 address += (WORD)((WORD)HB << 8) + LB;
535 if (address >= 0 && address < MEMORY_SIZE) {
536 Memory[address] = Registers[REGISTER_A];
537 }
538
539 break;
540
541 case 0xEC: //STO Ind XY
542 HB = fetch();
543 LB = fetch();
544 address = (WORD)((WORD)HB << 8) + LB;
545 HB = Memory[address];
546 LB = Memory[address + 1];
547 address = (WORD)((WORD)HB << 8) + LB;
548 address += Index_Registers[REGISTER_X];
549 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8);
550 if (address >= 0 && address < MEMORY_SIZE) {
551 Memory[address] = Registers[REGISTER_A];
552 }
553
554 break;
555
556
557 case 0x06: //MV Register B
558 data = fetch();
559 Registers[REGISTER_A] = data;
560
561 break;
562
563 case 0x07: //MV Register B
564 data = fetch();
565 Registers[REGISTER_B] = data;
566
567 break;
568
569 case 0x08: //MV Register C
570 data = fetch();
571 Registers[REGISTER_C] = data;
572
573 break;
574
575 case 0x09: //MV Register D
576 data = fetch();
577 Registers[REGISTER_D] = data;
578
579 break;
580
581 case 0x0A: //MV Register E
582 data = fetch();
583 Registers[REGISTER_E] = data;
584
585 break;
586
587 case 0x0B: //MV Register F
588 data = fetch();
589 Registers[REGISTER_F] = data;
590
591 break;
592
593
594 case 0x9D: //LODS Immed
595 data = fetch();
596 StackPointer = data << 8;
597 StackPointer += fetch();
598
599 break;
600
601 case 0xAD: //LODS Abs
602 HB = fetch();
603 LB = fetch();
604 address = (WORD)((WORD)HB << 8) + LB;
605 if (address >= 0 && address < MEMORY_SIZE - 1) {
606 StackPointer = (WORD)Memory[address] << 8;
607 StackPointer += Memory[address + 1];
608 }
609
610 break;
611
612 case 0xBD: //LODS Abs Index X
613 address += Index_Registers[REGISTER_X];
614 HB = fetch();
615 LB = fetch();
616 address = (WORD)((WORD)HB << 8) + LB;
617 if (address >= 0 && address < MEMORY_SIZE - 1) {
618 StackPointer = (WORD)Memory[address] << 8;
619 StackPointer += Memory[address + 1];
620 }
621
622 break;
623
624 case 0xCD: //LODS Abs Index Y
625 address += Index_Registers[REGISTER_Y];
626 HB = fetch();
627 LB = fetch();
628 address = (WORD)((WORD)HB << 8) + LB;
629 if (address >= 0 && address < MEMORY_SIZE - 1) {
630 StackPointer = (WORD)Memory[address] << 8;
631 StackPointer += Memory[address + 1];
632 }
633
634 break;
635
636 case 0xDD: //LODS Abs Index 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
646 break;
647
648 case 0xED: //LODS Ind Index XY
649 HB = fetch();
650 LB = fetch();
651 address = (WORD)((WORD)HB << 8) + LB;
652 HB = Memory[address];
653 LB = Memory[address + 1];
654 address = (WORD)((WORD)HB << 8) + LB;
655 address += Index_Registers[REGISTER_X];
656 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8);
657 if (address >= 0 && address < MEMORY_SIZE - 1) {
658 StackPointer = (WORD)Memory[address] << 8;
659 StackPointer += Memory[address + 1];
660 }
661
662 break;
663
664
665 case 0x23: //ADD AB
666 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
667 if ((Flags & FLAG_C) != 0) {
668 temp_word++;
669 }
670
671 if (temp_word >= 0x100) {
672 //Set carry flag
673 Flags = Flags | FLAG_C;
674 }
675 else {
676 //Clear carry flag
677 Flags = Flags & (0xFF - FLAG_C);
678 }
679 set_flag_n((BYTE)temp_word);
680 set_flag_z((BYTE)temp_word);
681 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_B], (BYTE)temp_word);
682 Registers[REGISTER_A] = (BYTE)temp_word; //Copy result back into accumulator
683
684 break;
685
686 case 0x33: //ADD AC
687 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
688 if ((Flags & FLAG_C) != 0) {
689 temp_word++;
690 }
691
692 if (temp_word >= 0x100) {
693 //Set carry flag
694 Flags = Flags | FLAG_C;
695 }
696 else {
697 //Clear carry flag
698 Flags = Flags & (0xFF - FLAG_C);
699 }
700 set_flag_n((BYTE)temp_word);
701 set_flag_z((BYTE)temp_word);
702 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_C], (BYTE)temp_word);
703 Registers[REGISTER_A] = (BYTE)temp_word;
704
705 break;
706
707 case 0x43: //ADD AD
708 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_D];
709 if ((Flags & FLAG_C) != 0) {
710 temp_word++;
711 }
712
713 if (temp_word >= 0x100) {
714 //Set carry flag
715 Flags = Flags | FLAG_C;
716 }
717 else {
718 //Clear carry flag
719 Flags = Flags & (0xFF - FLAG_C);
720 }
721 set_flag_n((BYTE)temp_word);
722 set_flag_z((BYTE)temp_word);
723 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_D], (BYTE)temp_word);
724 Registers[REGISTER_A] = (BYTE)temp_word;
725
726 break;
727
728 case 0x53: //ADD AE
729 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_E];
730 if ((Flags & FLAG_C) != 0) {
731 temp_word++;
732 }
733
734 if (temp_word >= 0x100) {
735 //Set carry flag
736 Flags = Flags | FLAG_C;
737 }
738 else {
739 //Clear carry flag
740 Flags = Flags & (0xFF - FLAG_C);
741 }
742 set_flag_n((BYTE)temp_word);
743 set_flag_z((BYTE)temp_word);
744 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_E], (BYTE)temp_word);
745 Registers[REGISTER_A] = (BYTE)temp_word;
746
747 break;
748
749 case 0x63: //ADD AF
750 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_F];
751 if ((Flags & FLAG_C) != 0) {
752 temp_word++;
753 }
754
755 if (temp_word >= 0x100) {
756 //Set carry flag
757 Flags = Flags | FLAG_C;
758 }
759 else {
760 //Clear carry flag
761 Flags = Flags & (0xFF - FLAG_C);
762 }
763 set_flag_n((BYTE)temp_word);
764 set_flag_z((BYTE)temp_word);
765 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_F], (BYTE)temp_word);
766 Registers[REGISTER_A] = (BYTE)temp_word;
767
768 break;
769
770
771 case 0x25: //CMP AB
772 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
773 if ((Flags & FLAG_C) != 0) {
774 temp_word++;
775 }
776
777 if (temp_word >= 0x100) {
778 //Set carry flag
779 Flags = Flags | FLAG_C;
780 }
781 else {
782 //Clear carry flag
783 Flags = Flags & (0xFF - FLAG_C);
784 }
785 set_flag_n((BYTE)temp_word);
786 set_flag_z((BYTE)temp_word);
787 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_B], (BYTE)temp_word);
788
789 break;
790
791 case 0x35: //CMP AC
792 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
793 if ((Flags & FLAG_C) != 0) {
794 temp_word++;
795 }
796
797 if (temp_word >= 0x100) {
798 //Set carry flag
799 Flags = Flags | FLAG_C;
800 }
801 else {
802 //Clear carry flag
803 Flags = Flags & (0xFF - FLAG_C);
804 }
805 set_flag_n((BYTE)temp_word);
806 set_flag_z((BYTE)temp_word);
807 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_C], (BYTE)temp_word);
808
809 break;
810
811 case 0x45: //CMP AD
812 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
813 if ((Flags & FLAG_C) != 0) {
814 temp_word++;
815 }
816
817 if (temp_word >= 0x100) {
818 //Set carry flag
819 Flags = Flags | FLAG_C;
820 }
821 else {
822 //Clear carry flag
823 Flags = Flags & (0xFF - FLAG_C);
824 }
825 set_flag_n((BYTE)temp_word);
826 set_flag_z((BYTE)temp_word);
827 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_D], (BYTE)temp_word);
828
829 break;
830
831 case 0x55: //CMP AE
832 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
833 if ((Flags & FLAG_C) != 0) {
834 temp_word++;
835 }
836
837 if (temp_word >= 0x100) {
838 //Set carry flag
839 Flags = Flags | FLAG_C;
840 }
841 else {
842 //Clear carry flag
843 Flags = Flags & (0xFF - FLAG_C);
844 }
845 set_flag_n((BYTE)temp_word);
846 set_flag_z((BYTE)temp_word);
847 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_E], (BYTE)temp_word);
848
849 break;
850
851 case 0x65: //CMP AF
852 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_F];
853 if ((Flags & FLAG_C) != 0) {
854 temp_word++;
855 }
856
857 if (temp_word >= 0x100) {
858 //Set carry flag
859 Flags = Flags | FLAG_C;
860 }
861 else {
862 //Clear carry flag
863 Flags = Flags & (0xFF - FLAG_C);
864 }
865 set_flag_n((BYTE)temp_word);
866 set_flag_z((BYTE)temp_word);
867 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_F], (BYTE)temp_word);
868
869 break;
870
871
872 case 0x0F: //CSA
873 Registers[REGISTER_A] = Flags;
874
875 break;
876 }
877}
878
879void Group_2_Move(BYTE opcode)
880{
881 BYTE source = opcode >> 4;
882 BYTE destination = opcode & 0x0F;
883 int destReg = 0;
884 int sourceReg = 0;
885
886 switch (destination) //MV Destination
887 {
888 case 0x0A:
889 destReg = REGISTER_A;
890
891 break;
892
893 case 0x0B:
894 destReg = REGISTER_B;
895
896 break;
897
898 case 0x0C:
899 destReg = REGISTER_C;
900
901 break;
902
903 case 0x0D:
904 destReg = REGISTER_D;
905
906 break;
907
908 case 0x0E:
909 destReg = REGISTER_E;
910
911 break;
912
913 case 0x0F:
914 destReg = REGISTER_F;
915
916 break;
917 }
918
919 switch (source) //MV Source
920 {
921 case 0x02:
922 sourceReg = REGISTER_A;
923
924 break;
925
926 case 0x03:
927 sourceReg = REGISTER_B;
928
929 break;
930
931 case 0x04:
932 sourceReg = REGISTER_C;
933
934 break;
935
936 case 0x05:
937 sourceReg = REGISTER_D;
938
939 break;
940
941 case 0x06:
942 sourceReg = REGISTER_E;
943
944 break;
945
946 case 0x07:
947 sourceReg = REGISTER_F;
948
949 break;
950
951 }
952 Registers[destReg] = Registers[sourceReg];
953}
954
955
956void execute(BYTE opcode)
957{
958
959 if ((opcode >= 0x2A) && (opcode <= 0x7F))
960 {
961 Group_2_Move(opcode);
962 }
963 else
964 {
965 Group_1(opcode);
966 }
967}
968
969void emulate()
970{
971 BYTE opcode;
972 int sanity;
973
974 sanity = 0;
975 ProgramCounter = 0;
976 halt = false;
977 memory_in_range = true;
978
979 printf(" A B C D E F X Y SP\n");
980
981 while ((!halt) && (memory_in_range)) {
982 sanity++;
983 if (sanity > 500) halt = true;
984 printf("%04X ", ProgramCounter); // Print current address
985 opcode = fetch();
986 execute(opcode);
987
988 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
989
990 printf("%02X ", Registers[REGISTER_A]);
991 printf("%02X ", Registers[REGISTER_B]);
992 printf("%02X ", Registers[REGISTER_C]);
993 printf("%02X ", Registers[REGISTER_D]);
994 printf("%02X ", Registers[REGISTER_E]);
995 printf("%02X ", Registers[REGISTER_F]);
996 printf("%02X ", Index_Registers[REGISTER_X]);
997 printf("%02X ", Index_Registers[REGISTER_Y]);
998 printf("%04X ", StackPointer); // Print Stack Pointer
999
1000 if ((Flags & FLAG_I) == FLAG_I)
1001 {
1002 printf("I=1 ");
1003 }
1004 else
1005 {
1006 printf("I=0 ");
1007 }
1008 if ((Flags & FLAG_V) == FLAG_V)
1009 {
1010 printf("V=1 ");
1011 }
1012 else
1013 {
1014 printf("V=0 ");
1015 }
1016 if ((Flags & FLAG_N) == FLAG_N)
1017 {
1018 printf("N=1 ");
1019 }
1020 else
1021 {
1022 printf("N=0 ");
1023 }
1024 if ((Flags & FLAG_Z) == FLAG_Z)
1025 {
1026 printf("Z=1 ");
1027 }
1028 else
1029 {
1030 printf("Z=0 ");
1031 }
1032 if ((Flags & FLAG_C) == FLAG_C)
1033 {
1034 printf("C=1 ");
1035 }
1036 else
1037 {
1038 printf("C=0 ");
1039 }
1040
1041 printf("\n"); // New line
1042 }
1043
1044 printf("\n"); // New line
1045}
1046
1047
1048////////////////////////////////////////////////////////////////////////////////
1049// Simulator/Emulator (End) //
1050////////////////////////////////////////////////////////////////////////////////
1051
1052
1053void initialise_filenames() {
1054 int i;
1055
1056 for (i = 0; i<MAX_FILENAME_SIZE; i++) {
1057 hex_file[i] = '\0';
1058 trc_file[i] = '\0';
1059 }
1060}
1061
1062
1063
1064
1065int find_dot_position(char *filename) {
1066 int dot_position;
1067 int i;
1068 char chr;
1069
1070 dot_position = 0;
1071 i = 0;
1072 chr = filename[i];
1073
1074 while (chr != '\0') {
1075 if (chr == '.') {
1076 dot_position = i;
1077 }
1078 i++;
1079 chr = filename[i];
1080 }
1081
1082 return (dot_position);
1083}
1084
1085
1086int find_end_position(char *filename) {
1087 int end_position;
1088 int i;
1089 char chr;
1090
1091 end_position = 0;
1092 i = 0;
1093 chr = filename[i];
1094
1095 while (chr != '\0') {
1096 end_position = i;
1097 i++;
1098 chr = filename[i];
1099 }
1100
1101 return (end_position);
1102}
1103
1104
1105bool file_exists(char *filename) {
1106 bool exists;
1107 FILE *ifp;
1108
1109 exists = false;
1110
1111 if ((ifp = fopen(filename, "r")) != NULL) {
1112 exists = true;
1113
1114 fclose(ifp);
1115 }
1116
1117 return (exists);
1118}
1119
1120
1121
1122void create_file(char *filename) {
1123 FILE *ofp;
1124
1125 if ((ofp = fopen(filename, "w")) != NULL) {
1126 fclose(ofp);
1127 }
1128}
1129
1130
1131
1132bool getline(FILE *fp, char *buffer) {
1133 bool rc;
1134 bool collect;
1135 char c;
1136 int i;
1137
1138 rc = false;
1139 collect = true;
1140
1141 i = 0;
1142 while (collect) {
1143 c = getc(fp);
1144
1145 switch (c) {
1146 case EOF:
1147 if (i > 0) {
1148 rc = true;
1149 }
1150 collect = false;
1151 break;
1152
1153 case '\n':
1154 if (i > 0) {
1155 rc = true;
1156 collect = false;
1157 buffer[i] = '\0';
1158 }
1159 break;
1160
1161 default:
1162 buffer[i] = c;
1163 i++;
1164 break;
1165 }
1166 }
1167
1168 return (rc);
1169}
1170
1171
1172
1173
1174
1175
1176void load_and_run(int args, _TCHAR** argv) {
1177 char chr;
1178 int ln;
1179 int dot_position;
1180 int end_position;
1181 long i;
1182 FILE *ifp;
1183 long address;
1184 long load_at;
1185 int code;
1186
1187 // Prompt for the .hex file
1188
1189 printf("\n");
1190 printf("Enter the hex filename (.hex): ");
1191
1192 if (args == 2) {
1193 ln = 0;
1194 chr = argv[1][ln];
1195 while (chr != '\0')
1196 {
1197 if (ln < MAX_FILENAME_SIZE)
1198 {
1199 hex_file[ln] = chr;
1200 trc_file[ln] = chr;
1201 ln++;
1202 }
1203 chr = argv[1][ln];
1204 }
1205 }
1206 else {
1207 ln = 0;
1208 chr = '\0';
1209 while (chr != '\n') {
1210 chr = getchar();
1211
1212 switch (chr) {
1213 case '\n':
1214 break;
1215 default:
1216 if (ln < MAX_FILENAME_SIZE) {
1217 hex_file[ln] = chr;
1218 trc_file[ln] = chr;
1219 ln++;
1220 }
1221 break;
1222 }
1223 }
1224
1225 }
1226 // Tidy up the file names
1227
1228 dot_position = find_dot_position(hex_file);
1229 if (dot_position == 0) {
1230 end_position = find_end_position(hex_file);
1231
1232 hex_file[end_position + 1] = '.';
1233 hex_file[end_position + 2] = 'h';
1234 hex_file[end_position + 3] = 'e';
1235 hex_file[end_position + 4] = 'x';
1236 hex_file[end_position + 5] = '\0';
1237 }
1238 else {
1239 hex_file[dot_position + 0] = '.';
1240 hex_file[dot_position + 1] = 'h';
1241 hex_file[dot_position + 2] = 'e';
1242 hex_file[dot_position + 3] = 'x';
1243 hex_file[dot_position + 4] = '\0';
1244 }
1245
1246 dot_position = find_dot_position(trc_file);
1247 if (dot_position == 0) {
1248 end_position = find_end_position(trc_file);
1249
1250 trc_file[end_position + 1] = '.';
1251 trc_file[end_position + 2] = 't';
1252 trc_file[end_position + 3] = 'r';
1253 trc_file[end_position + 4] = 'c';
1254 trc_file[end_position + 5] = '\0';
1255 }
1256 else {
1257 trc_file[dot_position + 0] = '.';
1258 trc_file[dot_position + 1] = 't';
1259 trc_file[dot_position + 2] = 'r';
1260 trc_file[dot_position + 3] = 'c';
1261 trc_file[dot_position + 4] = '\0';
1262 }
1263
1264 if (file_exists(hex_file)) {
1265 // Clear Registers and Memory
1266
1267 Registers[REGISTER_A] = 0;
1268 Registers[REGISTER_B] = 0;
1269 Registers[REGISTER_C] = 0;
1270 Registers[REGISTER_D] = 0;
1271 Registers[REGISTER_E] = 0;
1272 Registers[REGISTER_F] = 0;
1273 Index_Registers[REGISTER_X] = 0;
1274 Index_Registers[REGISTER_Y] = 0;
1275 Flags = 0;
1276 ProgramCounter = 0;
1277 StackPointer = 0;
1278
1279 for (i = 0; i<MEMORY_SIZE; i++) {
1280 Memory[i] = 0x00;
1281 }
1282
1283 // Load hex file
1284
1285 if ((ifp = fopen(hex_file, "r")) != NULL) {
1286 printf("Loading file...\n\n");
1287
1288 load_at = 0;
1289
1290 while (getline(ifp, InputBuffer)) {
1291 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
1292 load_at = address;
1293 }
1294 else if (sscanf(InputBuffer, "%x", &code) == 1) {
1295 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
1296 Memory[load_at] = (BYTE)code;
1297 }
1298 load_at++;
1299 }
1300 else {
1301 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
1302 }
1303 }
1304
1305 fclose(ifp);
1306 }
1307
1308 // Emulate
1309
1310 emulate();
1311 }
1312 else {
1313 printf("\n");
1314 printf("ERROR> Input file %s does not exist!\n", hex_file);
1315 printf("\n");
1316 }
1317}
1318
1319void building(int args, _TCHAR** argv) {
1320 char buffer[1024];
1321 load_and_run(args, argv);
1322 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",
1323 Memory[TEST_ADDRESS_1],
1324 Memory[TEST_ADDRESS_2],
1325 Memory[TEST_ADDRESS_3],
1326 Memory[TEST_ADDRESS_4],
1327 Memory[TEST_ADDRESS_5],
1328 Memory[TEST_ADDRESS_6],
1329 Memory[TEST_ADDRESS_7],
1330 Memory[TEST_ADDRESS_8],
1331 Memory[TEST_ADDRESS_9],
1332 Memory[TEST_ADDRESS_10],
1333 Memory[TEST_ADDRESS_11],
1334 Memory[TEST_ADDRESS_12]
1335 );
1336 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1337}
1338
1339
1340
1341void test_and_mark() {
1342 char buffer[1024];
1343 bool testing_complete;
1344 int len = sizeof(SOCKADDR);
1345 char chr;
1346 int i;
1347 int j;
1348 bool end_of_program;
1349 long address;
1350 long load_at;
1351 int code;
1352 int mark;
1353 int passed;
1354
1355 printf("\n");
1356 printf("Automatic Testing and Marking\n");
1357 printf("\n");
1358
1359 testing_complete = false;
1360
1361 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
1362 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1363
1364 while (!testing_complete) {
1365 memset(buffer, '\0', sizeof(buffer));
1366
1367 if (recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
1368 printf("Incoming Data: %s \n", buffer);
1369
1370 //if (strcmp(buffer, "Testing complete") == 1)
1371 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
1372 testing_complete = true;
1373 printf("Current mark = %d\n", mark);
1374
1375 }
1376 else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
1377 //testing_complete = true;
1378 printf("Passed = %d\n", passed);
1379
1380 }
1381 else if (strcmp(buffer, "Error") == 0) {
1382 printf("ERROR> Testing abnormally terminated\n");
1383 testing_complete = true;
1384 }
1385 else {
1386 // Clear Registers and Memory
1387
1388 Registers[REGISTER_A] = 0;
1389 Registers[REGISTER_B] = 0;
1390 Registers[REGISTER_C] = 0;
1391 Registers[REGISTER_D] = 0;
1392 Registers[REGISTER_E] = 0;
1393 Registers[REGISTER_F] = 0;
1394 Index_Registers[REGISTER_X] = 0;
1395 Index_Registers[REGISTER_Y] = 0;
1396 Flags = 0;
1397 ProgramCounter = 0;
1398 StackPointer = 0;
1399 for (i = 0; i<MEMORY_SIZE; i++) {
1400 Memory[i] = 0;
1401 }
1402
1403 // Load hex file
1404
1405 i = 0;
1406 j = 0;
1407 load_at = 0;
1408 end_of_program = false;
1409 FILE *ofp;
1410 fopen_s(&ofp, "branch.txt", "a");
1411
1412 while (!end_of_program) {
1413 chr = buffer[i];
1414 switch (chr) {
1415 case '\0':
1416 end_of_program = true;
1417
1418 case ',':
1419 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
1420 load_at = address;
1421 }
1422 else if (sscanf(InputBuffer, "%x", &code) == 1) {
1423 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
1424 Memory[load_at] = (BYTE)code;
1425 fprintf(ofp, "%02X\n", (BYTE)code);
1426 }
1427 load_at++;
1428 }
1429 else {
1430 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
1431 }
1432 j = 0;
1433 break;
1434
1435 default:
1436 InputBuffer[j] = chr;
1437 j++;
1438 break;
1439 }
1440 i++;
1441 }
1442 fclose(ofp);
1443 // Emulate
1444
1445 if (load_at > 1) {
1446 emulate();
1447 // Send and store results
1448 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
1449 Memory[TEST_ADDRESS_1],
1450 Memory[TEST_ADDRESS_2],
1451 Memory[TEST_ADDRESS_3],
1452 Memory[TEST_ADDRESS_4],
1453 Memory[TEST_ADDRESS_5],
1454 Memory[TEST_ADDRESS_6],
1455 Memory[TEST_ADDRESS_7],
1456 Memory[TEST_ADDRESS_8],
1457 Memory[TEST_ADDRESS_9],
1458 Memory[TEST_ADDRESS_10],
1459 Memory[TEST_ADDRESS_11],
1460 Memory[TEST_ADDRESS_12]
1461 );
1462 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1463 }
1464 }
1465 }
1466 }
1467}
1468
1469
1470
1471int _tmain(int argc, _TCHAR* argv[])
1472{
1473 char chr;
1474 char dummy;
1475
1476 printf("\n");
1477 printf("Microprocessor Emulator\n");
1478 printf("UWE Computer and Network Systems Assignment 1\n");
1479 printf("\n");
1480
1481 initialise_filenames();
1482
1483 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
1484
1485 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
1486 if (!sock) {
1487 // Creation failed!
1488 }
1489
1490 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
1491 server_addr.sin_family = AF_INET;
1492 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
1493 server_addr.sin_port = htons(PORT_SERVER);
1494
1495 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
1496 client_addr.sin_family = AF_INET;
1497 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
1498 client_addr.sin_port = htons(PORT_CLIENT);
1499
1500 chr = '\0';
1501 while ((chr != 'e') && (chr != 'E'))
1502 {
1503 printf("\n");
1504 printf("Please select option\n");
1505 printf("L - Load and run a hex file\n");
1506 printf("T - Have the server test and mark your emulator\n");
1507 printf("E - Exit\n");
1508 if (argc == 2) { building(argc, argv); exit(0); }
1509 printf("Enter option: ");
1510 chr = getchar();
1511 if (chr != 0x0A)
1512 {
1513 dummy = getchar(); // read in the <CR>
1514 }
1515 printf("\n");
1516
1517 switch (chr)
1518 {
1519 case 'L':
1520 case 'l':
1521 load_and_run(argc, argv);
1522 break;
1523
1524 case 'T':
1525 case 't':
1526 test_and_mark();
1527 break;
1528
1529 default:
1530 break;
1531 }
1532 }
1533
1534 closesocket(sock);
1535 WSACleanup();
1536
1537
1538 return 0;
1539}