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