· 7 years ago · Feb 26, 2019, 03:32 PM
1
2
3#include "stdafx.h"
4#include <winsock2.h>
5
6#pragma comment(lib, "wsock32.lib")
7
8
9#define STUDENT_NUMBER "18010426"
10
11#define IP_ADDRESS_SERVER "127.0.0.1"
12
13#define PORT_SERVER 0x1984 // We define a port that we are going to use.
14#define PORT_CLIENT 0x1985 // We define a port that we are going to use.
15
16#define WORD unsigned short
17#define DWORD unsigned long
18#define BYTE unsigned char
19
20#define MAX_FILENAME_SIZE 500
21#define MAX_BUFFER_SIZE 500
22
23SOCKADDR_IN server_addr;
24SOCKADDR_IN client_addr;
25
26SOCKET sock; // This is our socket, it is the handle to the IO address to read/write packets
27
28WSADATA data;
29
30char InputBuffer[MAX_BUFFER_SIZE];
31
32char hex_file[MAX_BUFFER_SIZE];
33char trc_file[MAX_BUFFER_SIZE];
34
35//////////////////////////
36// Registers //
37//////////////////////////
38
39#define FLAG_Z 0x80
40#define FLAG_I 0x20
41#define FLAG_N 0x08
42#define FLAG_C 0x01
43#define REGISTER_A 4
44#define REGISTER_H 3
45#define REGISTER_L 2
46#define REGISTER_C 1
47#define REGISTER_B 0
48#define REGISTER_X 0
49#define REGISTER_Y 1
50#define REGISTER_M 5
51BYTE Index_Registers[2];
52
53BYTE Registers[6];
54BYTE Flags;
55WORD ProgramCounter;
56WORD StackPointer;
57
58
59////////////
60// Memory //
61////////////
62
63#define MEMORY_SIZE 65536
64
65BYTE Memory[MEMORY_SIZE];
66
67#define TEST_ADDRESS_1 0x01FA
68#define TEST_ADDRESS_2 0x01FB
69#define TEST_ADDRESS_3 0x01FC
70#define TEST_ADDRESS_4 0x01FD
71#define TEST_ADDRESS_5 0x01FE
72#define TEST_ADDRESS_6 0x01FF
73#define TEST_ADDRESS_7 0x0200
74#define TEST_ADDRESS_8 0x0201
75#define TEST_ADDRESS_9 0x0202
76#define TEST_ADDRESS_10 0x0203
77#define TEST_ADDRESS_11 0x0204
78#define TEST_ADDRESS_12 0x0205
79
80
81///////////////////////
82// Control variables //
83///////////////////////
84
85bool memory_in_range = true;
86bool halt = false;
87
88
89///////////////////////
90// Disassembly table //
91///////////////////////
92
93char opcode_mneumonics[][14] =
94{
95"ILLEGAL ",
96"ILLEGAL ",
97"SWI impl ",
98"RTI impl ",
99"STO abs ",
100"STOX abs ",
101"STOY abs ",
102"JMPR abs ",
103"CCC abs ",
104"CCS abs ",
105"CNE abs ",
106"CEQ abs ",
107"CMI abs ",
108"CPL abs ",
109"ILLEGAL ",
110"STOS abs ",
111
112"ILLEGAL ",
113"ILLEGAL ",
114"ILLEGAL ",
115"ILLEGAL ",
116"STO abs,X ",
117"STOX abs,X ",
118"STOY abs,X ",
119"NOP impl ",
120"WAI impl ",
121"ILLEGAL ",
122"ILLEGAL ",
123"ILLEGAL ",
124"ADI # ",
125"CPI # ",
126"ANI # ",
127"STOS abs,X ",
128
129"LODS # ",
130"LDX # ",
131"LODY # ",
132"RT impl ",
133"STO abs,Y ",
134"STOX abs,Y ",
135"STOY abs,Y ",
136"MVR #,B ",
137"MVR #,C ",
138"MVR #,L ",
139"MVR #,H ",
140"TAY impl ",
141"TYA impl ",
142"MSA impl ",
143"ILLEGAL ",
144"STOS abs,Y ",
145
146"LODS abs ",
147"LDX abs ",
148"LODY abs ",
149"ILLEGAL ",
150"STO abs,XY ",
151"STOX abs,XY ",
152"STOY abs,XY ",
153"ILLEGAL ",
154"JUMP abs ",
155"JCC abs ",
156"JCS abs ",
157"JNE abs ",
158"JEQ abs ",
159"JMI abs ",
160"JPL abs ",
161"STOS abs,XY ",
162
163"LODS abs,X ",
164"LDX abs,X ",
165"LODY abs,X ",
166"LD # ",
167"STO zpg ",
168"STOX zpg ",
169"STOY zpg ",
170"ILLEGAL ",
171"ILLEGAL ",
172"ILLEGAL ",
173"DEX impl ",
174"INX impl ",
175"DEY impl ",
176"INY impl ",
177"ILLEGAL ",
178"STOS zpg ",
179
180"LODS abs,Y ",
181"LDX abs,Y ",
182"LODY abs,Y ",
183"LD abs ",
184"TEST abs ",
185"INC abs ",
186"DEC abs ",
187"RR abs ",
188"RCL abs ",
189"SAL abs ",
190"SHR abs ",
191"COM abs ",
192"NEG abs ",
193"RAL abs ",
194"ROR abs ",
195"CLR abs ",
196
197"LODS abs,XY ",
198"LDX abs,XY ",
199"LODY abs,XY ",
200"LD abs,X ",
201"TEST abs,X ",
202"INC abs,X ",
203"DEC abs,X ",
204"RR abs,X ",
205"RCL abs,X ",
206"SAL abs,X ",
207"SHR abs,X ",
208"COM abs,X ",
209"NEG abs,X ",
210"RAL abs,X ",
211"ROR abs,X ",
212"CLR abs,X ",
213
214"LODS zpg ",
215"LDX zpg ",
216"LODY zpg ",
217"LD abs,Y ",
218"TEST abs,Y ",
219"INC abs,Y ",
220"DEC abs,Y ",
221"RR abs,Y ",
222"RCL abs,Y ",
223"SAL abs,Y ",
224"SHR abs,Y ",
225"COM abs,Y ",
226"NEG abs,Y ",
227"RAL abs,Y ",
228"ROR abs,Y ",
229"CLR abs,Y ",
230
231"ILLEGAL ",
232"ILLEGAL ",
233"ILLEGAL ",
234"LD abs,XY ",
235"TEST abs,XY ",
236"INC abs,XY ",
237"DEC abs,XY ",
238"RR abs,XY ",
239"RCL abs,XY ",
240"SAL abs,XY ",
241"SHR abs,XY ",
242"COM abs,XY ",
243"NEG abs,XY ",
244"RAL abs,XY ",
245"ROR abs,XY ",
246"CLR abs,XY ",
247
248"ILLEGAL ",
249"ILLEGAL ",
250"ILLEGAL ",
251"LD zpg ",
252"TESTA A,A ",
253"INCA A,A ",
254"DECA A,A ",
255"RRA A,A ",
256"RCLA A,A ",
257"SALA A,A ",
258"SHRA A,A ",
259"COMA A,A ",
260"NEGA A,0 ",
261"RALA A,A ",
262"RORA A,A ",
263"CLRA A,0 ",
264
265"MV A,A ",
266"MV B,A ",
267"MV C,A ",
268"MV L,A ",
269"MV H,A ",
270"MV M,A ",
271"CLC impl ",
272"SEC impl ",
273"CLI impl ",
274"SEI impl ",
275"CMC impl ",
276"ILLEGAL ",
277"ILLEGAL ",
278"ILLEGAL ",
279"PUSH ,A ",
280"POP A, ",
281
282"MV A,B ",
283"MV B,B ",
284"MV C,B ",
285"MV L,B ",
286"MV H,B ",
287"MV M,B ",
288"ADC A,B ",
289"SBC A,B ",
290"ADD A,B ",
291"SUB A,B ",
292"CMP A,B ",
293"OR A,B ",
294"AND A,B ",
295"XOR A,B ",
296"PUSH ,s ",
297"POP s, ",
298
299"MV A,C ",
300"MV B,C ",
301"MV C,C ",
302"MV L,C ",
303"MV H,C ",
304"MV M,C ",
305"ADC A,C ",
306"SBC A,C ",
307"ADD A,C ",
308"SUB A,C ",
309"CMP A,C ",
310"OR A,C ",
311"AND A,C ",
312"XOR A,C ",
313"PUSH ,B ",
314"POP B, ",
315
316"MV A,L ",
317"MV B,L ",
318"MV C,L ",
319"MV L,L ",
320"MV H,L ",
321"MV M,L ",
322"ADC A,L ",
323"SBC A,L ",
324"ADD A,L ",
325"SUB A,L ",
326"CMP A,L ",
327"OR A,L ",
328"AND A,L ",
329"XOR A,L ",
330"PUSH ,C ",
331"POP C, ",
332
333"MV A,H ",
334"MV B,H ",
335"MV C,H ",
336"MV L,H ",
337"MV H,H ",
338"MV M,H ",
339"ADC A,H ",
340"SBC A,H ",
341"ADD A,H ",
342"SUB A,H ",
343"CMP A,H ",
344"OR A,H ",
345"AND A,H ",
346"XOR A,H ",
347"PUSH ,L ",
348"POP L, ",
349
350"MV A,M ",
351"MV B,M ",
352"MV C,M ",
353"MV L,M ",
354"MV H,M ",
355"MV -,- ",
356"ADC A,M ",
357"SBC A,M ",
358"ADD A,M ",
359"SUB A,M ",
360"CMP A,M ",
361"OR A,M ",
362"AND A,M ",
363"XOR A,M ",
364"PUSH ,H ",
365"POP H, ",
366
367};
368
369////////////////////////////////////////////////////////////////////////////////
370// Simulator/Emulator (Start) //
371////////////////////////////////////////////////////////////////////////////////
372BYTE fetch()
373{
374 BYTE byte = 0;
375
376 if ((ProgramCounter >= 0) && (ProgramCounter <= MEMORY_SIZE))
377 {
378 memory_in_range = true;
379 byte = Memory[ProgramCounter];
380 ProgramCounter++;
381 }
382 else
383 {
384 memory_in_range = false;
385 }
386 return byte;
387}
388void set_flag_z(BYTE inReg) {
389 BYTE reg;
390 reg = inReg;
391
392 if (reg == 0) // msbit set
393 {
394 Flags = Flags | FLAG_Z;
395 }
396 else
397 {
398 Flags = Flags & (0xFF - FLAG_Z);
399 }
400}
401
402void set_flag_n(BYTE inReg) {
403 BYTE reg;
404 reg = inReg;
405
406 if ((reg & 0x80) != 0) { //msbit set
407 Flags = Flags | FLAG_N;
408 }
409 else {
410 Flags = Flags & (0xFF - FLAG_N);
411 }
412}
413
414void set_flag_z_16bit(WORD inReg) {
415 WORD reg;
416 reg = inReg;
417
418 if (reg == 0) // msbit set
419 {
420 Flags = Flags | FLAG_Z;
421 }
422 else
423 {
424 Flags = Flags & (0xFF - FLAG_Z);
425 }
426}
427
428
429void set_flag_n_16bit(WORD inReg) {
430 WORD reg;
431 reg = inReg;
432
433 if ((reg & 0x8000) != 0) { //msbit set
434 Flags = Flags | FLAG_N;
435 }
436 else {
437 Flags = Flags & (0xFF - FLAG_N);
438 }
439
440}
441
442void Group_1(BYTE opcode) {
443 BYTE LB = 0;
444 BYTE HB = 0;
445 BYTE param1 = 0;
446 BYTE param2 = 0;
447 WORD address = 0;
448 WORD data = 0;
449 WORD temp_word = 0;
450 WORD saved_flags = 0;
451
452
453 switch (opcode) {
454
455 // LD - Loads Memory into Accumulator
456
457 case 0x43: //LD Immediate
458 data = fetch();
459 Registers[REGISTER_A] = data;
460 set_flag_n((BYTE)Registers[REGISTER_A]);
461 set_flag_z((BYTE)Registers[REGISTER_A]);
462 break;
463
464 case 0x53: //LD Absoulute
465 LB = fetch();
466 HB = fetch();
467 address += (WORD)((WORD)HB << 8) + LB;
468 if (address >= 0 && address < MEMORY_SIZE) {
469 Registers[REGISTER_A] = Memory[address];
470 }
471 set_flag_n((BYTE)Registers[REGISTER_A]);
472 set_flag_z((BYTE)Registers[REGISTER_A]);
473 break;
474
475 case 0x63://LD Absoulte X
476 address += Index_Registers[REGISTER_X];
477 LB = fetch();
478 HB = fetch();
479 address += (WORD)((WORD)HB << 8) + LB;
480 if (address >= 0 && address < MEMORY_SIZE) {
481 Registers[REGISTER_A] = Memory[address];
482 }
483 set_flag_n((BYTE)Registers[REGISTER_A]);
484 set_flag_z((BYTE)Registers[REGISTER_A]);
485 break;
486
487 case 0x73://LD Absoulte Y
488 address += Index_Registers[REGISTER_Y];
489 LB = fetch();
490 HB = fetch();
491 address += (WORD)((WORD)HB << 8) + LB;
492 if (address >= 0 && address < MEMORY_SIZE) {
493 Registers[REGISTER_A] = Memory[address];
494 }
495 set_flag_n((BYTE)Registers[REGISTER_A]);
496 set_flag_z((BYTE)Registers[REGISTER_A]);
497 break;
498
499 case 0x83://LD Absoulte XY
500 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
501 LB = fetch();
502 HB = fetch();
503 address += (WORD)((WORD)HB << 8) + LB;
504 if (address >= 0 && address < MEMORY_SIZE) {
505 Registers[REGISTER_A] = Memory[address];
506 }
507 set_flag_n((BYTE)Registers[REGISTER_A]);
508 set_flag_z((BYTE)Registers[REGISTER_A]);
509 break;
510
511 case 0x93://LD zpg
512 address += 0x0000 | (WORD)fetch();
513 if (address >= 0 && address < MEMORY_SIZE) {
514 Registers[REGISTER_A] = Memory[address];
515 }
516 set_flag_n((BYTE)Registers[REGISTER_A]);
517 set_flag_z((BYTE)Registers[REGISTER_A]);
518 break;
519
520
521
522 // STO - Stores Accumulator into Memory
523
524 case 0x04://STO Absolute
525 LB = fetch();
526 HB = fetch();
527 address += (WORD)((WORD)HB << 8) + LB;
528 if (address >= 0 && address < MEMORY_SIZE) {
529 Memory[address] = Registers[REGISTER_A];
530 }
531 set_flag_n((BYTE)Memory[address]);
532 set_flag_z((BYTE)Memory[address]);
533 break;
534
535 case 0x14://STO Absolute X
536 address += Index_Registers[REGISTER_X];
537 LB = fetch();
538 HB = fetch();
539 address += (WORD)((WORD)HB << 8) + LB;
540 if (address >= 0 && address < MEMORY_SIZE) {
541 Memory[address] = Registers[REGISTER_A];
542 }
543 set_flag_n((BYTE)Memory[address]);
544 set_flag_z((BYTE)Memory[address]);
545 break;
546
547 case 0x24: //STO Absolute Y
548 address += Index_Registers[REGISTER_Y];
549 LB = fetch();
550 HB = fetch();
551 address += (WORD)((WORD)HB << 8) + LB;
552 if (address >= 0 && address < MEMORY_SIZE) {
553 Memory[address] = Registers[REGISTER_A];
554 }
555 set_flag_n((BYTE)Memory[address]);
556 set_flag_z((BYTE)Memory[address]);
557 break;
558
559 case 0x34://STO Absolute XY
560 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
561 LB = fetch();
562 HB = fetch();
563 address += (WORD)((WORD)HB << 8) + LB;
564 if (address >= 0 && address < MEMORY_SIZE) {
565 Memory[address] = Registers[REGISTER_A];
566 }
567 set_flag_n((BYTE)Memory[address]);
568 set_flag_z((BYTE)Memory[address]);
569 break;
570
571 case 0x44://STO zpg
572 address += 0x0000 | (WORD)fetch();
573 if (address >= 0 && address < MEMORY_SIZE) {
574 Memory[address] = Registers[REGISTER_A];
575 }
576 set_flag_n((BYTE)Memory[address]);
577 set_flag_z((BYTE)Memory[address]);
578 break;
579
580
581
582 // ADC - Register added to Accumulator with Carry
583
584 case 0xB6://ADC A,B
585 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
586 if ((Flags & FLAG_C) != 0) {
587 temp_word++;
588 }
589 if (temp_word >= 0x100) {
590 Flags = Flags | FLAG_C;
591 }
592 else {
593 Flags = Flags & (0xFF - FLAG_C);
594 }
595 set_flag_n((BYTE)temp_word);
596 set_flag_z((BYTE)temp_word);
597 Registers[REGISTER_A] = (BYTE)temp_word;
598 break;
599
600 case 0xC6://ADC A,C
601 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
602 if ((Flags & FLAG_C) != 0) {
603 temp_word++;
604 }
605 if (temp_word >= 0x100) {
606 Flags = Flags | FLAG_C;
607 }
608 else {
609 Flags = Flags & (0xFF - FLAG_C);
610 }
611 set_flag_n((BYTE)temp_word);
612 set_flag_z((BYTE)temp_word);
613 Registers[REGISTER_A] = (BYTE)temp_word;
614 break;
615
616 case 0xD6://ADC A,L
617 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
618 if ((Flags & FLAG_C) != 0) {
619 temp_word++;
620 }
621 if (temp_word >= 0x100) {
622 Flags = Flags | FLAG_C;
623 }
624 else {
625 Flags = Flags & (0xFF - FLAG_C);
626 }
627 set_flag_n((BYTE)temp_word);
628 set_flag_z((BYTE)temp_word);
629 Registers[REGISTER_A] = (BYTE)temp_word;
630 break;
631
632 case 0xE6://ADC A,H
633 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
634 if ((Flags & FLAG_C) != 0) {
635 temp_word++;
636 }
637 if (temp_word >= 0x100) {
638 Flags = Flags | FLAG_C;
639 }
640 else {
641 Flags = Flags & (0xFF - FLAG_C);
642 }
643 set_flag_n((BYTE)temp_word);
644 set_flag_z((BYTE)temp_word);
645 Registers[REGISTER_A] = (BYTE)temp_word;
646 break;
647
648 case 0xF6://ADC A,M
649 HB = Registers[REGISTER_H];
650 LB = Registers[REGISTER_L];
651 address = ((WORD)HB << 8) + LB;
652 param1 = Registers[REGISTER_A];
653 param2 = Memory[address];
654 temp_word = (WORD)param1 + (WORD)param2;
655 if ((Flags & FLAG_C) != 0) {
656 temp_word++;
657 }
658 if (temp_word >= 0x100) {
659 Flags = Flags | FLAG_C;
660 }
661 else {
662 Flags = Flags & (0xFF - FLAG_C);
663 }
664 set_flag_n((BYTE)temp_word);
665 set_flag_z((BYTE)temp_word);
666 Registers[REGISTER_A] = (BYTE)temp_word;
667 break;
668
669
670
671 // SBC - Register subtracted from Accumulator with Carry
672
673 case 0xB7: //SBC A,B
674 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
675 if ((Flags & FLAG_C) != 0) {
676 temp_word--;
677 }
678 if (temp_word >= 0x100) {
679 Flags = Flags | FLAG_C;
680 }
681 else {
682 Flags = Flags & (0xFF - FLAG_C);
683 }
684 set_flag_n((BYTE)temp_word);
685 set_flag_z((BYTE)temp_word);
686 Registers[REGISTER_A] = (BYTE)temp_word;
687 break;
688
689 case 0xC7: //SBC A,C
690 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
691 if ((Flags & FLAG_C) != 0) {
692 temp_word--;
693 }
694 if (temp_word >= 0x100) {
695 Flags = Flags | FLAG_C;
696 }
697 else {
698 Flags = Flags & (0xFF - FLAG_C);
699 }
700 set_flag_n((BYTE)temp_word);
701 set_flag_z((BYTE)temp_word);
702 Registers[REGISTER_A] = (BYTE)temp_word;
703 break;
704
705 case 0xD7: //SBC A,L
706 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
707 if ((Flags & FLAG_C) != 0) {
708 temp_word--;
709 }
710 if (temp_word >= 0x100) {
711 Flags = Flags | FLAG_C;
712 }
713 else {
714 Flags = Flags & (0xFF - FLAG_C);
715 }
716 set_flag_n((BYTE)temp_word);
717 set_flag_z((BYTE)temp_word);
718 Registers[REGISTER_A] = (BYTE)temp_word;
719 break;
720
721 case 0xE7: //SBC A,H
722 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
723 if ((Flags & FLAG_C) != 0) {
724 temp_word--;
725 }
726 if (temp_word >= 0x100) {
727 Flags = Flags | FLAG_C;
728 }
729 else {
730 Flags = Flags & (0xFF - FLAG_C);
731 }
732 set_flag_n((BYTE)temp_word);
733 set_flag_z((BYTE)temp_word);
734 Registers[REGISTER_A] = (BYTE)temp_word;
735 break;
736
737 case 0xF7: //SBC A,M
738 HB = Registers[REGISTER_H];
739 LB = Registers[REGISTER_L];
740 address = ((WORD)HB << 8) + LB;
741 param1 = Registers[REGISTER_A];
742 param2 = Memory[address];
743 temp_word = (WORD)param1 - (WORD)param2;
744 if ((Flags & FLAG_C) != 0) {
745 temp_word--;
746 }
747 if (temp_word >= 0x100) {
748 Flags = Flags | FLAG_C;
749 }
750 else {
751 Flags = Flags & (0xFF - FLAG_C);
752 }
753 set_flag_n((BYTE)temp_word);
754 set_flag_z((BYTE)temp_word);
755 Registers[REGISTER_A] = (BYTE)temp_word;
756 break;
757
758
759
760 // ADD - Register added to Accumulator
761
762 case 0xB8://ADD A,B
763 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
764 if (temp_word >= 0x100) {
765 Flags = Flags | FLAG_C;
766 }
767 else {
768 Flags = Flags & (0xFF - FLAG_C);
769 }
770 set_flag_n((BYTE)temp_word);
771 set_flag_z((BYTE)temp_word);
772 Registers[REGISTER_A] = (BYTE)temp_word;
773 break;
774
775 case 0xC8://ADD A,C
776 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
777 if (temp_word >= 0x100) {
778 Flags = Flags | FLAG_C;
779 }
780 else {
781 Flags = Flags & (0xFF - FLAG_C);
782 }
783 set_flag_n((BYTE)temp_word);
784 set_flag_z((BYTE)temp_word);
785 Registers[REGISTER_A] = (BYTE)temp_word;
786 break;
787
788 case 0xD8://ADD A,L
789 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
790 if (temp_word >= 0x100) {
791 Flags = Flags | FLAG_C;
792 }
793 else {
794 Flags = Flags & (0xFF - FLAG_C);
795 }
796 set_flag_n((BYTE)temp_word);
797 set_flag_z((BYTE)temp_word);
798 Registers[REGISTER_A] = (BYTE)temp_word;
799 break;
800
801 case 0xE8://ADD A,H
802 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
803 if (temp_word >= 0x100) {
804 Flags = Flags | FLAG_C;
805 }
806 else {
807 Flags = Flags & (0xFF - FLAG_C);
808 }
809 set_flag_n((BYTE)temp_word);
810 set_flag_z((BYTE)temp_word);
811 Registers[REGISTER_A] = (BYTE)temp_word;
812 break;
813
814
815 case 0xF8://ADD A,M
816 HB = Registers[REGISTER_H];
817 LB = Registers[REGISTER_L];
818 address = ((WORD)HB << 8) + LB;
819 param1 = Registers[REGISTER_A];
820 param2 = Memory[address];
821 temp_word = (WORD)param1 + (WORD)param2;
822
823 if (temp_word >= 0x100) {
824 Flags = Flags | FLAG_C;
825 }
826 else {
827 Flags = Flags & (0xFF - FLAG_C);
828 }
829 set_flag_n((BYTE)temp_word);
830 set_flag_z((BYTE)temp_word);
831 Registers[REGISTER_A] = (BYTE)temp_word;
832 break;
833
834
835
836 // SUB - Register subtracted to Accumulator
837
838 case 0xB9: //SUB A,B
839 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
840 if (temp_word >= 0x100)
841 {
842 Flags = Flags | FLAG_C;
843 }
844 else
845 {
846 Flags = Flags & (0xFF - FLAG_C);
847 }
848 set_flag_n((BYTE)temp_word);
849 set_flag_z((BYTE)temp_word);
850 Registers[REGISTER_A] = (BYTE)temp_word;
851 break;
852
853 case 0xC9: //SUB A,C
854 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
855 if (temp_word >= 0x100)
856 {
857 Flags = Flags | FLAG_C;
858 }
859 else
860 {
861 Flags = Flags & (0xFF - FLAG_C);
862 }
863 set_flag_n((BYTE)temp_word);
864 set_flag_z((BYTE)temp_word);
865 Registers[REGISTER_A] = (BYTE)temp_word;
866 break;
867
868 case 0xD9: //SUB A,L
869 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
870 if (temp_word >= 0x100)
871 {
872 Flags = Flags | FLAG_C;
873 }
874 else
875 {
876 Flags = Flags & (0xFF - FLAG_C);
877 }
878 set_flag_n((BYTE)temp_word);
879 set_flag_z((BYTE)temp_word);
880 Registers[REGISTER_A] = (BYTE)temp_word;
881 break;
882
883 case 0xE9: //SUB A,H
884 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
885 if (temp_word >= 0x100)
886 {
887 Flags = Flags | FLAG_C;
888 }
889 else
890 {
891 Flags = Flags & (0xFF - FLAG_C);
892 }
893 set_flag_n((BYTE)temp_word);
894 set_flag_z((BYTE)temp_word);
895 Registers[REGISTER_A] = (BYTE)temp_word;
896 break;
897
898 case 0xF9: //SUB A,M
899 HB = Registers[REGISTER_H];
900 LB = Registers[REGISTER_L];
901 address = ((WORD)HB << 8) + LB;
902 param1 = Registers[REGISTER_A];
903 param2 = Memory[address];
904 temp_word = (WORD)param1 - (WORD)param2;
905 if (temp_word >= 0x100)
906 {
907 Flags = Flags | FLAG_C;
908 }
909 else
910 {
911 Flags = Flags & (0xFF - FLAG_C);
912 }
913 set_flag_n((BYTE)temp_word);
914 set_flag_z((BYTE)temp_word);
915 Registers[REGISTER_A] = (BYTE)temp_word;
916 break;
917
918
919
920 // CMP - Register compared to Accumulator
921
922 case 0xBA://CMP A,B
923 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
924 if (temp_word >= 0x100) {
925 Flags = Flags | FLAG_C; // Set carry flag
926 }
927 else {
928 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
929 }
930 set_flag_n((BYTE)temp_word);
931 set_flag_z((BYTE)temp_word);
932 break;
933
934 case 0xCA://CMP A,C
935 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
936 if (temp_word >= 0x100) {
937 Flags = Flags | FLAG_C; // Set carry flag
938 }
939 else {
940 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
941 }
942 set_flag_n((BYTE)temp_word);
943 set_flag_z((BYTE)temp_word);
944 break;
945
946 case 0xDA://CMP A,L
947 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
948 if (temp_word >= 0x100) {
949 Flags = Flags | FLAG_C; // Set carry flag
950 }
951 else {
952 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
953 }
954 set_flag_n((BYTE)temp_word);
955 set_flag_z((BYTE)temp_word);
956 break;
957
958 case 0xEA://CMP A,H
959 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
960 if (temp_word >= 0x100)
961 {
962 Flags = Flags | FLAG_C; // Set carry flag
963 }
964 else
965 {
966 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
967 }
968 set_flag_n((BYTE)temp_word);
969 set_flag_z((BYTE)temp_word);
970 break;
971
972 case 0xFA://CMP A,M
973
974 HB = Registers[REGISTER_H];
975 LB = Registers[REGISTER_L];
976 address += (WORD)((WORD)HB << 8) + LB;
977 param1 = Registers[REGISTER_A];
978 param2 = Memory[address];
979
980 temp_word = (WORD)param1 - (WORD)param2;
981
982 if (temp_word >= 0x100)
983 {
984 Flags = Flags | FLAG_C; // Set carry flag
985 }
986 else
987 {
988 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
989 }
990 set_flag_n((BYTE)temp_word);
991 set_flag_z((BYTE)temp_word);
992 break;
993
994
995
996 // OR - Register bitwise inclusive or with Accumulator
997
998 case 0xBB: //OR A,B
999 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_B];
1000 set_flag_n((BYTE)temp_word);
1001 set_flag_z((BYTE)temp_word);
1002 Registers[REGISTER_A] = (BYTE)temp_word;
1003 break;
1004
1005 case 0xCB: //OR A,C
1006 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_C];
1007 set_flag_n((BYTE)temp_word);
1008 set_flag_z((BYTE)temp_word);
1009 Registers[REGISTER_A] = (BYTE)temp_word;
1010 break;
1011
1012 case 0xDB: //OR A,L
1013 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_L];
1014 set_flag_n((BYTE)temp_word);
1015 set_flag_z((BYTE)temp_word);
1016 Registers[REGISTER_A] = (BYTE)temp_word;
1017 break;
1018
1019 case 0xEB: //OR A,H
1020 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_H];
1021 set_flag_n((BYTE)temp_word);
1022 set_flag_z((BYTE)temp_word);
1023 Registers[REGISTER_A] = (BYTE)temp_word;
1024 break;
1025
1026 case 0xFB: //OR A,M
1027 HB = Registers[REGISTER_H];
1028 LB = Registers[REGISTER_L];
1029 address = ((WORD)HB << 8) + LB;
1030 param1 = Registers[REGISTER_A];
1031 param2 = Memory[address];
1032 temp_word = (WORD)param1 | (WORD)param2;
1033 set_flag_n((BYTE)temp_word);
1034 set_flag_z((BYTE)temp_word);
1035 Registers[REGISTER_A] = (BYTE)temp_word;
1036 break;
1037
1038
1039
1040 // AND - Register bitwise and with Accumulator
1041
1042 case 0xBC: // AND Register A,B
1043 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_B];
1044 set_flag_n((BYTE)temp_word);
1045 set_flag_z((BYTE)temp_word);
1046 Registers[REGISTER_A] = (BYTE)temp_word;
1047 break;
1048
1049 case 0xCC: // AND Register A,C
1050 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_C];
1051 set_flag_n((BYTE)temp_word);
1052 set_flag_z((BYTE)temp_word);
1053 Registers[REGISTER_A] = (BYTE)temp_word;
1054 break;
1055
1056 case 0xDC: // AND Register A,L
1057 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_L];
1058 set_flag_n((BYTE)temp_word);
1059 set_flag_z((BYTE)temp_word);
1060 Registers[REGISTER_A] = (BYTE)temp_word;
1061 break;
1062
1063 case 0xEC: // AND Register A,H
1064 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_H];
1065 set_flag_n((BYTE)temp_word);
1066 set_flag_z((BYTE)temp_word);
1067 Registers[REGISTER_A] = (BYTE)temp_word;
1068 break;
1069
1070
1071 case 0xFC: // AND Register A,M
1072 HB = Registers[REGISTER_H];
1073 LB = Registers[REGISTER_L];
1074 address = ((WORD)HB << 8) + LB;
1075 param1 = Registers[REGISTER_A];
1076 param2 = Memory[address];
1077 temp_word = (WORD)param1 & (WORD)param2;
1078 //temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_M];
1079 set_flag_n((BYTE)temp_word);
1080 set_flag_z((BYTE)temp_word);
1081 Registers[REGISTER_A] = (BYTE)temp_word;
1082 break;
1083
1084
1085
1086 // XOR - Register bitwise exclusive or with Accumulator
1087
1088 case 0xBD: //XOR A,B
1089 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_B];
1090 set_flag_n((BYTE)temp_word);
1091 set_flag_z((BYTE)temp_word);
1092 Registers[REGISTER_A] = (BYTE)temp_word;
1093 break;
1094
1095 case 0xCD: //XOR A,C
1096 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_C];
1097 set_flag_n((BYTE)temp_word);
1098 set_flag_z((BYTE)temp_word);
1099 Registers[REGISTER_A] = (BYTE)temp_word;
1100 break;
1101
1102 case 0xDD: //XOR A,L
1103 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_L];
1104 set_flag_n((BYTE)temp_word);
1105 set_flag_z((BYTE)temp_word);
1106 Registers[REGISTER_A] = (BYTE)temp_word;
1107 break;
1108
1109 case 0xED: //XOR A,H
1110 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_H];
1111 set_flag_n((BYTE)temp_word);
1112 set_flag_z((BYTE)temp_word);
1113 Registers[REGISTER_A] = (BYTE)temp_word;
1114 break;
1115
1116 case 0xFD: //XOR A,M
1117 HB = Registers[REGISTER_H];
1118 LB = Registers[REGISTER_L];
1119 address = ((WORD)HB << 8) + LB;
1120 param1 = Registers[REGISTER_A];
1121 param2 = Memory[address];
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
1128
1129
1130 // ADI - Data added to Accumulator with Carry
1131
1132 case 0x1C: //ADI Immediate
1133 data = fetch();
1134 temp_word = (WORD)Registers[REGISTER_A] + data;
1135 if ((Flags & FLAG_C) != 0)
1136 {
1137 temp_word++;
1138 }
1139 if (temp_word >= 0x100)
1140 {
1141 Flags = Flags | FLAG_C;
1142 }
1143 else
1144 {
1145 Flags = Flags & (0xFF - FLAG_C);
1146 }
1147 set_flag_n((BYTE)temp_word);
1148 set_flag_z((BYTE)temp_word);
1149 Registers[REGISTER_A] = (BYTE)temp_word;
1150 break;
1151
1152
1153
1154 // CPI - Data compared to Accumulator
1155
1156 case 0x1D: //CPI Immediate
1157 data = fetch();
1158
1159 temp_word = (WORD)data - (WORD)Registers[REGISTER_A];
1160
1161 if (temp_word >= 0x100) {
1162 Flags = Flags | FLAG_C; // Set carry flag
1163 }
1164 else {
1165 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1166 }
1167
1168 set_flag_z((BYTE)temp_word);
1169 set_flag_n((BYTE)temp_word);
1170 break;
1171
1172
1173
1174 // ANI - Data bitwise and with Accumulator
1175
1176 case 0x1E: //ANI Immediate
1177 data = fetch();
1178 temp_word = (WORD)Registers[REGISTER_A] & data;
1179
1180 if (temp_word >= 0x100)
1181 {
1182 Flags = Flags | FLAG_C;
1183 }
1184 else
1185 {
1186 Flags = Flags & (0xFF - FLAG_C);
1187 }
1188 set_flag_n((BYTE)temp_word);
1189 set_flag_z((BYTE)temp_word);
1190 Registers[REGISTER_A] = (BYTE)temp_word;
1191 break;
1192
1193
1194
1195 // TEST - Bit test Memory or Accumulator
1196
1197 case 0x54: //TEST Absolute
1198 LB = fetch();
1199 HB = fetch();
1200 address += (WORD)((WORD)HB << 8) + LB;
1201 data = Memory[address];
1202 set_flag_n(data);
1203 set_flag_z(data);
1204 break;
1205
1206 case 0x64: //TEST Absolute X
1207 address += Index_Registers[REGISTER_X];
1208 LB = fetch();
1209 HB = fetch();
1210 address += (WORD)((WORD)HB << 8) + LB;
1211 data = Memory[address];
1212 set_flag_n(data);
1213 set_flag_z(data);
1214 break;
1215
1216 case 0x74: //TEST Absolute Y
1217 address += Index_Registers[REGISTER_Y];
1218 LB = fetch();
1219 HB = fetch();
1220 address += (WORD)((WORD)HB << 8) + LB;
1221 data = Memory[address];
1222 set_flag_n(data);
1223 set_flag_z(data);
1224 break;
1225
1226 case 0x84: //TEST Absolute X,Y
1227 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1228 LB = fetch();
1229 HB = fetch();
1230 address += (WORD)((WORD)HB << 8) + LB;
1231 data = Memory[address];
1232 set_flag_n(data);
1233 set_flag_z(data);
1234 break;
1235
1236
1237
1238 // TESTA - Bit test memory or accumulator
1239
1240 case 0x94: // TESTA
1241 set_flag_z(Registers[REGISTER_A]);
1242 set_flag_n(Registers[REGISTER_A]);
1243 break;
1244
1245
1246
1247 // INC - Increment Memory or Accumulator
1248
1249
1250 case 0x55: // INC abs
1251 LB = fetch();
1252 HB = fetch();
1253 address += (WORD)((WORD)HB << 8) + LB;
1254 ++Memory[address];
1255 set_flag_n(Memory[address]);
1256 set_flag_z(Memory[address]);
1257 break;
1258
1259 case 0x65: // INC abs X
1260 address += Index_Registers[REGISTER_X];
1261 LB = fetch();
1262 HB = fetch();
1263 address += (WORD)((WORD)HB << 8) + LB;
1264 if (address >= 0 && address < MEMORY_SIZE)
1265 {
1266 ++Memory[address];
1267 }
1268 set_flag_n(Memory[address]);
1269 set_flag_z(Memory[address]);
1270 break;
1271
1272 case 0x75: // INC abs Y
1273 address += Index_Registers[REGISTER_Y];
1274 LB = fetch();
1275 HB = fetch();
1276 address += (WORD)((WORD)HB << 8) + LB;
1277 if (address >= 0 && address < MEMORY_SIZE)
1278 {
1279 ++Memory[address];
1280 }
1281 set_flag_n(Memory[address]);
1282 set_flag_z(Memory[address]);
1283 break;
1284
1285 case 0x85: // INC abs XY
1286 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1287 LB = fetch();
1288 HB = fetch();
1289 address += (WORD)((WORD)HB << 8) + LB;
1290 if (address >= 0 && address < MEMORY_SIZE)
1291 {
1292 ++Memory[address];
1293 }
1294 set_flag_n(Memory[address]);
1295 set_flag_z(Memory[address]);
1296 break;
1297
1298
1299
1300 // INCA - Increment Memory or Accumulator
1301
1302 case 0x95: //INCA
1303 ++Registers[REGISTER_A];
1304 set_flag_n(Registers[REGISTER_A]);
1305 set_flag_z(Registers[REGISTER_A]);
1306 break;
1307
1308
1309
1310 // DEC - Decrement Memory or Accumulator
1311
1312 case 0x56: //DEC Absolute
1313 LB = fetch();
1314 HB = fetch();
1315 address += (WORD)((WORD)HB << 8) + LB;
1316 Memory[address]--;
1317 set_flag_n(Memory[address]);
1318 set_flag_z(Memory[address]);
1319 break;
1320
1321 case 0x66: //DEC Absolute X
1322 address += Index_Registers[REGISTER_X];
1323 LB = fetch();
1324 HB = fetch();
1325 address += (WORD)((WORD)HB << 8) + LB;
1326 if (address >= 0 && address < MEMORY_SIZE)
1327 {
1328 Memory[address]--;
1329 }
1330 set_flag_n(Memory[address]);
1331 set_flag_z(Memory[address]);
1332 break;
1333
1334 case 0x76: //DEC Absolute Y
1335 address += Index_Registers[REGISTER_Y];
1336 LB = fetch();
1337 HB = fetch();
1338 address += (WORD)((WORD)HB << 8) + LB;
1339 if (address >= 0 && address < MEMORY_SIZE)
1340 {
1341 Memory[address]--;
1342 }
1343 set_flag_n(Memory[address]);
1344 set_flag_z(Memory[address]);
1345 break;
1346
1347 case 0x86: //DEC Absolute X,Y
1348 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1349 LB = fetch();
1350 HB = fetch();
1351 address += (WORD)((WORD)HB << 8) + LB;
1352 if (address >= 0 && address < MEMORY_SIZE)
1353 {
1354 Memory[address]--;
1355 }
1356 set_flag_n(Memory[address]);
1357 set_flag_z(Memory[address]);
1358 break;
1359
1360
1361
1362 // DECA - Decrement Memory or Accumulator
1363
1364 case 0x96: //DECA Register A
1365 Registers[REGISTER_A]--;
1366 set_flag_n(Registers[REGISTER_A]);
1367 set_flag_z(Registers[REGISTER_A]);
1368 break;
1369
1370
1371
1372 //RR - Rotate right through carry Memory or Accumulator
1373
1374 case 0x57: //RR Absolute
1375 LB = fetch();
1376 HB = fetch();
1377 address += (WORD)((WORD)HB << 8) + LB;
1378 saved_flags = Flags;
1379
1380 if ((Memory[address] & 0x01) == 0x01) {
1381 Flags = Flags | FLAG_C;
1382 }
1383 else {
1384 Flags = Flags & (0xFF - FLAG_C);
1385 }
1386 Memory[address] = (Memory[address] >> 1) & 0x7F;
1387
1388 if ((saved_flags & FLAG_C) == FLAG_C) {
1389 Memory[address] = Memory[address] | 0x80;
1390 }
1391 set_flag_n((BYTE)Memory[address]);
1392 set_flag_z((BYTE)Memory[address]);
1393 break;
1394
1395
1396 case 0x67: //RR Absolute X
1397 address += Index_Registers[REGISTER_X];
1398
1399 LB = fetch();
1400 HB = fetch();
1401 address += (WORD)((WORD)HB << 8) + LB;
1402 saved_flags = Flags;
1403
1404 if ((Memory[address] & 0x01) == 0x01) {
1405 Flags = Flags | FLAG_C;
1406 }
1407 else {
1408 Flags = Flags & (0xFF - FLAG_C);
1409 }
1410 Memory[address] = (Memory[address] >> 1) & 0x7F;
1411
1412 if ((saved_flags & FLAG_C) == FLAG_C) {
1413 Memory[address] = Memory[address] | 0x80;
1414 }
1415 set_flag_n((BYTE)Memory[address]);
1416 set_flag_z((BYTE)Memory[address]);
1417
1418 break;
1419 case 0x77: //RR Absolute Y
1420 address += Index_Registers[REGISTER_Y];
1421
1422 LB = fetch();
1423 HB = fetch();
1424 address += (WORD)((WORD)HB << 8) + LB;
1425 saved_flags = Flags;
1426
1427 if ((Memory[address] & 0x01) == 0x01) {
1428 Flags = Flags | FLAG_C;
1429 }
1430 else {
1431 Flags = Flags & (0xFF - FLAG_C);
1432 }
1433 Memory[address] = (Memory[address] >> 1) & 0x7F;
1434
1435 if ((saved_flags & FLAG_C) == FLAG_C) {
1436 Memory[address] = Memory[address] | 0x80;
1437 }
1438 set_flag_n((BYTE)Memory[address]);
1439 set_flag_z((BYTE)Memory[address]);
1440
1441 break;
1442 case 0x87: //RR Absolute X,Y
1443 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1444 LB = fetch();
1445 HB = fetch();
1446 address += (WORD)((WORD)HB << 8) + LB;
1447 saved_flags = Flags;
1448
1449 if ((Memory[address] & 0x01) == 0x01) {
1450 Flags = Flags | FLAG_C;
1451 }
1452 else {
1453 Flags = Flags & (0xFF - FLAG_C);
1454 }
1455 Memory[address] = (Memory[address] >> 1) & 0x7F;
1456
1457 if ((saved_flags & FLAG_C) == FLAG_C) {
1458 Memory[address] = Memory[address] | 0x80;
1459 }
1460 set_flag_n((BYTE)Memory[address]);
1461 set_flag_z((BYTE)Memory[address]);
1462 break;
1463
1464
1465
1466 // RRA - Rotate right through carry Memory or Accumulator
1467
1468 case 0x97: //RRA Register A
1469 saved_flags = Flags;
1470
1471 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
1472 Flags = Flags | FLAG_C;
1473 }
1474 else {
1475 Flags = Flags & (0xFF - FLAG_C);
1476 }
1477 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
1478
1479 if ((saved_flags & FLAG_C) == FLAG_C) {
1480 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
1481 }
1482 set_flag_n((BYTE)Registers[REGISTER_A]);
1483 set_flag_z((BYTE)Registers[REGISTER_A]);
1484 break;
1485
1486 // RCL - Rotate left through carry Memory or Accumulator
1487
1488 case 0x58: //RCL Absolute
1489 LB = fetch();
1490 HB = fetch();
1491 address += (WORD)((WORD)HB << 8) + LB;
1492 saved_flags = Flags;
1493
1494 if ((Memory[address] & 0x80) == 0x80) {
1495 Flags = Flags | FLAG_C;
1496 }
1497 else {
1498 Flags = Flags & (0xFF - FLAG_C);
1499 }
1500 Memory[address] = (Memory[address] << 1) & 0xFE;
1501
1502 if ((saved_flags & FLAG_C) == FLAG_C) {
1503 Memory[address] = Memory[address] | 0x01;
1504 }
1505 set_flag_n((BYTE)Memory[address]);
1506 set_flag_z((BYTE)Memory[address]);
1507 break;
1508 case 0x68: //RCL Absolute X
1509 address += Index_Registers[REGISTER_X];
1510
1511 LB = fetch();
1512 HB = fetch();
1513 address += (WORD)((WORD)HB << 8) + LB;
1514 saved_flags = Flags;
1515
1516 if ((Memory[address] & 0x80) == 0x80) {
1517 Flags = Flags | FLAG_C;
1518 }
1519 else {
1520 Flags = Flags & (0xFF - FLAG_C);
1521 }
1522 Memory[address] = (Memory[address] << 1) & 0xFE;
1523
1524 if ((saved_flags & FLAG_C) == FLAG_C) {
1525 Memory[address] = Memory[address] | 0x01;
1526 }
1527 set_flag_n((BYTE)Memory[address]);
1528 set_flag_z((BYTE)Memory[address]);
1529 break;
1530 case 0x78: //RCL Absolute Y
1531 address += Index_Registers[REGISTER_Y];
1532
1533 LB = fetch();
1534 HB = fetch();
1535 address += (WORD)((WORD)HB << 8) + LB;
1536 saved_flags = Flags;
1537
1538 if ((Memory[address] & 0x80) == 0x80) {
1539 Flags = Flags | FLAG_C;
1540 }
1541 else {
1542 Flags = Flags & (0xFF - FLAG_C);
1543 }
1544 Memory[address] = (Memory[address] << 1) & 0xFE;
1545
1546 if ((saved_flags & FLAG_C) == FLAG_C) {
1547 Memory[address] = Memory[address] | 0x01;
1548 }
1549 set_flag_n((BYTE)Memory[address]);
1550 set_flag_z((BYTE)Memory[address]);
1551 break;
1552 case 0x88: //RCL Absolute X,Y
1553 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1554
1555 LB = fetch();
1556 HB = fetch();
1557 address += (WORD)((WORD)HB << 8) + LB;
1558 saved_flags = Flags;
1559
1560 if ((Memory[address] & 0x80) == 0x80) {
1561 Flags = Flags | FLAG_C;
1562 }
1563 else {
1564 Flags = Flags & (0xFF - FLAG_C);
1565 }
1566 Memory[address] = (Memory[address] << 1) & 0xFE;
1567
1568 if ((saved_flags & FLAG_C) == FLAG_C) {
1569 Memory[address] = Memory[address] | 0x01;
1570 }
1571 set_flag_n((BYTE)Memory[address]);
1572 set_flag_z((BYTE)Memory[address]);
1573 break;
1574
1575
1576
1577 // RCLA - Rotate left through carry Memory or Accumulator
1578
1579 case 0x98: //RCLA
1580 saved_flags = Flags;
1581
1582 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
1583 Flags = Flags | FLAG_C;
1584 }
1585 else {
1586 Flags = Flags & (0xFF - FLAG_C);
1587 }
1588 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
1589
1590 if ((saved_flags & FLAG_C) == FLAG_C) {
1591 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
1592 }
1593 set_flag_n((BYTE)Registers[REGISTER_A]);
1594 set_flag_z((BYTE)Registers[REGISTER_A]);
1595 break;
1596
1597
1598
1599 // SAL - Arithmetic shift left Memory or Accumulator
1600
1601
1602 case 0x59: //SAL Absolute
1603 LB = fetch();
1604 HB = fetch();
1605 address = (WORD)((WORD)HB << 8) + LB;
1606 saved_flags = Flags;
1607
1608 if ((Memory[address] & 0x80) == 0x80) {
1609 Flags = Flags | FLAG_C;
1610 }
1611 else {
1612 Flags = Flags & (0xFF - FLAG_C);
1613 }
1614
1615 Memory[address] = (Memory[address] << 1) & 0xFE;
1616
1617 set_flag_n(Memory[address]);
1618 set_flag_z(Memory[address]);
1619 break;
1620
1621 case 0x69: //SAL Absolute X
1622 address += Index_Registers[REGISTER_X];
1623 LB = fetch();
1624 HB = fetch();
1625 address += (WORD)((WORD)HB << 8) + LB;
1626 saved_flags = Flags;
1627
1628 if ((Memory[address] & 0x80) == 0x80) {
1629 Flags = Flags | FLAG_C;
1630 }
1631 else {
1632 Flags = Flags & (0xFF - FLAG_C);
1633 }
1634
1635 Memory[address] = (Memory[address] << 1) & 0xFE;
1636
1637 set_flag_n(Memory[address]);
1638 set_flag_z(Memory[address]);
1639 break;
1640
1641 case 0x79: //SAL Absolute Y
1642 address += Index_Registers[REGISTER_Y];
1643 LB = fetch();
1644 HB = fetch();
1645 address += (WORD)((WORD)HB << 8) + LB;
1646 saved_flags = Flags;
1647
1648 if ((Memory[address] & 0x80) == 0x80) {
1649 Flags = Flags | FLAG_C;
1650 }
1651 else {
1652 Flags = Flags & (0xFF - FLAG_C);
1653 }
1654
1655 Memory[address] = (Memory[address] << 1) & 0xFE;
1656
1657 set_flag_n(Memory[address]);
1658 set_flag_z(Memory[address]);
1659 break;
1660
1661
1662 case 0x89: //SAL Absolute X,Y
1663 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1664 LB = fetch();
1665 HB = fetch();
1666 address += (WORD)((WORD)HB << 8) + LB;
1667 saved_flags = Flags;
1668
1669 if ((Memory[address] & 0x80) == 0x80) {
1670 Flags = Flags | FLAG_C;
1671 }
1672 else {
1673 Flags = Flags & (0xFF - FLAG_C);
1674 }
1675
1676 Memory[address] = (Memory[address] << 1) & 0xFE;
1677
1678 set_flag_n(Memory[address]);
1679 set_flag_z(Memory[address]);
1680 break;
1681
1682
1683
1684 // SALA - Arithmetic shift left Memory or Accumulator
1685
1686 case 0x99: //SALA
1687 saved_flags = Flags;
1688
1689 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
1690 Flags = Flags | FLAG_C;
1691 }
1692 else {
1693 Flags = Flags & (0xFF - FLAG_C);
1694 }
1695 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
1696
1697 set_flag_n((BYTE)Registers[REGISTER_A]);
1698 set_flag_z((BYTE)Registers[REGISTER_A]);
1699 break;
1700
1701
1702
1703 // SHR - Arithmetic shift right Memory or Accumulator
1704
1705 case 0x5A: //SHR Absolute
1706 LB = fetch();
1707 HB = fetch();
1708 address = (WORD)((WORD)HB << 8) + LB;
1709 if ((Memory[address] & 0x01) == 0x01) {
1710 Flags = Flags | FLAG_C;
1711 }
1712 else {
1713 Flags = Flags & (0xFF - FLAG_C);
1714 }
1715 HB = Memory[address];
1716 Memory[address] = (Memory[address] >> 1) & 0x7F;
1717 if ((HB & 0x80) == 0x80) {
1718 Memory[address] = Memory[address] | 0x80;
1719 }
1720 set_flag_n(Memory[address]);
1721 set_flag_z(Memory[address]);
1722 break;
1723
1724 case 0x6A: //SHR Absolute X
1725 address += Index_Registers[REGISTER_X];
1726 LB = fetch();
1727 HB = fetch();
1728 address = (WORD)((WORD)HB << 8) + LB;
1729 if ((Memory[address] & 0x01) == 0x01) {
1730 Flags = Flags | FLAG_C;
1731 }
1732 else {
1733 Flags = Flags & (0xFF - FLAG_C);
1734 }
1735 HB = Memory[address];
1736 Memory[address] = (Memory[address] >> 1) & 0x7F;
1737 if ((HB & 0x80) == 0x80) {
1738 Memory[address] = Memory[address] | 0x80;
1739 }
1740 set_flag_n(Memory[address]);
1741 set_flag_z(Memory[address]);
1742 break;
1743
1744 case 0x7A: //SHR Absolute Y
1745 address += Index_Registers[REGISTER_Y];
1746 LB = fetch();
1747 HB = fetch();
1748 address = (WORD)((WORD)HB << 8) + LB;
1749 if ((Memory[address] & 0x01) == 0x01) {
1750 Flags = Flags | FLAG_C;
1751 }
1752 else {
1753 Flags = Flags & (0xFF - FLAG_C);
1754 }
1755 HB = Memory[address];
1756 Memory[address] = (Memory[address] >> 1) & 0x7F;
1757 if ((HB & 0x80) == 0x80) {
1758 Memory[address] = Memory[address] | 0x80;
1759 }
1760 set_flag_n(Memory[address]);
1761 set_flag_z(Memory[address]);
1762
1763 break;
1764
1765 case 0x8A: //SHR Absolute X,Y
1766 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1767 LB = fetch();
1768 HB = fetch();
1769 address = (WORD)((WORD)HB << 8) + LB;
1770 if ((Memory[address] & 0x01) == 0x01) {
1771 Flags = Flags | FLAG_C;
1772 }
1773 else {
1774 Flags = Flags & (0xFF - FLAG_C);
1775 }
1776 HB = Memory[address];
1777 Memory[address] = (Memory[address] >> 1) & 0x7F;
1778 if ((HB & 0x80) == 0x80) {
1779 Memory[address] = Memory[address] | 0x80;
1780 }
1781 set_flag_n(Memory[address]);
1782 set_flag_z(Memory[address]);
1783 break;
1784
1785
1786
1787 // SHRA - Arithmetic shift right Memory or Accumulator
1788
1789 case 0x9A: //SHRA
1790 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
1791 Flags = Flags | FLAG_C;
1792 }
1793 else {
1794 Flags = Flags & (0xFF - FLAG_C);
1795 }
1796 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
1797 if ((Flags & FLAG_N) == FLAG_N)
1798 {
1799 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
1800 }
1801 set_flag_n((BYTE)Registers[REGISTER_A]);
1802 set_flag_z((BYTE)Registers[REGISTER_A]);
1803 break;
1804
1805
1806
1807 // COM - Negate Memory or Accumulator
1808
1809 case 0x5B: //COM Absolute
1810 LB = fetch();
1811 HB = fetch();
1812 address += (WORD)((WORD)HB << 8) + LB;
1813 Memory[address] = Memory[address] ^ 0xFFFF;
1814
1815 Flags = Flags | FLAG_C;
1816 set_flag_n(Memory[address]);
1817 set_flag_z(Memory[address]);
1818 break;
1819 case 0x6B: //COM Absolute X
1820 address += Index_Registers[REGISTER_X];
1821
1822 LB = fetch();
1823 HB = fetch();
1824 address += (WORD)((WORD)HB << 8) + LB;
1825 Memory[address] = Memory[address] ^ 0xFFFF;
1826
1827 Flags = Flags | FLAG_C;
1828 set_flag_n(Memory[address]);
1829 set_flag_z(Memory[address]);
1830 break;
1831 case 0x7B: //COM Absolute Y
1832 address += Index_Registers[REGISTER_Y];
1833
1834 LB = fetch();
1835 HB = fetch();
1836 address += (WORD)((WORD)HB << 8) + LB;
1837 Memory[address] = Memory[address] ^ 0xFFFF;
1838
1839 Flags = Flags | FLAG_C;
1840 set_flag_n(Memory[address]);
1841 set_flag_z(Memory[address]);
1842 break;
1843 case 0x8B: //COM Absolute X,Y
1844 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1845 LB = fetch();
1846 HB = fetch();
1847 address += (WORD)((WORD)HB << 8) + LB;
1848 Memory[address] = Memory[address] ^ 0xFFFF;
1849
1850 Flags = Flags | FLAG_C;
1851 set_flag_n(Memory[address]);
1852 set_flag_z(Memory[address]);
1853 break;///////////////// COM
1854
1855 // COMA - Negate Memory or Accumulator
1856
1857 case 0x9B: //COMA
1858 Registers[REGISTER_A] = Registers[REGISTER_A] ^ 0xFF;
1859 Flags = Flags | FLAG_C;
1860 set_flag_n(Registers[REGISTER_A]);
1861 set_flag_z(Registers[REGISTER_A]);
1862 break;
1863
1864
1865
1866 // NEG - 2�s complement Memory or Accumulator
1867
1868 case 0x5C: //NEG Absolute
1869 LB = fetch();
1870 HB = fetch();
1871 address += (WORD)((WORD)HB << 8) + LB;
1872 Memory[address] = 0 - Memory[address];
1873 set_flag_n(Memory[address]);
1874 set_flag_z(Memory[address]);
1875 break;
1876
1877 case 0x6C: //NEG Absolute X
1878 address += Index_Registers[REGISTER_X];
1879
1880 LB = fetch();
1881 HB = fetch();
1882 address += (WORD)((WORD)HB << 8) + LB;
1883 Memory[address] = 0 - Memory[address];
1884 set_flag_n(Memory[address]);
1885 set_flag_z(Memory[address]);
1886 break;
1887
1888 case 0x7C: //NEG Absolute Y
1889 address += Index_Registers[REGISTER_Y];
1890
1891 LB = fetch();
1892 HB = fetch();
1893 address += (WORD)((WORD)HB << 8) + LB;
1894
1895 Memory[address] = 0 - Memory[address];
1896 set_flag_n(Memory[address]);
1897 set_flag_z(Memory[address]);
1898 break;
1899
1900 case 0x8C: //NEG Absolute X,Y
1901 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1902 LB = fetch();
1903 HB = fetch();
1904 address += (WORD)((WORD)HB << 8) + LB;
1905 Memory[address] = 0 - Memory[address];
1906
1907 set_flag_n(Memory[address]);
1908 set_flag_z(Memory[address]);
1909 break;
1910
1911
1912
1913 // NEGA - 2�s complement Memory or Accumulator
1914
1915 case 0x9C: //NEGA Register A
1916 Registers[REGISTER_A] = Registers[REGISTER_A] ^ 0xFF;
1917 Registers[REGISTER_A]++;
1918
1919 set_flag_n(Registers[REGISTER_A]);
1920 set_flag_z(Registers[REGISTER_A]);
1921 break;
1922
1923
1924
1925 // RAL - Rotate left without carry Memory or Accumulator
1926
1927 case 0x5D: //RAL Absolute
1928 LB = fetch();
1929 HB = fetch();
1930 address += (WORD)((WORD)HB << 8) + LB;
1931
1932 saved_flags = Flags;
1933
1934 if ((Memory[address] & 0x80) == 0x80) {
1935 Flags = Flags | FLAG_C;
1936 }
1937 else {
1938 Flags = Flags & (0xFF - FLAG_C);
1939 }
1940 Memory[address] = (Memory[address] << 1) & 0xFE;
1941
1942 if ((Flags & FLAG_C) == FLAG_C) {
1943 Memory[address] = Memory[address] | 0x01;
1944 }
1945 Flags = saved_flags;
1946 set_flag_n((BYTE)Memory[address]);
1947 set_flag_z((BYTE)Memory[address]);
1948 break;
1949 case 0x6D: //RAL Absolute X
1950 address += Index_Registers[REGISTER_X];
1951
1952 LB = fetch();
1953 HB = fetch();
1954 address += (WORD)((WORD)HB << 8) + LB;
1955
1956 saved_flags = Flags;
1957
1958 if ((Memory[address] & 0x80) == 0x80) {
1959 Flags = Flags | FLAG_C;
1960 }
1961 else {
1962 Flags = Flags & (0xFF - FLAG_C);
1963 }
1964 Memory[address] = (Memory[address] << 1) & 0xFE;
1965
1966 if ((Flags & FLAG_C) == FLAG_C) {
1967 Memory[address] = Memory[address] | 0x01;
1968 }
1969 Flags = saved_flags;
1970 set_flag_n((BYTE)Memory[address]);
1971 set_flag_z((BYTE)Memory[address]);
1972 break;
1973 case 0x7D: //RAL Absolute Y
1974 address += Index_Registers[REGISTER_Y];
1975
1976 LB = fetch();
1977 HB = fetch();
1978 address += (WORD)((WORD)HB << 8) + LB;
1979
1980 saved_flags = Flags;
1981
1982 if ((Memory[address] & 0x80) == 0x80) {
1983 Flags = Flags | FLAG_C;
1984 }
1985 else {
1986 Flags = Flags & (0xFF - FLAG_C);
1987 }
1988 Memory[address] = (Memory[address] << 1) & 0xFE;
1989
1990 if ((Flags & FLAG_C) == FLAG_C) {
1991 Memory[address] = Memory[address] | 0x01;
1992 }
1993 Flags = saved_flags;
1994 set_flag_n((BYTE)Memory[address]);
1995 set_flag_z((BYTE)Memory[address]);
1996 break;
1997 case 0x8D: //RAL Absolute X,Y
1998 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1999 LB = fetch();
2000 HB = fetch();
2001 address += (WORD)((WORD)HB << 8) + LB;
2002
2003 saved_flags = Flags;
2004
2005 if ((Memory[address] & 0x80) == 0x80) {
2006 Flags = Flags | FLAG_C;
2007 }
2008 else {
2009 Flags = Flags & (0xFF - FLAG_C);
2010 }
2011 Memory[address] = (Memory[address] << 1) & 0xFE;
2012
2013 if ((Flags & FLAG_C) == FLAG_C) {
2014 Memory[address] = Memory[address] | 0x01;
2015 }
2016 Flags = saved_flags;
2017 set_flag_n((BYTE)Memory[address]);
2018 set_flag_z((BYTE)Memory[address]);
2019 break;
2020
2021 // RALA - Rotate left without carry Memory or Accumulator
2022
2023 case 0x9D: //RALA Register A
2024 saved_flags = Flags;
2025
2026 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
2027 Flags = Flags | FLAG_C;
2028 }
2029 else {
2030 Flags = Flags & (0xFF - FLAG_C);
2031 }
2032 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
2033
2034 if ((Flags & FLAG_C) == FLAG_C) {
2035 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
2036 }
2037 Flags = saved_flags;
2038 set_flag_n((BYTE)Registers[REGISTER_A]);
2039 set_flag_z((BYTE)Registers[REGISTER_A]);
2040 break;
2041
2042
2043 // ROR - Rotate right without carry Memory or Accumulator
2044
2045
2046 case 0x5E: //ROR Absolute
2047 LB = fetch();
2048 HB = fetch();
2049 address += (WORD)((WORD)HB << 8) + LB;
2050 saved_flags = Flags;
2051
2052 if ((Memory[address] & 0x01) == 0x01) {
2053 Flags = Flags | FLAG_C;
2054 }
2055 else {
2056 Flags = Flags & (0xFF - FLAG_C);
2057 }
2058 Memory[address] = (Memory[address] >> 1) & 0x7F;
2059
2060 if ((Flags & FLAG_C) == FLAG_C) {
2061 Memory[address] = Memory[address] | 0x80;
2062 }
2063 Flags = saved_flags;
2064 set_flag_n((BYTE)Memory[address]);
2065 set_flag_z((BYTE)Memory[address]);
2066 break;
2067 case 0x6E: //ROR Absolute X
2068 address += Index_Registers[REGISTER_X];
2069
2070 LB = fetch();
2071 HB = fetch();
2072 address += (WORD)((WORD)HB << 8) + LB;
2073 saved_flags = Flags;
2074
2075 if ((Memory[address] & 0x01) == 0x01) {
2076 Flags = Flags | FLAG_C;
2077 }
2078 else {
2079 Flags = Flags & (0xFF - FLAG_C);
2080 }
2081 Memory[address] = (Memory[address] >> 1) & 0x7F;
2082
2083 if ((Flags & FLAG_C) == FLAG_C) {
2084 Memory[address] = Memory[address] | 0x80;
2085 }
2086 Flags = saved_flags;
2087 set_flag_n((BYTE)Memory[address]);
2088 set_flag_z((BYTE)Memory[address]);
2089 break;
2090 case 0x7E: //ROR Absolute Y
2091 address += Index_Registers[REGISTER_Y];
2092
2093 LB = fetch();
2094 HB = fetch();
2095 address += (WORD)((WORD)HB << 8) + LB;
2096 saved_flags = Flags;
2097
2098 if ((Memory[address] & 0x01) == 0x01) {
2099 Flags = Flags | FLAG_C;
2100 }
2101 else {
2102 Flags = Flags & (0xFF - FLAG_C);
2103 }
2104 Memory[address] = (Memory[address] >> 1) & 0x7F;
2105
2106 if ((Flags & FLAG_C) == FLAG_C) {
2107 Memory[address] = Memory[address] | 0x80;
2108 }
2109 Flags = saved_flags;
2110 set_flag_n((BYTE)Memory[address]);
2111 set_flag_z((BYTE)Memory[address]);
2112 break;
2113 case 0x8E: //ROR Absolute X,Y
2114 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2115 LB = fetch();
2116 HB = fetch();
2117 address += (WORD)((WORD)HB << 8) + LB;
2118 saved_flags = Flags;
2119
2120 if ((Memory[address] & 0x01) == 0x01) {
2121 Flags = Flags | FLAG_C;
2122 }
2123 else {
2124 Flags = Flags & (0xFF - FLAG_C);
2125 }
2126 Memory[address] = (Memory[address] >> 1) & 0x7F;
2127
2128 if ((Flags & FLAG_C) == FLAG_C) {
2129 Memory[address] = Memory[address] | 0x80;
2130 }
2131 Flags = saved_flags;
2132 set_flag_n((BYTE)Memory[address]);
2133 set_flag_z((BYTE)Memory[address]);
2134
2135 break;
2136
2137 // RORA - Rotate right without carry Memory or Accumulator
2138
2139 case 0x9E: //RORA Register A
2140 saved_flags = Flags;
2141
2142 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
2143 Flags = Flags | FLAG_C;
2144 }
2145 else {
2146 Flags = Flags & (0xFF - FLAG_C);
2147 }
2148 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
2149
2150 if ((Flags & FLAG_C) == FLAG_C) {
2151 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
2152 }
2153 Flags = saved_flags;
2154 set_flag_n((BYTE)Registers[REGISTER_A]);
2155 set_flag_z((BYTE)Registers[REGISTER_A]);
2156 break;
2157
2158
2159
2160 // CLR - Clear Memory or Accumulator
2161
2162 case 0x5F: // CLR abs
2163 LB = fetch();
2164 HB = fetch();
2165 address += (WORD)((WORD)HB << 8) + LB;
2166 Memory[address] = 0;
2167 Flags = Flags | FLAG_Z;
2168 Flags = Flags & (0xFF - FLAG_N);
2169 Flags = Flags & (0xFF - FLAG_C);
2170 break;
2171
2172 case 0x6F: // CLR abs X
2173 address += Index_Registers[REGISTER_X];
2174 LB = fetch();
2175 HB = fetch();
2176 address += (WORD)((WORD)HB << 8) + LB;
2177 Memory[address] = 0;
2178 Flags = Flags | FLAG_Z;
2179 Flags = Flags & (0xFF - FLAG_N);
2180 Flags = Flags & (0xFF - FLAG_C);
2181 break;
2182
2183 case 0x7F: // CLR abs Y
2184 address += Index_Registers[REGISTER_Y];
2185 LB = fetch();
2186 HB = fetch();
2187 address += (WORD)((WORD)HB << 8) + LB;
2188 Memory[address] = 0;
2189 Flags = Flags | FLAG_Z;
2190 Flags = Flags & (0xFF - FLAG_N);
2191 Flags = Flags & (0xFF - FLAG_C);
2192 break;
2193
2194 case 0x8F: // CLR abs XY
2195 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2196 LB = fetch();
2197 HB = fetch();
2198 address += (WORD)((WORD)HB << 8) + LB;
2199 Memory[address] = 0;
2200 Flags = Flags | FLAG_Z;
2201 Flags = Flags & (0xFF - FLAG_N);
2202 Flags = Flags & (0xFF - FLAG_C);
2203 break;
2204
2205 // CLRA - Clear Memory or Accumulator
2206
2207 case 0x9F: //CLRA
2208 Registers[REGISTER_A] = 0;
2209 Flags = Flags | FLAG_Z;
2210 Flags = Flags & (0xFF - FLAG_N);
2211 Flags = Flags & (0xFF - FLAG_C);
2212 break;
2213
2214
2215
2216 // LDX - Loads Memory into Register X
2217
2218 case 0x21://LDX Immediate
2219 data = fetch();
2220 Index_Registers[REGISTER_X] = data;
2221 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
2222 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
2223 break;
2224
2225 case 0x31: //LDX Absoulute
2226 LB = fetch();
2227 HB = fetch();
2228 address += (WORD)((WORD)HB << 8) + LB;
2229 if (address >= 0 && address < MEMORY_SIZE) {
2230 Index_Registers[REGISTER_X] = Memory[address];
2231 }
2232 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
2233 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
2234 break;
2235
2236 case 0x41://LDX Absoulte X
2237 address += Index_Registers[REGISTER_X];
2238 LB = fetch();
2239 HB = fetch();
2240 address += (WORD)((WORD)HB << 8) + LB;
2241 if (address >= 0 && address < MEMORY_SIZE) {
2242 Index_Registers[REGISTER_X] = Memory[address];
2243 }
2244 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
2245 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
2246 break;
2247
2248 case 0x51://LDX Absoulte Y
2249 address += Index_Registers[REGISTER_Y];
2250 LB = fetch();
2251 HB = fetch();
2252 address += (WORD)((WORD)HB << 8) + LB;
2253 if (address >= 0 && address < MEMORY_SIZE) {
2254 Index_Registers[REGISTER_X] = Memory[address];
2255 }
2256 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
2257 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
2258 break;
2259
2260 case 0x61://LDX Absoulte XY
2261 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2262 LB = fetch();
2263 HB = fetch();
2264 address += (WORD)((WORD)HB << 8) + LB;
2265 if (address >= 0 && address < MEMORY_SIZE) {
2266 Index_Registers[REGISTER_X] = Memory[address];
2267 }
2268 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
2269 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
2270 break;
2271
2272 case 0x71://LDX zpg
2273 address += 0x0000 | (WORD)fetch();
2274 if (address >= 0 && address < MEMORY_SIZE) {
2275 Index_Registers[REGISTER_X] = Memory[address];
2276 }
2277 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
2278 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
2279 break;
2280
2281
2282
2283 // STOX - Stores Register X into Memory
2284
2285
2286 case 0x05://STOX Absolute
2287 LB = fetch();
2288 HB = fetch();
2289 address += (WORD)((WORD)HB << 8) + LB;
2290 if (address >= 0 && address < MEMORY_SIZE) {
2291 Memory[address] = Index_Registers[REGISTER_X];
2292 }
2293 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
2294 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
2295 break;
2296
2297 case 0x15://STOX Absolute X
2298 address += Index_Registers[REGISTER_X];
2299 LB = fetch();
2300 HB = fetch();
2301 address += (WORD)((WORD)HB << 8) + LB;
2302 if (address >= 0 && address < MEMORY_SIZE) {
2303 Memory[address] = Index_Registers[REGISTER_X];
2304 }
2305 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
2306 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
2307 break;
2308
2309 case 0x25: //STOX Absolute Y
2310 address += Index_Registers[REGISTER_Y];
2311 LB = fetch();
2312 HB = fetch();
2313 address += (WORD)((WORD)HB << 8) + LB;
2314 if (address >= 0 && address < MEMORY_SIZE) {
2315 Memory[address] = Index_Registers[REGISTER_X];
2316 }
2317 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
2318 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
2319 break;
2320
2321 case 0x35://STOX Absolute XY
2322 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2323 LB = fetch();
2324 HB = fetch();
2325 address += (WORD)((WORD)HB << 8) + LB;
2326 if (address >= 0 && address < MEMORY_SIZE) {
2327 Memory[address] = Index_Registers[REGISTER_X];
2328 }
2329 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
2330 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
2331 break;
2332
2333 case 0x45://STOX zpg
2334 address += 0x0000 | (WORD)fetch();
2335 if (address >= 0 && address < MEMORY_SIZE) {
2336 Memory[address] = Index_Registers[REGISTER_X];
2337 }
2338 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
2339 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
2340 break;
2341
2342
2343
2344 // DEX - Decrements Register X
2345
2346 case 0x4A: // DEX impl
2347 Index_Registers[REGISTER_X]--;
2348 set_flag_z(Index_Registers[REGISTER_X]);
2349 break;
2350
2351 // INX - Increments register X
2352
2353 case 0x4B: //INX impl
2354 ++Index_Registers[REGISTER_X];
2355 set_flag_z(Index_Registers[REGISTER_X]);
2356 break;
2357
2358
2359
2360 // LODY - Loads Memory into Register Y
2361
2362 case 0x22://LODY Immediate
2363 data = fetch();
2364 Index_Registers[REGISTER_Y] = data;
2365 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2366 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
2367 break;
2368
2369 case 0x32: //LODY Absoulute
2370 LB = fetch();
2371 HB = fetch();
2372 address += (WORD)((WORD)HB << 8) + LB;
2373 if (address >= 0 && address < MEMORY_SIZE) {
2374 Index_Registers[REGISTER_Y] = Memory[address];
2375 }
2376 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2377 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
2378 break;
2379
2380 case 0x42://LODY Absoulte X
2381 address += Index_Registers[REGISTER_X];
2382 LB = fetch();
2383 HB = fetch();
2384 address += (WORD)((WORD)HB << 8) + LB;
2385 if (address >= 0 && address < MEMORY_SIZE) {
2386 Index_Registers[REGISTER_Y] = Memory[address];
2387 }
2388 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2389 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
2390 break;
2391
2392 case 0x52://LODY Absoulte Y
2393 address += Index_Registers[REGISTER_Y];
2394 LB = fetch();
2395 HB = fetch();
2396 address += (WORD)((WORD)HB << 8) + LB;
2397 if (address >= 0 && address < MEMORY_SIZE) {
2398 Index_Registers[REGISTER_Y] = Memory[address];
2399 }
2400 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2401 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
2402 break;
2403
2404 case 0x62://LODY Absoulte XY
2405 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2406 LB = fetch();
2407 HB = fetch();
2408 address += (WORD)((WORD)HB << 8) + LB;
2409 if (address >= 0 && address < MEMORY_SIZE) {
2410 Index_Registers[REGISTER_Y] = Memory[address];
2411 }
2412 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2413 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
2414 break;
2415
2416 case 0x72://LODY zpg
2417 address += 0x0000 | (WORD)fetch();
2418 if (address >= 0 && address < MEMORY_SIZE) {
2419 Index_Registers[REGISTER_Y] = Memory[address];
2420 }
2421 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2422 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
2423 break;
2424
2425
2426
2427 // STOY - Stores Register Y into Memory
2428
2429
2430 case 0x06://STOY Absolute
2431 LB = fetch();
2432 HB = fetch();
2433 address += (WORD)((WORD)HB << 8) + LB;
2434 if (address >= 0 && address < MEMORY_SIZE) {
2435 Memory[address] = Index_Registers[REGISTER_Y];
2436 }
2437 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2438 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
2439 break;
2440
2441 case 0x16://STOY Absolute X
2442 address += Index_Registers[REGISTER_X];
2443 LB = fetch();
2444 HB = fetch();
2445 address += (WORD)((WORD)HB << 8) + LB;
2446 if (address >= 0 && address < MEMORY_SIZE) {
2447 Memory[address] = Index_Registers[REGISTER_Y];
2448 }
2449 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2450 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
2451 break;
2452
2453 case 0x26: //STOY Absolute Y
2454 address += Index_Registers[REGISTER_Y];
2455 LB = fetch();
2456 HB = fetch();
2457 address += (WORD)((WORD)HB << 8) + LB;
2458 if (address >= 0 && address < MEMORY_SIZE) {
2459 Memory[address] = Index_Registers[REGISTER_Y];
2460 }
2461 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2462 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
2463 break;
2464
2465 case 0x36://STOY Absolute XY
2466 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2467 LB = fetch();
2468 HB = fetch();
2469 address += (WORD)((WORD)HB << 8) + LB;
2470 if (address >= 0 && address < MEMORY_SIZE) {
2471 Memory[address] = Index_Registers[REGISTER_Y];
2472 }
2473 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2474 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
2475 break;
2476
2477 case 0x46://STOY zpg
2478 address += 0x0000 | (WORD)fetch();
2479 if (address >= 0 && address < MEMORY_SIZE) {
2480 Memory[address] = Index_Registers[REGISTER_Y];
2481 }
2482 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2483 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
2484 break;
2485
2486
2487
2488 // TAY - Transters Accumulator to Register Y
2489
2490 case 0x2B://TAY
2491 Index_Registers[REGISTER_Y] = Registers[REGISTER_A];
2492 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2493 break;
2494
2495
2496
2497 // TYA - Transters register Y to Accumulator
2498
2499 case 0x2C://TYA
2500 Registers[REGISTER_A] = Index_Registers[REGISTER_Y];
2501 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
2502 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
2503 break;
2504
2505
2506
2507 // DEY - Decrements Register Y
2508
2509 case 0x4C: //DEY impl
2510 Index_Registers[REGISTER_Y]--;
2511 set_flag_z(Index_Registers[REGISTER_Y]);
2512 break;
2513
2514
2515
2516 // INY - Increments Register Y
2517
2518 case 0x4D: //INY impl
2519 ++Index_Registers[REGISTER_Y];
2520 set_flag_z(Index_Registers[REGISTER_Y]);
2521 break;
2522
2523
2524
2525 // LODS - Loads Memory into Stackpointer
2526
2527 case 0x20://LODS Immediate
2528 data = fetch();
2529 StackPointer = data;
2530 StackPointer += (WORD)fetch() << 8;
2531 set_flag_n_16bit(StackPointer);
2532 set_flag_z_16bit(StackPointer);
2533 break;
2534
2535 case 0x30://LODS Absoulte
2536 LB = fetch();
2537 HB = fetch();
2538 address += (WORD)((WORD)HB << 8) + LB;
2539 if (address >= 0 && address < MEMORY_SIZE - 1) {
2540 StackPointer = Memory[address];
2541 StackPointer += (WORD)Memory[address + 1] << 8;
2542 }
2543 set_flag_n_16bit(StackPointer);
2544 set_flag_z_16bit(StackPointer);
2545 break;
2546
2547 case 0x40://LODS Absoulte X
2548 address += Index_Registers[REGISTER_X];
2549 LB = fetch();
2550 HB = fetch();
2551 address += (WORD)((WORD)HB << 8) + LB;
2552 if (address >= 0 && address < MEMORY_SIZE - 1) {
2553 StackPointer = Memory[address];
2554 StackPointer += (WORD)Memory[address + 1] << 8;
2555 }
2556 set_flag_n_16bit(StackPointer);
2557 set_flag_z_16bit(StackPointer);
2558 break;
2559
2560 case 0x50://LODS Absoulte Y
2561 address += Index_Registers[REGISTER_Y];
2562 LB = fetch();
2563 HB = fetch();
2564 address += (WORD)((WORD)HB << 8) + LB;
2565 if (address >= 0 && address < MEMORY_SIZE - 1) {
2566 StackPointer = Memory[address];
2567 StackPointer += (WORD)Memory[address + 1] << 8;
2568 }
2569 set_flag_n_16bit(StackPointer);
2570 set_flag_z_16bit(StackPointer);
2571 break;
2572
2573 case 0x60://LODS Absolute XY
2574 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2575 LB = fetch();
2576 HB = fetch();
2577 address += (WORD)((WORD)HB << 8) + LB;
2578 if (address >= 0 && address < MEMORY_SIZE - 1) {
2579 StackPointer = Memory[address];
2580 StackPointer += (WORD)Memory[address + 1] << 8;
2581 }
2582 set_flag_n_16bit(StackPointer);
2583 set_flag_z_16bit(StackPointer);
2584 break;
2585
2586 case 0x70://LODS zpg
2587 address += 0x0000 | (WORD)fetch();
2588 if (address >= 0 && address < MEMORY_SIZE - 1) {
2589 StackPointer = Memory[address];
2590 StackPointer += (WORD)Memory[address + 1] << 8;
2591 }
2592 set_flag_n_16bit(StackPointer);
2593 set_flag_z_16bit(StackPointer);
2594 break;
2595
2596
2597
2598 // STOS - Stores Stackpointer into Memory
2599
2600 case 0x0F://STOS Absoulte
2601 LB = fetch();
2602 HB = fetch();
2603 address += (WORD)((WORD)HB << 8) + LB;
2604 if (address >= 0 && address < MEMORY_SIZE) {
2605 Memory[address] = StackPointer;
2606 }
2607 set_flag_z_16bit(StackPointer);
2608 set_flag_n_16bit(StackPointer);
2609 break;
2610
2611 case 0x1F://STOS Absoulte X
2612 address += Index_Registers[REGISTER_X];
2613 LB = fetch();
2614 HB = fetch();
2615 address += (WORD)((WORD)HB << 8) + LB;
2616 if (address >= 0 && address < MEMORY_SIZE) {
2617 Memory[address] = StackPointer;
2618 }
2619 set_flag_z_16bit(StackPointer);
2620 set_flag_n_16bit(StackPointer);
2621 break;
2622
2623 case 0x2F://STOS Absoulte Y
2624 address += Index_Registers[REGISTER_Y];
2625 LB = fetch();
2626 HB = fetch();
2627 address += (WORD)((WORD)HB << 8) + LB;
2628 if (address >= 0 && address < MEMORY_SIZE) {
2629 Memory[address] = StackPointer;
2630 }
2631 set_flag_z_16bit(StackPointer);
2632 set_flag_n_16bit(StackPointer);
2633 break;
2634
2635 case 0x3F://STOS Absolute XY
2636 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2637 LB = fetch();
2638 HB = fetch();
2639 address += (WORD)((WORD)HB << 8) + LB;
2640 if (address >= 0 && address < MEMORY_SIZE) {
2641 Memory[address] = StackPointer;
2642 }
2643 set_flag_z_16bit(StackPointer);
2644 set_flag_n_16bit(StackPointer);
2645 break;
2646
2647 case 0x4F://STOS zpg
2648 address += 0x0000 | (WORD)fetch();
2649 if (address >= 0 && address < MEMORY_SIZE) {
2650 Memory[address] = StackPointer;
2651 }
2652 set_flag_z_16bit(StackPointer);
2653 set_flag_n_16bit(StackPointer);
2654 break;
2655
2656
2657
2658 // MSA - Transters Status register to Accumulator
2659
2660 case 0x2D://MSA
2661 Registers[REGISTER_A] = Flags;
2662 break;
2663
2664
2665
2666 // PUSH - Pushes Register onto the Stack
2667
2668 case 0xAE://PUSH REGISTER A
2669 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2670 StackPointer--;
2671 Memory[StackPointer] = Registers[REGISTER_A];
2672 }
2673 break;
2674
2675 case 0xBE://PUSH FLAGS
2676 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2677 StackPointer--;
2678 Memory[StackPointer] = Flags;
2679 }
2680 break;
2681
2682 case 0xCE://PUSH REGISTER B
2683 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2684 StackPointer--;
2685 Memory[StackPointer] = Registers[REGISTER_B];
2686 }
2687 break;
2688
2689 case 0xDE://PUSH REGISTER C
2690 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2691 StackPointer--;
2692 Memory[StackPointer] = Registers[REGISTER_C];
2693 }
2694 break;
2695
2696 case 0xEE://PUSH REGISTER L
2697 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2698 StackPointer--;
2699 Memory[StackPointer] = Registers[REGISTER_L];
2700 }
2701 break;
2702
2703 case 0xFE://PUSH REGISTER H
2704 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2705 StackPointer--;
2706 Memory[StackPointer] = Registers[REGISTER_H];
2707 }
2708 break;
2709
2710
2711
2712 // POP - Pop the top of the Stack into the Register
2713
2714 case 0xAF://POP REGISTER A
2715 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2716 Registers[REGISTER_A] = Memory[StackPointer];
2717 StackPointer++;
2718 }
2719 break;
2720
2721 case 0xBF://POP FLAGS
2722 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2723 Flags = Memory[StackPointer];
2724 StackPointer++;
2725 }
2726 break;
2727
2728 case 0xCF://POP REGISTER B
2729 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2730 Registers[REGISTER_B] = Memory[StackPointer];
2731 StackPointer++;
2732 }
2733 break;
2734
2735 case 0xDF://POP REGISTER C
2736 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2737 Registers[REGISTER_C] = Memory[StackPointer];
2738 StackPointer++;
2739 }
2740 break;
2741
2742 case 0xEF://POP REGISTER L
2743 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2744 Registers[REGISTER_L] = Memory[StackPointer];
2745 StackPointer++;
2746 }
2747 break;
2748
2749 case 0xFF://POP REGISTER H
2750 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2751 Registers[REGISTER_H] = Memory[StackPointer];
2752 StackPointer++;
2753 }
2754 break;
2755
2756
2757
2758 // JUMP - Loads Memory into abs 0x38 ProgramCounter
2759
2760 case 0x38: //JUMP abs
2761 LB = fetch();
2762 HB = fetch();
2763 address = ((WORD)HB << 8) + (WORD)LB;
2764 ProgramCounter = address;
2765 break;
2766
2767
2768
2769 // MVR - Loads Memory into Register
2770
2771 case 0x27://Register B MVR Intermediate
2772 data = fetch();
2773 Registers[REGISTER_B] = data;
2774 set_flag_n((BYTE)Registers[REGISTER_B]);
2775 set_flag_z((BYTE)Registers[REGISTER_B]);
2776 break;
2777
2778 case 0x28://Register C MVR Intermediate
2779 data = fetch();
2780 Registers[REGISTER_C] = data;
2781 set_flag_n((BYTE)Registers[REGISTER_C]);
2782 set_flag_z((BYTE)Registers[REGISTER_C]);
2783 break;
2784
2785 case 0x29://Register L MVR Intermediate
2786 data = fetch();
2787 Registers[REGISTER_L] = data;
2788 set_flag_n((BYTE)Registers[REGISTER_L]);
2789 set_flag_z((BYTE)Registers[REGISTER_L]);
2790 break;
2791
2792 case 0x2A://Register H MVR Intermediate
2793 data = fetch();
2794 Registers[REGISTER_H] = data;
2795 set_flag_n((BYTE)Registers[REGISTER_H]);
2796 set_flag_z((BYTE)Registers[REGISTER_H]);
2797 break;
2798
2799
2800
2801 // JMPR - Jump to subroutine
2802
2803 case 0x07: // JMPR
2804 LB = fetch();
2805 HB = fetch();
2806 address += ((WORD)HB << 8) + (WORD)LB;
2807 if ((StackPointer >= 2) && StackPointer < MEMORY_SIZE) {
2808
2809 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
2810 StackPointer--;
2811 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
2812 StackPointer--;
2813 }
2814 ProgramCounter = address;
2815 break;
2816
2817
2818
2819 // RT - Return from subroutine
2820
2821 case 0x23: //RT impl
2822 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
2823 HB = Memory[StackPointer];
2824 StackPointer++;
2825 LB = Memory[StackPointer];
2826 StackPointer++;
2827 }
2828 ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
2829 break;
2830
2831
2832
2833 // JCC - Jump on Carry clear
2834
2835 case 0x39: // JCC
2836 LB = fetch();
2837 HB = fetch();
2838 address = ((WORD)HB << 8) + (WORD)LB;
2839
2840 if (address >= 0 && address < MEMORY_SIZE) {
2841 if ((Flags & FLAG_C) == 0) {
2842 ProgramCounter = address;
2843 }
2844 }
2845 break;
2846
2847
2848
2849 //JCS - Jump on carry set
2850 case 0x3A: // JCS
2851 LB = fetch();
2852 HB = fetch();
2853 address = ((WORD)HB << 8) + (WORD)LB;
2854 if (address >= 0 && address < MEMORY_SIZE) {
2855 if ((Flags & FLAG_C) != 0) {
2856 ProgramCounter = address;
2857 }
2858 }
2859 break;
2860
2861
2862
2863 // JNE - Jump on result not zero
2864 case 0x3B: // JNE
2865 LB = fetch();
2866 HB = fetch();
2867 address = ((WORD)HB << 8) + (WORD)LB;
2868 if (address >= 0 && address < MEMORY_SIZE) {
2869 if ((Flags & FLAG_Z) == 0) {
2870 ProgramCounter = address;
2871 }
2872 }
2873 break;
2874
2875
2876
2877 // JEQ - jump on result equal to zero
2878 case 0x3C: // JEQ
2879 LB = fetch();
2880 HB = fetch();
2881 address = ((WORD)HB << 8) + (WORD)LB;
2882 if (address >= 0 && address < MEMORY_SIZE) {
2883 if ((Flags & FLAG_Z) != 0) {
2884 ProgramCounter = address;
2885 }
2886 }
2887 break;
2888
2889
2890
2891 // JMI - Jump on negative result
2892 case 0x3D: // JMI
2893 LB = fetch();
2894 HB = fetch();
2895 address = ((WORD)HB << 8) + (WORD)LB;
2896 if (address >= 0 && address < MEMORY_SIZE) {
2897 if ((Flags & FLAG_N) != 0) {
2898 ProgramCounter = address;
2899 }
2900 }
2901 break;
2902
2903
2904
2905 // JPL - Jump on positive result
2906 case 0x3E: // JPL
2907 LB = fetch();
2908 HB = fetch();
2909 address = ((WORD)HB << 8) + (WORD)LB;
2910 if (address >= 0 && address < MEMORY_SIZE) {
2911 if ((Flags & FLAG_N) == 0) {
2912 ProgramCounter = address;
2913 }
2914 }
2915
2916 break;
2917
2918
2919
2920 // CCC - Call on carry clear
2921 case 0x08: // CCC
2922 LB = fetch();
2923 HB = fetch();
2924 address = ((WORD)HB << 8) + (WORD)LB;
2925 if ((Flags & FLAG_C) == 0) {
2926 Memory[StackPointer] = ProgramCounter;
2927 StackPointer--;
2928 ProgramCounter = address;
2929 }
2930 break;
2931
2932
2933
2934 // CCS - Call on carry set
2935 case 0x09: // CCS
2936 LB = fetch();
2937 HB = fetch();
2938 address = ((WORD)HB << 8) + (WORD)LB;
2939
2940 if ((Flags & FLAG_C) != 0) {
2941 Memory[StackPointer] = ProgramCounter;
2942 StackPointer--;
2943 ProgramCounter = address;
2944 }
2945 break;
2946
2947
2948
2949 // CNE - Call on result not zero
2950 case 0x0A: // CNE
2951 LB = fetch();
2952 HB = fetch();
2953 address = ((WORD)HB << 8) + (WORD)LB;
2954
2955 if ((Flags & FLAG_Z) == 0) {
2956 Memory[StackPointer] = ProgramCounter;
2957 StackPointer--;
2958 ProgramCounter = address;
2959 }
2960 break;
2961
2962
2963
2964 // CEQ - Call on result equal to zero
2965 case 0x0B: // CEQ
2966 LB = fetch();
2967 HB = fetch();
2968 address = ((WORD)HB << 8) + (WORD)LB;
2969
2970 if ((Flags & FLAG_Z) != 0) {
2971 Memory[StackPointer] = ProgramCounter;
2972 StackPointer--;
2973 ProgramCounter = address;
2974 }
2975 break;
2976
2977
2978
2979 // CMI - Call on negative result
2980 case 0x0C: // CMI
2981 LB = fetch();
2982 HB = fetch();
2983 address = ((WORD)HB << 8) + (WORD)LB;
2984
2985 if ((Flags & FLAG_N) != 0) {
2986 Memory[StackPointer] = ProgramCounter;
2987 StackPointer--;
2988 ProgramCounter = address;
2989 }
2990 break;
2991
2992
2993
2994 // CPL - Call on positive result
2995 case 0x0D: // CPL
2996 LB = fetch();
2997 HB = fetch();
2998 address = ((WORD)HB << 8) + (WORD)LB;
2999
3000 if ((Flags & FLAG_N) == 0) {
3001 Memory[StackPointer] = ProgramCounter;
3002 StackPointer--;
3003 ProgramCounter = address;
3004 }
3005 break;
3006
3007
3008
3009 //CLC - Clear carry flag
3010
3011 case 0xA6://CLC
3012 Flags = Flags & (0xFF - FLAG_C);
3013 break;
3014
3015
3016
3017 // SEC - Set carry flag
3018
3019 case 0xA7://SEC
3020 Flags = Flags | FLAG_C;
3021 break;
3022
3023
3024
3025 // CLI - Clear Interupt flag
3026
3027 case 0xA8://CLI
3028 Flags = Flags & (0xFF - FLAG_I);
3029 break;
3030
3031
3032
3033 // SEI - Set interupt flag
3034
3035 case 0xA9://SEI
3036 Flags = Flags | FLAG_I;
3037 break;
3038
3039
3040 // CMC - Compliment carry flag
3041
3042 case 0xAA://CMC
3043 Flags = Flags ^ FLAG_C;
3044 break;
3045
3046
3047
3048 // NOP - No operation
3049
3050 case 0x17: //NOP
3051 break;
3052
3053
3054
3055 // WAI - Wait for interupt
3056
3057 case 0x18: //WAI
3058 halt = true;
3059 break;
3060
3061
3062
3063 // SWI - Software interupt
3064
3065 case 0x02: //SWI (IMPL)
3066 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
3067 StackPointer--;
3068 Memory[StackPointer] = Registers[REGISTER_A];
3069 }
3070 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
3071 StackPointer--;
3072 Memory[StackPointer] = (BYTE)ProgramCounter;
3073 }
3074 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
3075 StackPointer--;
3076 Memory[StackPointer] = (BYTE)(ProgramCounter >> 8);
3077 }
3078 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
3079 StackPointer--;
3080 Memory[StackPointer] = Flags;
3081 }
3082 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
3083 StackPointer--;
3084 Memory[StackPointer] = Registers[REGISTER_B];
3085 }
3086 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
3087 StackPointer--;
3088 Memory[StackPointer] = Registers[REGISTER_C];
3089 }
3090 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
3091 StackPointer--;
3092 Memory[StackPointer] = Registers[REGISTER_L];
3093 }
3094 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
3095 StackPointer--;
3096 Memory[StackPointer] = Registers[REGISTER_H];
3097 }
3098
3099 Flags = Flags | FLAG_I;
3100
3101 break;
3102
3103
3104
3105 // RTI - Return from software interupt
3106
3107 case 0x03: //RTI (IMPL)
3108 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
3109 Registers[REGISTER_H] = Memory[StackPointer];
3110 StackPointer++;
3111 }
3112 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
3113 Registers[REGISTER_L] = Memory[StackPointer];
3114 StackPointer++;
3115 }
3116 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
3117 Registers[REGISTER_C] = Memory[StackPointer];
3118 StackPointer++;
3119 }
3120 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
3121 Registers[REGISTER_B] = Memory[StackPointer];
3122 StackPointer++;
3123 }
3124 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
3125 Flags = Memory[StackPointer];
3126 StackPointer++;
3127 }
3128 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
3129 ProgramCounter = (WORD)(Memory[StackPointer] << 8);
3130 StackPointer++;
3131 }
3132 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
3133 ProgramCounter += Memory[StackPointer];
3134 StackPointer++;
3135 }
3136 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
3137 Registers[REGISTER_A] = Memory[StackPointer];
3138 StackPointer++;
3139 }
3140 break;
3141 }
3142}
3143
3144void Group_2_Move(BYTE opcode) {
3145 BYTE source = opcode >> 4;
3146 BYTE destination = opcode & 0x0F;
3147 int destReg;
3148 int sourceReg;
3149 WORD address = 0;
3150
3151 switch (destination) {
3152 case 0x00:
3153 destReg = REGISTER_A;
3154 break;
3155 case 0x01:
3156 destReg = REGISTER_B;
3157 break;
3158 case 0x02:
3159 destReg = REGISTER_C;
3160 break;
3161 case 0x03:
3162 destReg = REGISTER_L;
3163 break;
3164 case 0x04:
3165 destReg = REGISTER_H;
3166 break;
3167 case 0x05:
3168 destReg = REGISTER_M;
3169 break;
3170 }
3171
3172 switch (source) {
3173 case 0x0A:
3174 sourceReg = REGISTER_A;
3175 break;
3176 case 0x0B:
3177 sourceReg = REGISTER_B;
3178 break;
3179 case 0x0C:
3180 sourceReg = REGISTER_C;
3181 break;
3182 case 0x0D:
3183 sourceReg = REGISTER_L;
3184 break;
3185 case 0x0E:
3186 sourceReg = REGISTER_H;
3187 break;
3188 case 0x0F:
3189 sourceReg = REGISTER_M;
3190 break;
3191 }
3192
3193 if (sourceReg == REGISTER_M) {
3194 address = Registers[REGISTER_L];
3195 address += (WORD)Registers[REGISTER_H] << 8;
3196 if (address >= 0 && address <= MEMORY_SIZE) {
3197 Registers[REGISTER_M] = Memory[address];
3198 }
3199 }
3200 if (destReg == REGISTER_M) {
3201 address = Registers[REGISTER_L];
3202 address += (WORD)Registers[REGISTER_H] << 8;
3203 if (address >= 0 && address <= MEMORY_SIZE) {
3204 Memory[address] = Registers[sourceReg];
3205 }
3206 }
3207 else {
3208 Registers[destReg] = Registers[sourceReg];
3209 }
3210
3211
3212
3213}
3214void execute(BYTE opcode) {
3215 BYTE source = opcode >> 4;
3216 BYTE destination = opcode & 0x0F;
3217 if (((source >= 0x0A) && (source <= 0x0F)) && ((destination >= 0x00) && (destination <= 0x05)))
3218 {
3219 Group_2_Move(opcode);
3220 }
3221 else
3222 {
3223 Group_1(opcode);
3224 }
3225}
3226
3227void emulate()
3228{
3229 BYTE opcode;
3230 int sanity;
3231
3232 ProgramCounter = 0;
3233 halt = false;
3234 memory_in_range = true;
3235 sanity = 0;
3236
3237 printf(" A B C L H X Y SP\n");
3238
3239
3240
3241 while ((!halt) && (memory_in_range)) {
3242
3243
3244 printf("%04X ", ProgramCounter); // Print current address
3245 opcode = fetch();
3246 execute(opcode);
3247
3248 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
3249
3250 printf("%02X ", Registers[REGISTER_A]);
3251 printf("%02X ", Registers[REGISTER_B]);
3252 printf("%02X ", Registers[REGISTER_C]);
3253 printf("%02X ", Registers[REGISTER_L]);
3254 printf("%02X ", Registers[REGISTER_H]);
3255 printf("%02X ", Index_Registers[REGISTER_X]);
3256 printf("%02X ", Index_Registers[REGISTER_Y]);
3257 printf("%04X ", StackPointer); // Print Stack Pointer
3258
3259 if ((Flags & FLAG_Z) == FLAG_Z)
3260 {
3261 printf("Z=1 ");
3262 }
3263 else
3264 {
3265 printf("Z=0 ");
3266 }
3267 if ((Flags & FLAG_I) == FLAG_I)
3268 {
3269 printf("I=1 ");
3270 }
3271 else
3272 {
3273 printf("I=0 ");
3274 }
3275 if ((Flags & FLAG_N) == FLAG_N)
3276 {
3277 printf("N=1 ");
3278 }
3279 else
3280 {
3281 printf("N=0 ");
3282 }
3283 if ((Flags & FLAG_C) == FLAG_C)
3284 {
3285 printf("C=1 ");
3286 }
3287 else
3288 {
3289 printf("C=0 ");
3290 }
3291
3292 printf("\n"); // New line
3293 if (sanity > 200) halt = true;
3294 sanity++;
3295
3296 }
3297
3298 printf("\n"); // New line
3299}
3300
3301
3302////////////////////////////////////////////////////////////////////////////////
3303// Simulator/Emulator (End) //
3304////////////////////////////////////////////////////////////////////////////////
3305
3306
3307void initialise_filenames() {
3308 int i;
3309
3310 for (i = 0; i < MAX_FILENAME_SIZE; i++) {
3311 hex_file[i] = '\0';
3312 trc_file[i] = '\0';
3313 }
3314}
3315
3316
3317
3318
3319int find_dot_position(char *filename) {
3320 int dot_position;
3321 int i;
3322 char chr;
3323
3324 dot_position = 0;
3325 i = 0;
3326 chr = filename[i];
3327
3328 while (chr != '\0') {
3329 if (chr == '.') {
3330 dot_position = i;
3331 }
3332 i++;
3333 chr = filename[i];
3334 }
3335
3336 return (dot_position);
3337}
3338
3339
3340int find_end_position(char *filename) {
3341 int end_position;
3342 int i;
3343 char chr;
3344
3345 end_position = 0;
3346 i = 0;
3347 chr = filename[i];
3348
3349 while (chr != '\0') {
3350 end_position = i;
3351 i++;
3352 chr = filename[i];
3353 }
3354
3355 return (end_position);
3356}
3357
3358
3359bool file_exists(char *filename) {
3360 bool exists;
3361 FILE *ifp;
3362
3363 exists = false;
3364
3365 if ((ifp = fopen(filename, "r")) != NULL) {
3366 exists = true;
3367
3368 fclose(ifp);
3369 }
3370
3371 return (exists);
3372}
3373
3374
3375
3376void create_file(char *filename) {
3377 FILE *ofp;
3378
3379 if ((ofp = fopen(filename, "w")) != NULL) {
3380 fclose(ofp);
3381 }
3382}
3383
3384
3385
3386bool getline(FILE *fp, char *buffer) {
3387 bool rc;
3388 bool collect;
3389 char c;
3390 int i;
3391
3392 rc = false;
3393 collect = true;
3394
3395 i = 0;
3396 while (collect) {
3397 c = getc(fp);
3398
3399 switch (c) {
3400 case EOF:
3401 if (i > 0) {
3402 rc = true;
3403 }
3404 collect = false;
3405 break;
3406
3407 case '\n':
3408 if (i > 0) {
3409 rc = true;
3410 collect = false;
3411 buffer[i] = '\0';
3412 }
3413 break;
3414
3415 default:
3416 buffer[i] = c;
3417 i++;
3418 break;
3419 }
3420 }
3421
3422 return (rc);
3423}
3424
3425
3426
3427
3428
3429
3430void load_and_run(int args, _TCHAR** argv) {
3431 char chr;
3432 int ln;
3433 int dot_position;
3434 int end_position;
3435 long i;
3436 FILE *ifp;
3437 long address;
3438 long load_at;
3439 int code;
3440
3441 // Prompt for the .hex file
3442
3443 printf("\n");
3444 printf("Enter the hex filename (.hex): ");
3445
3446 if (args == 2) {
3447 ln = 0;
3448 chr = argv[1][ln];
3449 while (chr != '\0')
3450 {
3451 if (ln < MAX_FILENAME_SIZE)
3452 {
3453 hex_file[ln] = chr;
3454 trc_file[ln] = chr;
3455 ln++;
3456 }
3457 chr = argv[1][ln];
3458 }
3459 }
3460 else {
3461 ln = 0;
3462 chr = '\0';
3463 while (chr != '\n') {
3464 chr = getchar();
3465
3466 switch (chr) {
3467 case '\n':
3468 break;
3469 default:
3470 if (ln < MAX_FILENAME_SIZE) {
3471 hex_file[ln] = chr;
3472 trc_file[ln] = chr;
3473 ln++;
3474 }
3475 break;
3476 }
3477 }
3478
3479 }
3480 // Tidy up the file names
3481
3482 dot_position = find_dot_position(hex_file);
3483 if (dot_position == 0) {
3484 end_position = find_end_position(hex_file);
3485
3486 hex_file[end_position + 1] = '.';
3487 hex_file[end_position + 2] = 'h';
3488 hex_file[end_position + 3] = 'e';
3489 hex_file[end_position + 4] = 'x';
3490 hex_file[end_position + 5] = '\0';
3491 }
3492 else {
3493 hex_file[dot_position + 0] = '.';
3494 hex_file[dot_position + 1] = 'h';
3495 hex_file[dot_position + 2] = 'e';
3496 hex_file[dot_position + 3] = 'x';
3497 hex_file[dot_position + 4] = '\0';
3498 }
3499
3500 dot_position = find_dot_position(trc_file);
3501 if (dot_position == 0) {
3502 end_position = find_end_position(trc_file);
3503
3504 trc_file[end_position + 1] = '.';
3505 trc_file[end_position + 2] = 't';
3506 trc_file[end_position + 3] = 'r';
3507 trc_file[end_position + 4] = 'c';
3508 trc_file[end_position + 5] = '\0';
3509 }
3510 else {
3511 trc_file[dot_position + 0] = '.';
3512 trc_file[dot_position + 1] = 't';
3513 trc_file[dot_position + 2] = 'r';
3514 trc_file[dot_position + 3] = 'c';
3515 trc_file[dot_position + 4] = '\0';
3516 }
3517
3518 if (file_exists(hex_file)) {
3519 // Clear Registers and Memory
3520
3521 Registers[REGISTER_A] = 0;
3522 Registers[REGISTER_B] = 0;
3523 Registers[REGISTER_C] = 0;
3524 Registers[REGISTER_L] = 0;
3525 Registers[REGISTER_H] = 0;
3526 Index_Registers[REGISTER_X] = 0;
3527 Index_Registers[REGISTER_Y] = 0;
3528 Flags = 0;
3529 ProgramCounter = 0;
3530 StackPointer = 0;
3531
3532 for (i = 0; i < MEMORY_SIZE; i++) {
3533 Memory[i] = 0x00;
3534 }
3535
3536 // Load hex file
3537
3538 if ((ifp = fopen(hex_file, "r")) != NULL) {
3539 printf("Loading file...\n\n");
3540
3541 load_at = 0;
3542
3543 while (getline(ifp, InputBuffer)) {
3544 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
3545 load_at = address;
3546 }
3547 else if (sscanf(InputBuffer, "%x", &code) == 1) {
3548 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
3549 Memory[load_at] = (BYTE)code;
3550 }
3551 load_at++;
3552 }
3553 else {
3554 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
3555 }
3556 }
3557
3558 fclose(ifp);
3559 }
3560
3561 // Emulate
3562
3563 emulate();
3564 }
3565 else {
3566 printf("\n");
3567 printf("ERROR> Input file %s does not exist!\n", hex_file);
3568 printf("\n");
3569 }
3570}
3571
3572void building(int args, _TCHAR** argv) {
3573 char buffer[1024];
3574 load_and_run(args, argv);
3575 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",
3576 Memory[TEST_ADDRESS_1],
3577 Memory[TEST_ADDRESS_2],
3578 Memory[TEST_ADDRESS_3],
3579 Memory[TEST_ADDRESS_4],
3580 Memory[TEST_ADDRESS_5],
3581 Memory[TEST_ADDRESS_6],
3582 Memory[TEST_ADDRESS_7],
3583 Memory[TEST_ADDRESS_8],
3584 Memory[TEST_ADDRESS_9],
3585 Memory[TEST_ADDRESS_10],
3586 Memory[TEST_ADDRESS_11],
3587 Memory[TEST_ADDRESS_12]
3588 );
3589 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
3590}
3591
3592
3593
3594void test_and_mark() {
3595 char buffer[1024];
3596 bool testing_complete;
3597 int len = sizeof(SOCKADDR);
3598 char chr;
3599 int i;
3600 int j;
3601 bool end_of_program;
3602 long address;
3603 long load_at;
3604 int code;
3605 int mark;
3606 int passed;
3607
3608 printf("\n");
3609 printf("Automatic Testing and Marking\n");
3610 printf("\n");
3611
3612 testing_complete = false;
3613
3614 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
3615 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
3616
3617 while (!testing_complete) {
3618 memset(buffer, '\0', sizeof(buffer));
3619
3620 if (recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
3621 printf("Incoming Data: %s \n", buffer);
3622
3623 //if (strcmp(buffer, "Testing complete") == 1)
3624 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
3625 testing_complete = true;
3626 printf("Current mark = %d\n", mark);
3627
3628 }
3629 else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
3630 //testing_complete = true;
3631 printf("Passed = %d\n", passed);
3632
3633 }
3634 else if (strcmp(buffer, "Error") == 0) {
3635 printf("ERROR> Testing abnormally terminated\n");
3636 testing_complete = true;
3637 }
3638 else {
3639 // Clear Registers and Memory
3640
3641 Registers[REGISTER_A] = 0;
3642 Registers[REGISTER_B] = 0;
3643 Registers[REGISTER_C] = 0;
3644 Registers[REGISTER_L] = 0;
3645 Registers[REGISTER_H] = 0;
3646 Index_Registers[REGISTER_X] = 0;
3647 Index_Registers[REGISTER_Y] = 0;
3648 Flags = 0;
3649 ProgramCounter = 0;
3650 StackPointer = 0;
3651 for (i = 0; i < MEMORY_SIZE; i++) {
3652 Memory[i] = 0;
3653 }
3654
3655 // Load hex file
3656
3657 i = 0;
3658 j = 0;
3659 load_at = 0;
3660 end_of_program = false;
3661 FILE *ofp;
3662 fopen_s(&ofp, "branch.txt", "a");
3663
3664 while (!end_of_program) {
3665 chr = buffer[i];
3666 switch (chr) {
3667 case '\0':
3668 end_of_program = true;
3669
3670 case ',':
3671 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
3672 load_at = address;
3673 }
3674 else if (sscanf(InputBuffer, "%x", &code) == 1) {
3675 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
3676 Memory[load_at] = (BYTE)code;
3677 fprintf(ofp, "%02X\n", (BYTE)code);
3678 }
3679 load_at++;
3680 }
3681 else {
3682 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
3683 }
3684 j = 0;
3685 break;
3686
3687 default:
3688 InputBuffer[j] = chr;
3689 j++;
3690 break;
3691 }
3692 i++;
3693 }
3694 fclose(ofp);
3695 // Emulate
3696
3697 if (load_at > 1) {
3698 emulate();
3699 // Send and store results
3700 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
3701 Memory[TEST_ADDRESS_1],
3702 Memory[TEST_ADDRESS_2],
3703 Memory[TEST_ADDRESS_3],
3704 Memory[TEST_ADDRESS_4],
3705 Memory[TEST_ADDRESS_5],
3706 Memory[TEST_ADDRESS_6],
3707 Memory[TEST_ADDRESS_7],
3708 Memory[TEST_ADDRESS_8],
3709 Memory[TEST_ADDRESS_9],
3710 Memory[TEST_ADDRESS_10],
3711 Memory[TEST_ADDRESS_11],
3712 Memory[TEST_ADDRESS_12]
3713 );
3714 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
3715 }
3716 }
3717 }
3718 }
3719}
3720
3721
3722
3723int _tmain(int argc, _TCHAR* argv[])
3724{
3725 char chr;
3726 char dummy;
3727
3728 printf("\n");
3729 printf("Microprocessor Emulator\n");
3730 printf("UWE Computer and Network Systems Assignment 1\n");
3731 printf("\n");
3732
3733 initialise_filenames();
3734
3735 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
3736
3737 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
3738 if (!sock) {
3739 // Creation failed!
3740 }
3741
3742 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
3743 server_addr.sin_family = AF_INET;
3744 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
3745 server_addr.sin_port = htons(PORT_SERVER);
3746
3747 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
3748 client_addr.sin_family = AF_INET;
3749 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
3750 client_addr.sin_port = htons(PORT_CLIENT);
3751
3752 chr = '\0';
3753 while ((chr != 'e') && (chr != 'E'))
3754 {
3755 printf("\n");
3756 printf("Please select option\n");
3757 printf("L - Load and run a hex file\n");
3758 printf("T - Have the server test and mark your emulator\n");
3759 printf("E - Exit\n");
3760 if (argc == 2) { building(argc, argv); exit(0); }
3761 printf("Enter option: ");
3762 chr = getchar();
3763 if (chr != 0x0A)
3764 {
3765 dummy = getchar(); // read in the <CR>
3766 }
3767 printf("\n");
3768
3769 switch (chr)
3770 {
3771 case 'L':
3772 case 'l':
3773 load_and_run(argc, argv);
3774 break;
3775
3776 case 'T':
3777 case 't':
3778 test_and_mark();
3779 break;
3780
3781 default:
3782 break;
3783 }
3784 }
3785
3786 closesocket(sock);
3787 WSACleanup();
3788
3789
3790 return 0;
3791}