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