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