· 5 years ago · Feb 25, 2020, 11:26 PM
1
2
3#include "stdafx.h"
4#include <winsock2.h>
5
6#pragma comment(lib, "wsock32.lib")
7
8
9#define STUDENT_NUMBER "17033624"
10
11#define IP_ADDRESS_SERVER "127.0.0.1"
12//#define IP_ADDRESS_SERVER "164.11.76.66"
13
14
15#define PORT_SERVER 0x1984 // We define a port that we are going to use.
16#define PORT_CLIENT 0x1985 // We define a port that we are going to use.
17
18#define WORD unsigned short
19#define DWORD unsigned long
20#define BYTE unsigned char
21
22#define MAX_FILENAME_SIZE 500
23#define MAX_BUFFER_SIZE 500
24
25SOCKADDR_IN server_addr;
26SOCKADDR_IN client_addr;
27
28SOCKET sock; // This is our socket, it is the handle to the IO address to read/write packets
29
30WSADATA data;
31
32char InputBuffer [MAX_BUFFER_SIZE];
33
34char hex_file [MAX_BUFFER_SIZE];
35char trc_file [MAX_BUFFER_SIZE];
36
37//////////////////////////
38// Registers //
39//////////////////////////
40
41#define FLAG_I 0x80
42#define FLAG_N 0x20
43#define FLAG_V 0x10
44#define FLAG_Z 0x08
45#define FLAG_C 0x01
46#define REGISTER_M 7
47#define REGISTER_A 6
48#define REGISTER_H 5
49#define REGISTER_L 4
50#define REGISTER_E 3
51#define REGISTER_D 2
52#define REGISTER_C 1
53#define REGISTER_B 0
54WORD IndexRegister;
55
56BYTE Registers[8];
57BYTE Flags;
58WORD ProgramCounter;
59WORD StackPointer;
60
61
62////////////
63// Memory //
64////////////
65
66#define MEMORY_SIZE 65536
67
68BYTE Memory[MEMORY_SIZE];
69
70#define TEST_ADDRESS_1 0x01FA
71#define TEST_ADDRESS_2 0x01FB
72#define TEST_ADDRESS_3 0x01FC
73#define TEST_ADDRESS_4 0x01FD
74#define TEST_ADDRESS_5 0x01FE
75#define TEST_ADDRESS_6 0x01FF
76#define TEST_ADDRESS_7 0x0200
77#define TEST_ADDRESS_8 0x0201
78#define TEST_ADDRESS_9 0x0202
79#define TEST_ADDRESS_10 0x0203
80#define TEST_ADDRESS_11 0x0204
81#define TEST_ADDRESS_12 0x0205
82
83
84///////////////////////
85// Control variables //
86///////////////////////
87
88bool memory_in_range = true;
89bool halt = false;
90
91
92///////////////////////
93// Disassembly table //
94///////////////////////
95
96char opcode_mneumonics[][14] =
97{
98"BRA rel ",
99"BCC rel ",
100"BCS rel ",
101"BNE rel ",
102"BEQ rel ",
103"BVC rel ",
104"BVS rel ",
105"BMI rel ",
106"BPL rel ",
107"BGE rel ",
108"BLE rel ",
109"BLS rel ",
110"BHI rel ",
111"ILLEGAL ",
112"RTN impl ",
113"ILLEGAL ",
114
115"ST abs ",
116"PSH ,A ",
117"POP A, ",
118"ILLEGAL ",
119"ILLEGAL ",
120"CLC impl ",
121"SEC impl ",
122"CLI impl ",
123"STI impl ",
124"SEV impl ",
125"CLV impl ",
126"DEX impl ",
127"INX impl ",
128"NOP impl ",
129"WAI impl ",
130"ILLEGAL ",
131
132"ST abs,X ",
133"PSH ,s ",
134"POP s, ",
135"ILLEGAL ",
136"ILLEGAL ",
137"ADI # ",
138"SBI # ",
139"CPI # ",
140"ANI # ",
141"XRI # ",
142"MVI #,B ",
143"MVI #,C ",
144"MVI #,D ",
145"MVI #,E ",
146"MVI #,L ",
147"MVI #,H ",
148
149"ILLEGAL ",
150"PSH ,B ",
151"POP B, ",
152"JPR abs ",
153"CCC abs ",
154"CCS abs ",
155"CNE abs ",
156"CEQ abs ",
157"CVC abs ",
158"CVS abs ",
159"CMI abs ",
160"CPL abs ",
161"CHI abs ",
162"CLE abs ",
163"ILLEGAL ",
164"ILLEGAL ",
165
166"ILLEGAL ",
167"PSH ,C ",
168"POP C, ",
169"TST abs ",
170"INC abs ",
171"DEC abs ",
172"RCR abs ",
173"RCL abs ",
174"SAL abs ",
175"ASR abs ",
176"NOT abs ",
177"ROL abs ",
178"ROR abs ",
179"ILLEGAL ",
180"LDX # ",
181"LODS # ",
182
183"STOX abs ",
184"PSH ,D ",
185"POP D, ",
186"TST abs,X ",
187"INC abs,X ",
188"DEC abs,X ",
189"RCR abs,X ",
190"RCL abs,X ",
191"SAL abs,X ",
192"ASR abs,X ",
193"NOT abs,X ",
194"ROL abs,X ",
195"ROR abs,X ",
196"ILLEGAL ",
197"LDX abs ",
198"LODS abs ",
199
200"STOX abs,X ",
201"PSH ,E ",
202"POP E, ",
203"TSTA A,A ",
204"INCA A,A ",
205"DECA A,A ",
206"RCRA A,A ",
207"RCLA A,A ",
208"SALA A,A ",
209"ASRA A,A ",
210"NOTA A,A ",
211"ROLA A,A ",
212"RORA A,A ",
213"ILLEGAL ",
214"LDX abs,X ",
215"LODS abs,X ",
216
217"ILLEGAL ",
218"PSH ,L ",
219"POP L, ",
220"ILLEGAL ",
221"TAS impl ",
222"TSA impl ",
223"ILLEGAL ",
224"ILLEGAL ",
225"MOVE A,A ",
226"MOVE B,A ",
227"MOVE C,A ",
228"MOVE D,A ",
229"MOVE E,A ",
230"MOVE L,A ",
231"MOVE H,A ",
232"MOVE M,A ",
233
234"ILLEGAL ",
235"PSH ,H ",
236"POP H, ",
237"ILLEGAL ",
238"ILLEGAL ",
239"SWI impl ",
240"RTI impl ",
241"ILLEGAL ",
242"MOVE A,B ",
243"MOVE B,B ",
244"MOVE C,B ",
245"MOVE D,B ",
246"MOVE E,B ",
247"MOVE L,B ",
248"MOVE H,B ",
249"MOVE M,B ",
250
251"ADC A,B ",
252"SBC A,B ",
253"CMP A,B ",
254"IOR A,B ",
255"AND A,B ",
256"XOR A,B ",
257"BT A,B ",
258"ILLEGAL ",
259"MOVE A,C ",
260"MOVE B,C ",
261"MOVE C,C ",
262"MOVE D,C ",
263"MOVE E,C ",
264"MOVE L,C ",
265"MOVE H,C ",
266"MOVE M,C ",
267
268"ADC A,C ",
269"SBC A,C ",
270"CMP A,C ",
271"IOR A,C ",
272"AND A,C ",
273"XOR A,C ",
274"BT A,C ",
275"ILLEGAL ",
276"MOVE A,D ",
277"MOVE B,D ",
278"MOVE C,D ",
279"MOVE D,D ",
280"MOVE E,D ",
281"MOVE L,D ",
282"MOVE H,D ",
283"MOVE M,D ",
284"ADC A,D ",
285"SBC A,D ",
286"CMP A,D ",
287"IOR A,D ",
288"AND A,D ",
289"XOR A,D ",
290"BT A,D ",
291"LD # ",
292"MOVE A,E ",
293"MOVE B,E ",
294"MOVE C,E ",
295"MOVE D,E ",
296"MOVE E,E ",
297"MOVE L,E ",
298"MOVE H,E ",
299"MOVE M,E ",
300
301"ADC A,E ",
302"SBC A,E ",
303"CMP A,E ",
304"IOR A,E ",
305"AND A,E ",
306"XOR A,E ",
307"BT A,E ",
308"LD abs ",
309"MOVE A,L ",
310"MOVE B,L ",
311"MOVE C,L ",
312"MOVE D,L ",
313"MOVE E,L ",
314"MOVE L,L ",
315"MOVE H,L ",
316"MOVE M,L ",
317
318"ADC A,L ",
319"SBC A,L ",
320"CMP A,L ",
321"IOR A,L ",
322"AND A,L ",
323"XOR A,L ",
324"BT A,L ",
325"LD abs,X ",
326"MOVE A,H ",
327"MOVE B,H ",
328"MOVE C,H ",
329"MOVE D,H ",
330"MOVE E,H ",
331"MOVE L,H ",
332"MOVE H,H ",
333"MOVE M,H ",
334
335"ADC A,H ",
336"SBC A,H ",
337"CMP A,H ",
338"IOR A,H ",
339"AND A,H ",
340"XOR A,H ",
341"BT A,H ",
342"ILLEGAL ",
343"MOVE A,M ",
344"MOVE B,M ",
345"MOVE C,M ",
346"MOVE D,M ",
347"MOVE E,M ",
348"MOVE L,M ",
349"MOVE H,M ",
350"MOVE -,- ",
351
352"ADC A,M ",
353"SBC A,M ",
354"CMP A,M ",
355"IOR A,M ",
356"AND A,M ",
357"XOR A,M ",
358"BT A,M ",
359"ILLEGAL ",
360"ILLEGAL ",
361"ILLEGAL ",
362"JMP abs ",
363"ILLEGAL ",
364"ILLEGAL ",
365"ILLEGAL ",
366"ILLEGAL ",
367"ILLEGAL ",
368
369};
370
371////////////////////////////////////////////////////////////////////////////////
372// Simulator/Emulator (Start) //
373////////////////////////////////////////////////////////////////////////////////
374BYTE fetch()
375{
376 BYTE byte = 0;
377
378 if ((ProgramCounter >= 0) && (ProgramCounter <= MEMORY_SIZE))
379 {
380 memory_in_range = true;
381 byte = Memory[ProgramCounter];
382 ProgramCounter++;
383 }
384 else
385 {
386 memory_in_range = false;
387 }
388 return byte;
389}
390void set_flag_v(BYTE in1, BYTE in2, BYTE out1)
391{
392 BYTE reg1in;
393 BYTE reg2in;
394 BYTE regOut;
395
396 reg1in = in1;
397 reg2in = in2;
398 regOut = out1;
399
400 if ((((reg1in & 0x80) == 0x80) && ((reg2in & 0x80) == 0x80) && ((regOut & 0x80) != 0x80)) //overflow
401 || (((reg1in & 0x80) != 0x80) && ((reg2in & 0x80) != 0x80) && ((regOut & 0x80) == 0x80))) //overflow
402 {
403 Flags = Flags | FLAG_V;
404 }
405 else
406 {
407 Flags = Flags & (0xFF - FLAG_V);
408 }
409}
410
411void set_flag_n(BYTE inReg) {
412 BYTE reg;
413 reg = inReg;
414 if ((reg & 0x80) != 0) // msbit set
415 {
416 Flags = Flags | FLAG_N;
417 }
418 else
419 {
420 Flags = Flags & (0xFF - FLAG_N);
421 }
422}
423
424void set_flag_z(BYTE inReg) {
425 BYTE reg;
426 reg = inReg;
427 if (reg == 0) // zero set
428 {
429 Flags = Flags | FLAG_Z;
430 }
431 else
432 {
433 Flags = Flags & (0xFF - FLAG_Z);
434 }
435}
436
437void Group_1(BYTE opcode){
438 BYTE LB = 0;
439 BYTE HB = 0;
440 BYTE temp_word;
441 BYTE saved_flags;
442 WORD address = 0;
443 WORD data = 0;
444 WORD offset = 0;
445
446 switch(opcode) {
447 case 0xB7: //LD Immidiate
448 data = fetch();
449 Registers[REGISTER_A] = data;
450 set_flag_n(Registers[REGISTER_A]);
451 set_flag_z(Registers[REGISTER_A]);
452 Flags = Flags & (0xFF - FLAG_C);
453 break;
454
455 case 0xC7: //LD impl
456 HB = fetch();
457 LB = fetch();
458 address += (WORD)((WORD)HB << 8) + LB;
459 if (address >= 0 && address < MEMORY_SIZE) {
460 Registers[REGISTER_A] = Memory[address];
461 }
462 set_flag_n(Registers[REGISTER_A]);
463 set_flag_z(Registers[REGISTER_A]);
464 Flags = Flags & (0xFF - FLAG_C);
465 break;
466
467 case 0xD7: //LD impl
468 address += IndexRegister;
469 HB = fetch();
470 LB = fetch();
471 address += (WORD)((WORD)HB << 8) + LB;
472 if (address >= 0 && address < MEMORY_SIZE) {
473 Registers[REGISTER_A] = Memory[address];
474 }
475 set_flag_n(Registers[REGISTER_A]);
476 set_flag_z(Registers[REGISTER_A]);
477 Flags = Flags & (0xFF - FLAG_C);
478 break;
479
480 case 0x10: //ST impl
481 HB = fetch();
482 LB = fetch();
483 address += (WORD)((WORD)HB << 8) + LB;
484 if (address >= 0 && address < MEMORY_SIZE) {
485 Memory[address] = Registers[REGISTER_A];
486 }
487 set_flag_n(Registers[REGISTER_A]);
488 set_flag_z(Registers[REGISTER_A]);
489 Flags = Flags & (0xFF - FLAG_C);
490 break;
491
492 case 0x20: //ST impl
493 address += IndexRegister;
494 HB = fetch(); LB = fetch();
495 address += (WORD)((WORD)HB << 8) + LB;
496 if (address >= 0 && address < MEMORY_SIZE) {
497 Memory[address] = Registers[REGISTER_A];
498 }
499 set_flag_n(Registers[REGISTER_A]);
500 set_flag_z(Registers[REGISTER_A]);
501 Flags = Flags & (0xFF - FLAG_C);
502 break;
503
504 /*in this case it would be better to use " Registers[Register_B] = fetch() "
505 as this would save memory and be more efficient than storing a variable called data */
506
507 case 0x2A: //MVI impl
508 data = fetch();
509 Registers[REGISTER_B] = data;
510 set_flag_n(Registers[REGISTER_B]);
511 set_flag_z(Registers[REGISTER_B]);
512 Flags = Flags & (0xFF - FLAG_C);
513 break;
514
515 case 0x2B: //MVI impl
516 data = fetch();
517 Registers[REGISTER_C] = data;
518 set_flag_n(Registers[REGISTER_C]);
519 set_flag_z(Registers[REGISTER_C]);
520 Flags = Flags & (0xFF - FLAG_C);
521 break;
522
523 case 0x2C: //MVI impl
524 data = fetch();
525 Registers[REGISTER_D] = data;
526 set_flag_n(Registers[REGISTER_D]);
527 set_flag_z(Registers[REGISTER_D]);
528 Flags = Flags & (0xFF - FLAG_C);
529 break;
530
531 case 0x2D: //MVI impl
532 data = fetch();
533 Registers[REGISTER_E] = data;
534 set_flag_n(Registers[REGISTER_E]);
535 set_flag_z(Registers[REGISTER_E]);
536 Flags = Flags & (0xFF - FLAG_C);
537 break;
538
539 case 0x2E: //MVI impl
540 data = fetch();
541 Registers[REGISTER_L] = data;
542 set_flag_n(Registers[REGISTER_L]);
543 set_flag_z(Registers[REGISTER_L]);
544 Flags = Flags & (0xFF - FLAG_C);
545 break;
546
547 case 0x2F: //MVI impl
548 data = fetch();
549 Registers[REGISTER_H] = data;
550 set_flag_n(Registers[REGISTER_H]);
551 set_flag_z(Registers[REGISTER_H]);
552 Flags = Flags & (0xFF - FLAG_C);
553 break;
554
555 case 0x74: //TAS impl
556 Flags = Registers[REGISTER_A];
557 break;
558
559 case 0x75: //TSA impl
560 Registers[REGISTER_A] = Flags;
561 break;
562
563 case 0x4F: //LODS impl
564 data = fetch();
565 StackPointer = data << 8;
566 StackPointer += fetch();
567 set_flag_n(StackPointer);
568 set_flag_z(StackPointer);
569 Flags = Flags & (0xFF - FLAG_C);
570 break;
571
572 case 0x5f: //LODS impl
573 HB = fetch();
574 LB = fetch(); //DONT WORK
575 address += (WORD)((WORD)HB << 8) + LB;
576 if (address >= 0 && address < MEMORY_SIZE - 1) {
577 StackPointer = (WORD)Memory[address] << 8;
578 StackPointer += Memory[address + 1];
579 }
580 set_flag_n(Memory[address]);
581 set_flag_z(Memory[address]);
582 Flags = Flags & (0xFF - FLAG_C);
583 break;
584
585 case 0x6F: //LODS impl
586 address += IndexRegister;
587 HB = fetch();
588 LB = fetch(); // DONT WORK
589 address += (WORD)((WORD)HB << 8) + LB;
590 if (address >= 0 && address < MEMORY_SIZE - 1) {
591 StackPointer = (WORD)Memory[address] << 8;
592 StackPointer += Memory[address + 1];
593 }
594 set_flag_n(Memory[address]);
595 set_flag_z(Memory[address]);
596 Flags = Flags & (0xFF - FLAG_C);
597 break;
598
599 case 0x50: //STOX impl ( abs )
600 HB = fetch();
601 LB = fetch();
602 address += (WORD)((WORD)HB << 8) + LB;
603 if (address >= 0 && address < MEMORY_SIZE) {
604 Memory[address] = IndexRegister;
605 }
606 set_flag_n(IndexRegister);
607 set_flag_z(IndexRegister);
608 Flags = Flags & (0xFF - FLAG_C);
609 break;
610
611 case 0x60: //STOX impl ( abs,X )
612 address += IndexRegister;
613 HB = fetch();
614 LB = fetch(); //DOESNT WORK
615 address += (WORD)((WORD)HB << 8) + LB;
616 if (address >= 0 && address < MEMORY_SIZE) {
617 Memory[address] = IndexRegister >> 8;
618 Memory[address + 1] = IndexRegister;
619 }
620 set_flag_n(IndexRegister);
621 set_flag_z(IndexRegister);
622 Flags = Flags & (0xFF - FLAG_C);
623 break;
624
625 case 0x4E: //LDX impl
626 data = fetch();
627 IndexRegister = fetch();
628 break;
629
630 case 0x5E: //LDX impl
631 HB = fetch();
632 LB = fetch();
633 address += (WORD)((WORD)HB << 8) + LB;
634 if (address >= 0 && address < MEMORY_SIZE) {
635 IndexRegister = Memory[address];
636 }
637 break;
638
639 case 0x6E: //LDX impl
640 address += IndexRegister;
641 HB = fetch();
642 LB = fetch();
643 address += (WORD)((WORD)HB << 8) + LB;
644 if (address >= 0 && address < MEMORY_SIZE) {
645 IndexRegister = Memory[address];
646 }
647 break;
648
649 // ADC FLAGS
650
651 case 0x90:
652 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
653 if ((Flags & FLAG_C) != 0) {
654 temp_word++;
655 }
656 if (temp_word >= 0x100) {
657 Flags = Flags | FLAG_C; // Set carry flag
658 }
659 else {
660 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
661 }
662 set_flag_n((BYTE)temp_word);
663 set_flag_z((BYTE)temp_word);
664 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_B], (BYTE)temp_word);
665 Registers[REGISTER_A] = (BYTE)temp_word;
666 break;
667
668 case 0xA0:
669
670 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
671 if ((Flags & FLAG_C) != 0) {
672 temp_word++;
673 }
674 if (temp_word >= 0x100) {
675 Flags = Flags | FLAG_C; // Set carry flag
676 }
677 else {
678 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
679 }
680 set_flag_n((BYTE)temp_word);
681 set_flag_z((BYTE)temp_word);
682 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_C], (BYTE)temp_word);
683 Registers[REGISTER_A] = (BYTE)temp_word;
684 break;
685
686 case 0xB0:
687
688 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_D];
689 if ((Flags & FLAG_C) != 0) {
690 temp_word++;
691 }
692 if (temp_word >= 0x100) {
693 Flags = Flags | FLAG_C; // Set carry flag
694 }
695 else {
696 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
697 }
698 set_flag_n((BYTE)temp_word);
699 set_flag_z((BYTE)temp_word);
700 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_D], (BYTE)temp_word);
701 Registers[REGISTER_A] = (BYTE)temp_word;
702 break;
703
704 case 0xC0:
705
706 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_E];
707 if ((Flags & FLAG_C) != 0) {
708 temp_word++;
709 }
710 if (temp_word >= 0x100) {
711 Flags = Flags | FLAG_C; // Set carry flag
712 }
713 else {
714 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
715 }
716 set_flag_n((BYTE)temp_word);
717 set_flag_z((BYTE)temp_word);
718 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_E], (BYTE)temp_word);
719 Registers[REGISTER_A] = (BYTE)temp_word;
720 break;
721
722 case 0xD0:
723
724 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
725 if ((Flags & FLAG_C) != 0) {
726 temp_word++;
727 }
728 if (temp_word >= 0x100) {
729 Flags = Flags | FLAG_C; // Set carry flag
730 }
731 else {
732 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
733 }
734 set_flag_n((BYTE)temp_word);
735 set_flag_z((BYTE)temp_word);
736 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_L], (BYTE)temp_word);
737 Registers[REGISTER_A] = (BYTE)temp_word;
738 break;
739
740 case 0xE0:
741
742 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
743 if ((Flags & FLAG_C) != 0) {
744 temp_word++;
745 }
746 if (temp_word >= 0x100) {
747 Flags = Flags | FLAG_C; // Set carry flag
748 }
749 else {
750 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
751 }
752 set_flag_n((BYTE)temp_word);
753 set_flag_z((BYTE)temp_word);
754 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_H], (BYTE)temp_word);
755 Registers[REGISTER_A] = (BYTE)temp_word;
756 break;
757
758 case 0xF0:
759
760 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_M];
761 if ((Flags & FLAG_C) != 0) {
762 temp_word++;
763 }
764 if (temp_word >= 0x100) {
765 Flags = Flags | FLAG_C; // Set carry flag
766 }
767 else {
768 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
769 }
770 set_flag_n((BYTE)temp_word);
771 set_flag_z((BYTE)temp_word);
772 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_M], (BYTE)temp_word);
773 Registers[REGISTER_A] = (BYTE)temp_word;
774 break;
775
776 // CMP FLAGS
777 case 0x92:
778
779 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
780 if ((Flags & FLAG_C) != 0) {
781 temp_word++;
782 }
783 if (temp_word >= 0x100) {
784 Flags = Flags | FLAG_C; // Set carry flag
785 }
786 else {
787 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
788 }
789 set_flag_n((BYTE)temp_word);
790 set_flag_z((BYTE)temp_word);
791 set_flag_v(REGISTER_A, -REGISTER_B, (BYTE)temp_word);
792 break;
793
794 case 0xA2:
795
796 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
797 if ((Flags & FLAG_C) != 0) {
798 temp_word++;
799 }
800 if (temp_word >= 0x100) {
801 Flags = Flags | FLAG_C; // Set carry flag
802 }
803 else {
804 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
805 }
806 set_flag_n((BYTE)temp_word);
807 set_flag_z((BYTE)temp_word);
808 set_flag_v(REGISTER_A, -REGISTER_C, (BYTE)temp_word);
809 break;
810
811 case 0xB2:
812 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
813 if ((Flags & FLAG_C) != 0) {
814 temp_word++;
815 }
816 if (temp_word >= 0x100) {
817 Flags = Flags | FLAG_C; // Set carry flag
818 }
819 else {
820 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
821 }
822 set_flag_n((BYTE)temp_word);
823 set_flag_z((BYTE)temp_word);
824 set_flag_v(REGISTER_A, -REGISTER_D, (BYTE)temp_word);
825 break;
826
827 case 0xC2:
828 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
829 if ((Flags & FLAG_C) != 0) {
830 temp_word++;
831 }
832 if (temp_word >= 0x100) {
833 Flags = Flags | FLAG_C; // Set carry flag
834 }
835 else {
836 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
837 }
838 set_flag_n((BYTE)temp_word);
839 set_flag_z((BYTE)temp_word);
840 set_flag_v(REGISTER_A, -REGISTER_E, (BYTE)temp_word);
841 break;
842
843 case 0xD2:
844 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
845 if ((Flags & FLAG_C) != 0) {
846 temp_word++;
847 }
848 if (temp_word >= 0x100) {
849 Flags = Flags | FLAG_C; // Set carry flag
850 }
851 else {
852 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
853 }
854 set_flag_n((BYTE)temp_word);
855 set_flag_z((BYTE)temp_word);
856 set_flag_v(REGISTER_A, -REGISTER_L, (BYTE)temp_word);
857 break;
858
859 case 0xE2:
860 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
861 if ((Flags & FLAG_C) != 0) {
862 temp_word++;
863 }
864 if (temp_word >= 0x100) {
865 Flags = Flags | FLAG_C; // Set carry flag
866 }
867 else {
868 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
869 }
870 set_flag_n((BYTE)temp_word);
871 set_flag_z((BYTE)temp_word);
872 set_flag_v(REGISTER_A, -REGISTER_H, (BYTE)temp_word);
873 break;
874
875 case 0xF2:
876 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
877 if ((Flags & FLAG_C) != 0) {
878 temp_word++;
879 }
880 if (temp_word >= 0x100) {
881 Flags = Flags | FLAG_C; // Set carry flag
882 }
883 else {
884 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
885 }
886 set_flag_n((BYTE)temp_word);
887 set_flag_z((BYTE)temp_word);
888 set_flag_v(REGISTER_A, -REGISTER_M, (BYTE)temp_word);
889 break;
890
891 // CLC FLAGS
892
893 case 0x15:
894
895 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
896 break;
897
898 // SEC FLAGS
899
900 case 0x16:
901
902 Flags = Flags | FLAG_C;
903 break;
904
905 // CLV FLAGS
906
907 case 0x1A:
908 Flags = Flags & (0xFF - FLAG_V);
909 break;
910 // CLI FLAGS
911
912 case 0x17:
913
914 Flags = Flags & (0xFF - FLAG_I);
915 break;
916
917 // STI FLAGS
918
919 case 0x18:
920 Flags = Flags | FLAG_I;
921 break;
922 // SEV FLAGS
923
924 case 0x19:
925 Flags = Flags | FLAG_V;
926 break;
927
928 case 0x11: // PSH
929 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
930 Memory[StackPointer] = Registers[REGISTER_A];
931 StackPointer--;
932 }
933 break;
934
935 case 0x21: // PSH
936 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
937 Memory[StackPointer] = Flags;
938 StackPointer--;
939 }
940 break;
941
942 case 0x31: // PSH
943 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
944 Memory[StackPointer] = Registers[REGISTER_B];
945 StackPointer--;
946 }
947 break;
948
949 case 0x41: // PSH
950 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
951 Memory[StackPointer] = Registers[REGISTER_C];
952 StackPointer--;
953 }
954 break;
955
956 case 0x51: // PSH
957 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
958 Memory[StackPointer] = Registers[REGISTER_D];
959 StackPointer--;
960 }
961 break;
962
963 case 0x61: // PSH
964 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
965 Memory[StackPointer] = Registers[REGISTER_E];
966 StackPointer--;
967 }
968 break;
969
970 case 0x71: // PSH
971 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
972 Memory[StackPointer] = Registers[REGISTER_L];
973 StackPointer--;
974 }
975 break;
976
977 case 0x81: // PSH
978 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
979 Memory[StackPointer] = Registers[REGISTER_H];
980 StackPointer--;
981 }
982 break;
983
984 case 0x12: // POP
985 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
986 StackPointer++;
987 Registers[REGISTER_A] = Memory[StackPointer];
988 }
989 break;
990
991 case 0x22: // POP
992 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
993 StackPointer++;
994 Flags = Memory[StackPointer];
995 }
996 break;
997
998 case 0x32: // POP
999 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1000 StackPointer++;
1001 Registers[REGISTER_B] = Memory[StackPointer];
1002 }
1003 break;
1004
1005 case 0x42: // POP
1006 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1007 StackPointer++;
1008 Registers[REGISTER_C] = Memory[StackPointer];
1009 }
1010 break;
1011
1012 case 0x52: // POP
1013 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1014 StackPointer++;
1015 Registers[REGISTER_D] = Memory[StackPointer];
1016 }
1017 break;
1018
1019 case 0x62: // POP
1020 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1021 StackPointer++;
1022 Registers[REGISTER_E] = Memory[StackPointer];
1023 }
1024 break;
1025
1026 case 0x72: // POP
1027 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1028 StackPointer++;
1029 Registers[REGISTER_L] = Memory[StackPointer];
1030 }
1031 break;
1032
1033 case 0x82: // POP
1034 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1035 StackPointer++;
1036 Registers[REGISTER_H] = Memory[StackPointer];
1037 }
1038 break;
1039
1040 case 0xFA: // JMP abs
1041 HB = fetch();
1042 LB = fetch();
1043 address = ((WORD)HB << 8) + (WORD)LB;
1044 ProgramCounter = address;
1045 break;
1046
1047 case 0x33: // JPR abs
1048 HB = fetch();
1049 LB = fetch();
1050 address = ((WORD)HB << 8) + (WORD)LB;
1051 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1052 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1053 StackPointer--;
1054 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1055 StackPointer--;
1056 }
1057 ProgramCounter = address;
1058 break;
1059
1060 case 0x0E: // RTN
1061 HB = fetch();
1062 LB = fetch();
1063 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
1064 StackPointer++;
1065 HB = Memory[StackPointer];
1066 StackPointer++;
1067 LB = Memory[StackPointer];
1068 }
1069 ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
1070 break;
1071
1072 case 0x00: // BRA implementation
1073 LB = fetch();
1074 offset = (WORD)LB;
1075 if((offset & 0x80) != 0) { // need to sign extend
1076 offset = offset + 0xFF00;
1077 }
1078 address = ProgramCounter + offset;
1079 ProgramCounter = address;
1080 break;
1081
1082 // ------------------------------------------------------
1083 // -------- BCC Branch On Carry Clear | No Flags -------- DOESNT WORK
1084 // ------------------------------------------------------
1085
1086 case 0x01:
1087 LB = fetch();
1088 if ((Flags & FLAG_C) == 0) {
1089 offset = (WORD)LB;
1090 if ((offset & 0x80) != 0) {
1091 offset = offset + 0xFF00;
1092 }
1093 address = ProgramCounter + offset;
1094 ProgramCounter = address;
1095 }
1096 break;
1097
1098 // ------------------------------------------------------
1099 // -------- BCS Branch On Carry Set | No Flags ---------- DOESNT WORK
1100 // ------------------------------------------------------
1101
1102 case 0x02:
1103 LB = fetch();
1104 if ((Flags & FLAG_C) == FLAG_C) {
1105 offset = (WORD)LB;
1106 if ((offset & 0x80) != 0) {
1107 offset = offset + 0xFF00;
1108 }
1109 address = ProgramCounter + offset;
1110 ProgramCounter = address;
1111 }
1112 break;
1113
1114 // ------------------------------------------------------
1115 // -------- BNE Branch On Result NOT Zero | No Flags --------
1116 // ------------------------------------------------------
1117
1118 case 0x03:
1119 LB = fetch();
1120 if ((Flags & FLAG_Z) == 0) {
1121 offset = (WORD)LB;
1122 if ((offset & 0x80) != 0) {
1123 offset = offset + 0xFF00;
1124 }
1125 address = ProgramCounter + offset;
1126 ProgramCounter = address;
1127 }
1128 break;
1129
1130 // ------------------------------------------------------
1131 // -------- BEQ Branch On Result == 0 | No Flags ----------
1132 // ------------------------------------------------------
1133
1134 case 0x04:
1135 LB = fetch();
1136 if ((Flags & FLAG_Z) == FLAG_Z) {
1137 offset = (WORD)LB;
1138 if ((offset & 0x80) != 0) {
1139 offset = offset + 0xFF00;
1140 }
1141 address = ProgramCounter + offset;
1142 ProgramCounter = address;
1143 }
1144 break;
1145
1146 // ------------------------------------------------------
1147 // -------- BVC Branch On overflow clear | No Flags ---------- DOESNT WORK
1148 // ------------------------------------------------------
1149
1150 case 0x05:
1151 LB = fetch();
1152 if ((Flags & FLAG_V) == 0) {
1153 offset = (WORD)LB;
1154 if ((offset & 0x80) != 0) {
1155 offset = offset + 0xFF00;
1156 }
1157 address = ProgramCounter + offset;
1158 ProgramCounter = address;
1159 }
1160 break;
1161
1162 // ------------------------------------------------------
1163 // -------- BVS Branch On overflow set | No Flags ---------- DOESNT WORK
1164 // ------------------------------------------------------
1165
1166 case 0x06:
1167 LB = fetch();
1168 if ((Flags & FLAG_V) == FLAG_V) {
1169 offset = (WORD)LB;
1170 if ((offset & 0x80) != 0) {
1171 offset = offset + 0xFF00;
1172 }
1173 address = ProgramCounter + offset;
1174 ProgramCounter = address;
1175 }
1176 break;
1177
1178 // ------------------------------------------------------
1179 // -------- BMI Branch On Negative Result | No Flags ----------
1180 // ------------------------------------------------------
1181
1182 case 0x07:
1183 LB = fetch();
1184 if (((Flags & FLAG_N) == FLAG_N) && ((Flags & FLAG_Z) == 0)) {
1185 offset = (WORD)LB;
1186 if ((offset & 0x80) != 0) {
1187 offset = offset + 0xFF00;
1188 }
1189 address = ProgramCounter + offset;
1190 ProgramCounter = address;
1191 }
1192 break;
1193
1194 // ------------------------------------------------------
1195 // -------- BPL Branch On Positive Result | No Flags ----------
1196 // ------------------------------------------------------
1197
1198 case 0x08:
1199 LB = fetch();
1200 if (((Flags & FLAG_N) == 0) && ((Flags & FLAG_Z) == 0)) {
1201 offset = (WORD)LB;
1202 if ((offset & 0x80) != 0) {
1203 offset = offset + 0xFF00;
1204 }
1205 address = ProgramCounter + offset;
1206 ProgramCounter = address;
1207 }
1208 break;
1209
1210 // ------------------------------------------------------
1211 // -------- BGE Branch On Result Less Than Or Equal To 0 | No Flags ---------- DOESNT WORK
1212 // ------------------------------------------------------
1213
1214 case 0x09:
1215 LB = fetch();
1216 if (((Flags & FLAG_N) == 0) ^ ((Flags & FLAG_V) == 0)) {
1217 offset = (WORD)LB;
1218 if ((offset & 0x80) != 0) {
1219 offset = offset + 0xFF00;
1220 }
1221 address = ProgramCounter + offset;
1222 ProgramCounter = address;
1223 }
1224 break;
1225
1226 // ------------------------------------------------------
1227 // -------- BLE Branch On Result Greater Than Or Equal To 0 | No Flags ---------- DOESNT WORK
1228 // ------------------------------------------------------
1229
1230 case 0x0A:
1231 LB = fetch();
1232 if ((((Flags & FLAG_Z) == FLAG_Z) | ((Flags & FLAG_N) == FLAG_N)) ^ ((Flags & FLAG_V) == FLAG_V)) {
1233 offset = (WORD)LB;
1234 if ((offset & 0x80) != 0) {
1235 offset = offset + 0xFF00;
1236 }
1237 address = ProgramCounter + offset;
1238 ProgramCounter = address;
1239 }
1240 break;
1241
1242
1243 // ------------------------------------------------------
1244 // -------- BLS Branch On Result Less Than Or Equal To 0 | No Flags ---------- DOESNT WORK
1245 // ------------------------------------------------------
1246
1247 case 0x0B:
1248 LB = fetch();
1249 if (((Flags & FLAG_N) == 0) ^ ((Flags & FLAG_Z) == FLAG_Z)) {
1250 offset = (WORD)LB;
1251 if ((offset & 0x80) != 0) {
1252 offset = offset + 0xFF00;
1253 }
1254 address = ProgramCounter + offset;
1255 ProgramCounter = address;
1256 }
1257 break;
1258
1259
1260 //------------------------BHI ------------------------ Dont work
1261
1262 case 0x0C:
1263 int CF, ZF, NF;
1264 LB = fetch();
1265 if ((Flags & FLAG_N) == FLAG_N) {
1266 CF = 0;
1267 }
1268
1269 else {
1270 CF = 1;
1271 }
1272
1273 if ((Flags & FLAG_Z) == FLAG_Z) {
1274 ZF = 0;
1275 }
1276
1277 else {
1278 ZF = 1;
1279 }
1280
1281 if ((CF | NF) == 0) {
1282 offset = (WORD)LB;
1283 if ((offset & 0x80) != 0) {
1284 offset = offset + 0xFF00;
1285 }
1286 address = ProgramCounter + offset;
1287
1288 ProgramCounter = address;
1289
1290 }
1291
1292 break;
1293
1294 //--------------------------CCC----------------------------
1295 case 0x34: //abs
1296
1297 HB = fetch();
1298 LB = fetch();
1299 if ((Flags & FLAG_C) == 0) // Overflow flag set
1300 {
1301 address += (WORD)((WORD)HB << 8) + LB;
1302 if (address >= 0 && address < MEMORY_SIZE)
1303 {
1304 // Push return address onto the stack
1305 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE))
1306 {
1307 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1308 StackPointer--;
1309 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1310 StackPointer--;
1311 }
1312 ProgramCounter = (WORD)address;
1313 }
1314 }
1315 break;
1316
1317
1318 //----------------------------CCS OPCODE----------------------- Dont work
1319 //Call on Carry set
1320
1321 case 0x35: //abs
1322
1323 HB = fetch();
1324 LB = fetch();
1325 if ((Flags & FLAG_C) == FLAG_C) // Overflow flag set
1326 {
1327 address += (WORD)((WORD)HB << 8) + LB;
1328 if (address >= 0 && address < MEMORY_SIZE)
1329 {
1330 // Push return address onto the stack
1331 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE))
1332 {
1333 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1334 StackPointer--;
1335 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1336 StackPointer--;
1337 }
1338 ProgramCounter = (WORD)address;
1339 }
1340 }
1341
1342 break;
1343
1344 //---------------------------------CNE OPCODE---------------------Dont work
1345 //Call on result not Zero
1346
1347 case 0x36: //abs
1348
1349 HB = fetch();
1350 LB = fetch();
1351 if ((Flags & FLAG_Z) == 0) // Overflow flag set
1352 {
1353 address += (WORD)((WORD)HB << 8) + LB;
1354 if (address >= 0 && address < MEMORY_SIZE)
1355 {
1356 // Push return address onto the stack
1357 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE))
1358 {
1359 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1360 StackPointer--;
1361 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1362 StackPointer--;
1363 }
1364 ProgramCounter = (WORD)address;
1365 }
1366 }
1367 break;
1368
1369 //---------------------------------CEQ OPCODE------------------------------ Dont work
1370 //Call on result equal to Zero
1371
1372 case 0x37: //abs
1373
1374 HB = fetch();
1375 LB = fetch();
1376 if ((Flags & FLAG_Z) == FLAG_Z) // Overflow flag set
1377 {
1378 address += (WORD)((WORD)HB << 8) + LB;
1379 if (address >= 0 && address < MEMORY_SIZE)
1380 {
1381 // Push return address onto the stack
1382 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE))
1383 {
1384 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1385 StackPointer--;
1386 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1387 StackPointer--;
1388 }
1389 ProgramCounter = (WORD)address;
1390 }
1391 }
1392 break;
1393
1394 //-----------------------CVC OPCODE-------------------------- Dont work
1395 //Call on overflow clear
1396
1397 case 0x38: //abs
1398
1399 HB = fetch();
1400 LB = fetch();
1401 if ((Flags & FLAG_V) == 0) // Overflow flag set
1402 {
1403 address += (WORD)((WORD)HB << 8) + LB;
1404 if (address >= 0 && address < MEMORY_SIZE)
1405 {
1406 // Push return address onto the stack
1407 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE))
1408 {
1409 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1410 StackPointer--;
1411 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1412 StackPointer--;
1413 }
1414 ProgramCounter = (WORD)address;
1415 }
1416 }
1417
1418 break;
1419
1420 //--------------------------------CVS OPCODE-----------------------------
1421 //Call on overflow set
1422
1423 case 0x39: //abs
1424
1425 HB = fetch();
1426 LB = fetch();
1427 if ((Flags & FLAG_V) == FLAG_V) // Overflow flag set
1428 {
1429 address += (WORD)((WORD)HB << 8) + LB;
1430 if (address >= 0 && address < MEMORY_SIZE)
1431 {
1432 // Push return address onto the stack
1433 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE))
1434 {
1435 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1436 StackPointer--;
1437 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1438 StackPointer--;
1439 }
1440 ProgramCounter = (WORD)address;
1441 }
1442 }
1443 break;
1444
1445 //------------------------CMI OPCODE-------------------- Dont work
1446 //Call on negative result
1447
1448 case 0x3A: //abs
1449
1450 HB = fetch();
1451 LB = fetch();
1452 if ((Flags & FLAG_N) == FLAG_N) // Overflow flag set
1453 {
1454 address += (WORD)((WORD)HB << 8) + LB;
1455 if (address >= 0 && address < MEMORY_SIZE)
1456 {
1457 // Push return address onto the stack
1458 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE))
1459 {
1460 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1461 StackPointer--;
1462 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1463 StackPointer--;
1464 }
1465 ProgramCounter = (WORD)address;
1466 }
1467 }
1468 break;
1469
1470 //---------------------CPL OPCODE--------------------- Dont work
1471 //Call on positive result
1472
1473 case 0x3B: //abs
1474 HB = fetch();
1475 LB = fetch();
1476 if ((Flags & FLAG_N) == 0) // Overflow flag set
1477 {
1478 address += (WORD)((WORD)HB << 8) + LB;
1479 if (address >= 0 && address < MEMORY_SIZE)
1480 {
1481 // Push return address onto the stack
1482 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE))
1483 {
1484 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1485 StackPointer--;
1486 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1487 StackPointer--;
1488 }
1489 ProgramCounter = (WORD)address;
1490 }
1491 }
1492 break;
1493
1494 //--------------------------CHI OPCODE ------------------------- Dont work
1495 //Call on result same or lower
1496
1497 case 0x3C: //abs
1498
1499 HB = fetch();
1500 LB = fetch();
1501 if ((Flags & FLAG_C | FLAG_Z) == 1) // Overflow flag set
1502 {
1503 address += (WORD)((WORD)HB << 8) + LB;
1504 if (address >= 0 && address < MEMORY_SIZE)
1505 {
1506 // Push return address onto the stack
1507 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE))
1508 {
1509 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1510 StackPointer--;
1511 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1512 StackPointer--;
1513 }
1514 ProgramCounter = (WORD)address;
1515 }
1516 }
1517 break;
1518
1519 //-----------------------CLE OPCODE--------------------- Dont work
1520 //Call on result higher
1521
1522 case 0x3D: //abs
1523
1524 HB = fetch();
1525 LB = fetch();
1526 if ((Flags & FLAG_C | FLAG_Z) == 0) // Overflow flag set
1527 {
1528 address += (WORD)((WORD)HB << 8) + LB;
1529 if (address >= 0 && address < MEMORY_SIZE)
1530 {
1531 // Push return address onto the stack
1532 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE))
1533 {
1534 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1535 StackPointer--;
1536 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1537 StackPointer--;
1538 }
1539 ProgramCounter = (WORD)address;
1540 }
1541 }
1542 break;
1543
1544
1545 // ----------------------------------------------------------------------------------
1546 // ---------------------------- INCA IMPLEMENTATION ---------------------------------
1547 // ----------------------------------------------------------------------------------
1548
1549 case 0x64:
1550 ++Registers[REGISTER_A];
1551 set_flag_n(Registers[REGISTER_A]);
1552 set_flag_z(Registers[REGISTER_A]);
1553 break;
1554
1555 // ----------------------------------------------------------------------------------
1556 // ---------------------------- INC IMPLEMENTATION ---------------------------------
1557 // ----------------------------------------------------------------------------------
1558
1559 case 0x44: //abs
1560 HB = fetch();
1561 LB = fetch();
1562 address += (WORD)((WORD)HB << 8) + LB;
1563 ++Memory[address];
1564 set_flag_n(Memory[address]);
1565 set_flag_z(Memory[address]);
1566 break;
1567
1568 case 0x54: //abs, X
1569 address += IndexRegister;
1570 HB = fetch();
1571 LB = fetch();
1572 address += (WORD)((WORD)HB << 8) + LB;
1573 ++Memory[address];
1574 set_flag_n(Memory[address]);
1575 set_flag_z(Memory[address]);
1576 break;
1577
1578 // ----------------------------------------------------------------------------------
1579 // ----------------------------- TST IMPLEMENTATION ---------------------------------
1580 // ----------------------------------------------------------------------------------
1581
1582 case 0x43:
1583 HB = fetch();
1584 LB = fetch();
1585 address += (WORD)((WORD)HB << 8) + LB;
1586 set_flag_n(Memory[address]);
1587 set_flag_z(Memory[address]);
1588 break;
1589
1590 case 0x53:
1591 HB = fetch();
1592 LB = fetch();
1593 address += (WORD)((WORD)HB << 8) + LB;
1594 set_flag_n(Memory[address]);
1595 set_flag_z(Memory[address]);
1596 break;
1597
1598 // -------------------------------RCLA ----------------------------------
1599
1600 case 0x67:
1601 saved_flags = Flags;
1602
1603 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
1604 Flags = Flags | FLAG_C;
1605 }
1606 else {
1607 Flags = Flags & (0xFF - FLAG_C);
1608 }
1609 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
1610 if ((saved_flags & FLAG_C) == FLAG_C) {
1611 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
1612 }
1613 set_flag_z(Registers[REGISTER_A]);
1614 set_flag_n(Registers[REGISTER_A]);
1615 break;
1616
1617 // ------------------------------ SALA ------------------------------------
1618
1619 case 0x68:
1620 if ((Registers[REGISTER_A] & 0X80) == 0X80) {
1621 Flags = Flags | FLAG_C;
1622 }
1623 else {
1624 Flags = Flags & (0xFF - FLAG_C);
1625 }
1626 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0XFE;
1627 set_flag_z(Registers[REGISTER_A]);
1628 set_flag_n(Registers[REGISTER_A]);
1629 break;
1630
1631
1632 case 0x1E: // WAI
1633 halt = true;
1634 break;
1635
1636
1637 case 0x1C: // INX ------------------------------------------------- DOESNT WORK
1638 ++IndexRegister;
1639 set_flag_z(IndexRegister);
1640 break;
1641
1642
1643 case 0x1B: // DEX ------------------------------------------ DOESNT WORK
1644 --IndexRegister;
1645 set_flag_z(IndexRegister);
1646 break;
1647
1648 case 0x94: // AND
1649 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_B];
1650 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1651 set_flag_n((BYTE)temp_word);
1652 set_flag_z((BYTE)temp_word);
1653 Flags = Flags & (0xFF - FLAG_V);
1654 Registers[REGISTER_A] = (BYTE)temp_word;
1655 break;
1656
1657 case 0xA4: // AND
1658 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_C];
1659 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1660 set_flag_n((BYTE)temp_word);
1661 set_flag_z((BYTE)temp_word);
1662 Flags = Flags & (0xFF - FLAG_V);
1663 Registers[REGISTER_A] = (BYTE)temp_word;
1664 break;
1665
1666 case 0xB4: // AND
1667 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_D];
1668 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1669 set_flag_n((BYTE)temp_word);
1670 set_flag_z((BYTE)temp_word);
1671 Flags = Flags & (0xFF - FLAG_V);
1672 Registers[REGISTER_A] = (BYTE)temp_word;
1673 break;
1674
1675 case 0xC4: // AND
1676 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_E];
1677 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1678 set_flag_n((BYTE)temp_word);
1679 set_flag_z((BYTE)temp_word);
1680 Flags = Flags & (0xFF - FLAG_V);
1681 Registers[REGISTER_A] = (BYTE)temp_word;
1682 break;
1683
1684 case 0xD4: // AND
1685 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_L];
1686 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1687 set_flag_n((BYTE)temp_word);
1688 set_flag_z((BYTE)temp_word);
1689 Flags = Flags & (0xFF - FLAG_V);
1690 Registers[REGISTER_A] = (BYTE)temp_word;
1691 break;
1692
1693 case 0xE4: // AND
1694 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_H];
1695 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1696 set_flag_n((BYTE)temp_word);
1697 set_flag_z((BYTE)temp_word);
1698 Flags = Flags & (0xFF - FLAG_V);
1699 Registers[REGISTER_A] = (BYTE)temp_word;
1700 break;
1701
1702 case 0xF4: // AND
1703 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_M];
1704 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1705 set_flag_n((BYTE)temp_word);
1706 set_flag_z((BYTE)temp_word);
1707 Flags = Flags & (0xFF - FLAG_V);
1708 Registers[REGISTER_A] = (BYTE)temp_word;
1709 break;
1710
1711 case 0x96: // BT
1712 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_B];
1713 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1714 set_flag_n((BYTE)temp_word);
1715 set_flag_z((BYTE)temp_word);
1716 Flags = Flags & (0xFF - FLAG_V);
1717 break;
1718
1719 case 0xA6: // BT
1720 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_C];
1721 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1722 set_flag_n((BYTE)temp_word);
1723 set_flag_z((BYTE)temp_word);
1724 Flags = Flags & (0xFF - FLAG_V);
1725 break;
1726
1727 case 0xB6: // BT
1728 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_D];
1729 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1730 set_flag_n((BYTE)temp_word);
1731 set_flag_z((BYTE)temp_word);
1732 Flags = Flags & (0xFF - FLAG_V);
1733 break;
1734
1735 case 0xC6: // BT
1736 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_E];
1737 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1738 set_flag_n((BYTE)temp_word);
1739 set_flag_z((BYTE)temp_word);
1740 Flags = Flags & (0xFF - FLAG_V);
1741 break;
1742
1743 case 0xD6: // BT
1744 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_L];
1745 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1746 set_flag_n((BYTE)temp_word);
1747 set_flag_z((BYTE)temp_word);
1748 Flags = Flags & (0xFF - FLAG_V);
1749 break;
1750
1751 case 0xE6: // BT
1752 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_H];
1753 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1754 set_flag_n((BYTE)temp_word);
1755 set_flag_z((BYTE)temp_word);
1756 Flags = Flags & (0xFF - FLAG_V);
1757 break;
1758
1759 case 0xF6: // BT
1760 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_M];
1761 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1762 set_flag_n((BYTE)temp_word);
1763 set_flag_z((BYTE)temp_word);
1764 Flags = Flags & (0xFF - FLAG_V);
1765 break;
1766
1767 ///////////////////////////////////////// SBC ////////////////////////////////////// ---------------------------- DOESNT WORK
1768
1769 case 0x91:
1770 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
1771 if ((Flags & FLAG_C) != 0) {
1772 temp_word++;
1773 }
1774 if (temp_word >= 0x100) {
1775 Flags = Flags | FLAG_C; // Set carry flag
1776 }
1777 else {
1778 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1779 }
1780 set_flag_n((BYTE)temp_word);
1781 set_flag_z((BYTE)temp_word);
1782 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_B], (BYTE)temp_word);
1783 Registers[REGISTER_A] = (BYTE)temp_word;
1784 break;
1785
1786 case 0xA1:
1787 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
1788 if ((Flags & FLAG_C) != 0) {
1789 temp_word++;
1790 }
1791 if (temp_word >= 0x100) {
1792 Flags = Flags | FLAG_C; // Set carry flag
1793 }
1794 else {
1795 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1796 }
1797 set_flag_n((BYTE)temp_word);
1798 set_flag_z((BYTE)temp_word);
1799 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_C], (BYTE)temp_word);
1800 Registers[REGISTER_A] = (BYTE)temp_word;
1801 break;
1802
1803 case 0xB1:
1804
1805 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
1806 if ((Flags & FLAG_C) != 0) {
1807 temp_word++;
1808 }
1809 if (temp_word >= 0x100) {
1810 Flags = Flags | FLAG_C; // Set carry flag
1811 }
1812 else {
1813 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1814 }
1815 set_flag_n((BYTE)temp_word);
1816 set_flag_z((BYTE)temp_word);
1817 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_D], (BYTE)temp_word);
1818 Registers[REGISTER_A] = (BYTE)temp_word;
1819 break;
1820
1821 case 0xC1:
1822
1823 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
1824 if ((Flags & FLAG_C) != 0) {
1825 temp_word++;
1826 }
1827 if (temp_word >= 0x100) {
1828 Flags = Flags | FLAG_C; // Set carry flag
1829 }
1830 else {
1831 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1832 }
1833 set_flag_n((BYTE)temp_word);
1834 set_flag_z((BYTE)temp_word);
1835 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_E], (BYTE)temp_word);
1836 Registers[REGISTER_A] = (BYTE)temp_word;
1837 break;
1838
1839 case 0xD1:
1840
1841 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1842 if ((Flags & FLAG_C) != 0) {
1843 temp_word++;
1844 }
1845 if (temp_word >= 0x100) {
1846 Flags = Flags | FLAG_C; // Set carry flag
1847 }
1848 else {
1849 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1850 }
1851 set_flag_n((BYTE)temp_word);
1852 set_flag_z((BYTE)temp_word);
1853 set_flag_v(REGISTER_A, REGISTER_L, (BYTE)temp_word);
1854 Registers[REGISTER_A] = (BYTE)temp_word;
1855 break;
1856
1857 case 0xE1:
1858
1859 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1860 if ((Flags & FLAG_C) != 0) {
1861 temp_word++;
1862 }
1863 if (temp_word >= 0x100) {
1864 Flags = Flags | FLAG_C; // Set carry flag
1865 }
1866 else {
1867 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1868 }
1869 set_flag_n((BYTE)temp_word);
1870 set_flag_z((BYTE)temp_word);
1871 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_H], (BYTE)temp_word);
1872 Registers[REGISTER_A] = (BYTE)temp_word;
1873 break;
1874
1875 case 0xF1:
1876
1877 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
1878 if ((Flags & FLAG_C) != 0) {
1879 temp_word++;
1880 }
1881 if (temp_word >= 0x100) {
1882 Flags = Flags | FLAG_C; // Set carry flag
1883 }
1884 else {
1885 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1886 }
1887 set_flag_n((BYTE)temp_word);
1888 set_flag_z((BYTE)temp_word);
1889 set_flag_v(Registers[REGISTER_A], Registers[REGISTER_M], (BYTE)temp_word);
1890 Registers[REGISTER_A] = (BYTE)temp_word;
1891 break;
1892
1893 //-------------------- SAL--------------------------------------
1894
1895 case 0x48:
1896 HB = fetch();
1897 LB = fetch();
1898 address +=(WORD)((WORD)HB << 8) + LB;
1899 if (address >= 0 && address < MEMORY_SIZE) {
1900 if ((Memory[address] & 0x80) == 0x80) {
1901 Flags = Flags | FLAG_C;
1902 }
1903 else {
1904 Flags = Flags & (0xFF - FLAG_C);
1905 }
1906 Memory[address] = (Memory[address] << 1) & 0xFE;
1907 }
1908 set_flag_n(Memory[address]);
1909 set_flag_z(Memory[address]);
1910 break;
1911
1912 case 0x58:
1913 address += IndexRegister;
1914 HB = fetch();
1915 LB = fetch();
1916 address += (WORD)((WORD)HB << 8) + LB;
1917 if (address >= 0 && address < MEMORY_SIZE) {
1918 if ((Memory[address] & 0x80) == 0x80) {
1919 Flags = Flags | FLAG_C;
1920 }
1921 else {
1922 Flags = Flags & (0xFF - FLAG_C);
1923 }
1924 Memory[address] = (Memory[address] << 1) & 0xFE;
1925 }
1926 set_flag_n(Memory[address]);
1927 set_flag_z(Memory[address]);
1928 break;
1929
1930 // ------------------------------ ASRA -------------------------------------
1931
1932 case 0x69:
1933 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
1934 Flags = Flags | FLAG_C;
1935 }
1936 else {
1937 Flags = Flags & (0xFF - FLAG_C);
1938 }
1939 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0X7F;
1940
1941 if ((Flags & FLAG_N) == FLAG_N) {
1942 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
1943 }
1944 set_flag_z(Registers[REGISTER_A]);
1945 set_flag_n(Registers[REGISTER_A]);
1946 break;
1947
1948 //--------------------------------------- ASR --------------------------------------- DOESNT WORK
1949
1950 case 0x49:
1951 HB = fetch();
1952 LB = fetch();
1953 address +=(WORD)((WORD)HB << 8) + LB;
1954 if (address >= 0 && address < MEMORY_SIZE) {
1955 if ((Memory[address] & 0x01) == 0x01) {
1956 Flags = Flags | FLAG_C;
1957 }
1958 else {
1959 Flags = Flags & (0xFF - FLAG_C);
1960 }
1961 Memory[address] = (Memory[address] >> 1) & 0x7F;
1962
1963 if ((Flags & FLAG_N) == FLAG_N) {
1964 Memory[address] = Memory[address] | 0x80;
1965 }
1966 }
1967 set_flag_z(Memory[address]);
1968 set_flag_n(Memory[address]);
1969 break;
1970
1971 case 0x59:
1972 address += IndexRegister;
1973 HB = fetch();
1974 LB = fetch();
1975 address +=(WORD)((WORD)HB << 8) + LB;
1976 if (address >= 0 && address < MEMORY_SIZE) {
1977 if ((Memory[address] & 0x01) == 0x01) {
1978 Flags = Flags | FLAG_C;
1979 }
1980 else {
1981 Flags = Flags & (0xFF - FLAG_C);
1982 }
1983 Memory[address] = (Memory[address] >> 1) & 0x7F;
1984 if ((Flags & FLAG_N) == FLAG_N) {
1985 Memory[address] = Memory[address] | 0x80;
1986 }
1987 }
1988 set_flag_z(Memory[address]);
1989 set_flag_n(Memory[address]);
1990 break;
1991
1992 // RCL
1993
1994 case 0x47:
1995
1996 saved_flags = Flags;
1997 HB = fetch();
1998 LB = fetch();
1999 address +=(WORD)((WORD)HB << 8) + LB;
2000 if (address >= 0 && address < MEMORY_SIZE) {
2001 if ((Memory[address] & 0x80) == 0x80) {
2002 Flags = Flags | FLAG_C;
2003 }
2004 else {
2005 Flags = Flags & (0xFF - FLAG_C);
2006 }
2007 Memory[address] = (Memory[address] << 1) & 0xFE;
2008
2009 if ((saved_flags & FLAG_C) == FLAG_C) {
2010 Memory[address] = Memory[address] | 0x01;
2011 }
2012 }
2013 set_flag_n(Memory[address]);
2014 set_flag_z(Memory[address]);
2015 break;
2016
2017 case 0x57:
2018 saved_flags = Flags;
2019 address += IndexRegister;
2020 HB = fetch();
2021 LB = fetch();
2022 address +=(WORD)((WORD)HB << 8) + LB;
2023 if (address >= 0 && address < MEMORY_SIZE) {
2024 if ((Memory[address] & 0x80) == 0x80) {
2025 Flags = Flags | FLAG_C;
2026 }
2027 else {
2028 Flags = Flags & (0xFF - FLAG_C);
2029 }
2030 Memory[address] = (Memory[address] << 1) & 0xFE;
2031
2032 if ((saved_flags & FLAG_C) == FLAG_C) {
2033 Memory[address] = Memory[address] | 0x01;
2034 }
2035
2036 }
2037 set_flag_n(Memory[address]);
2038 set_flag_z(Memory[address]);
2039 break;
2040
2041 // RCR
2042
2043 case 0x46:
2044
2045 saved_flags = Flags;
2046 HB = fetch();
2047 LB = fetch();
2048 address +=(WORD)((WORD)HB << 8) + LB;
2049 if (address >= 0 && address < MEMORY_SIZE) {
2050 if ((Memory[address] & 0x80) == 0x80) {
2051 Flags = Flags | FLAG_C;
2052 }
2053 else {
2054 Flags = Flags & (0xFF - FLAG_C);
2055 }
2056 Memory[address] = (Memory[address] << 1) & 0x7F;
2057
2058 if ((saved_flags & FLAG_C) == FLAG_C) {
2059 Memory[address] = Memory[address] | 0x01;
2060 }
2061 }
2062 set_flag_n(Memory[address]);
2063 set_flag_z(Memory[address]);
2064 break;
2065
2066 case 0x56:
2067 saved_flags = Flags;
2068 address += IndexRegister;
2069 HB = fetch();
2070 LB = fetch();
2071 address +=(WORD)((WORD)HB << 8) + LB;
2072 if (address >= 0 && address < MEMORY_SIZE) {
2073 if ((Memory[address] & 0x01) == 0x01) {
2074 Flags = Flags | FLAG_C;
2075 }
2076 else {
2077 Flags = Flags & (0xFF - FLAG_C);
2078 }
2079 Memory[address] = (Memory[address] << 1) & 0x7F;
2080
2081 if ((saved_flags & FLAG_C) == FLAG_C) {
2082 Memory[address] = Memory[address] | 0x01;
2083 }
2084
2085 }
2086 set_flag_n(Memory[address]);
2087 set_flag_z(Memory[address]);
2088 break;
2089
2090 // NOT
2091
2092 case 0x4A:
2093 HB = fetch();
2094 LB = fetch();
2095 address += (WORD)((WORD)HB << 8) + LB;
2096 if (address >= 0 && address < MEMORY_SIZE) {
2097 Memory[address] = ~Memory[address];
2098 }
2099 set_flag_n(Memory[address]);
2100 set_flag_z(Memory[address]);
2101 Flags = Flags | FLAG_C;
2102 break;
2103
2104 case 0x5A:
2105 address += IndexRegister;
2106 HB = fetch();
2107 LB = fetch();
2108 address +=(WORD)((WORD)HB << 8) + LB;
2109 if (address >= 0 && address < MEMORY_SIZE) {
2110 Memory[address] = ~Memory[address];
2111 }
2112 set_flag_n(Memory[address]);
2113 set_flag_z(Memory[address]);
2114 Flags = Flags | FLAG_C;
2115 break;
2116
2117 //---------------------------NOTA CASE----------------------
2118 //Negate Memory or Accumulator
2119
2120 case 0x6A: // Need an XOR offset of OxFF
2121 Registers[REGISTER_A] = ~Registers[REGISTER_A];
2122 set_flag_n(Registers[REGISTER_A]);
2123 set_flag_z(Registers[REGISTER_A]);
2124 Flags = Flags & (0xFF - FLAG_C);
2125 break;
2126
2127 //-----------------------IOR --------------------
2128 //Register bitwise inclusive or with Accumulator
2129
2130 case 0x93:
2131 Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_B];
2132 set_flag_n(Registers[REGISTER_A]);
2133 set_flag_z(Registers[REGISTER_A]);
2134 break;
2135
2136 case 0xA3:
2137 Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_C];
2138 set_flag_n(Registers[REGISTER_A]);
2139 set_flag_z(Registers[REGISTER_A]);
2140 break;
2141
2142 case 0xB3:
2143 Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_D];
2144 set_flag_n(Registers[REGISTER_A]);
2145 set_flag_z(Registers[REGISTER_A]);
2146 break;
2147
2148 case 0xC3:
2149 Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_E];
2150 set_flag_n(Registers[REGISTER_A]);
2151 set_flag_z(Registers[REGISTER_A]);
2152 break;
2153
2154 case 0xD3:
2155 Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_L];
2156 set_flag_n(Registers[REGISTER_A]);
2157 set_flag_z(Registers[REGISTER_A]);
2158 break;
2159
2160 case 0xE3:
2161 Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_H];
2162 set_flag_n(Registers[REGISTER_A]);
2163 set_flag_z(Registers[REGISTER_A]);
2164 break;
2165
2166 case 0xF3:
2167 Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_M];
2168 set_flag_n(Registers[REGISTER_A]);
2169 set_flag_z(Registers[REGISTER_A]);
2170 break;
2171
2172 //----------------------------XOR CASE--------------------------------
2173 //Register bitwise exclusive OR with Accumulator
2174
2175 case 0x95:
2176 Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_B];
2177 set_flag_n(Registers[REGISTER_A]);
2178 set_flag_z(Registers[REGISTER_A]);
2179 break;
2180
2181 case 0xA5:
2182 Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_C];
2183 set_flag_n(Registers[REGISTER_A]);
2184 set_flag_z(Registers[REGISTER_A]);
2185 break;
2186
2187 case 0xB5:
2188 Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_D];
2189 set_flag_n(Registers[REGISTER_A]);
2190 set_flag_z(Registers[REGISTER_A]);
2191 break;
2192
2193 case 0xC5:
2194 Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_E];
2195 set_flag_n(Registers[REGISTER_A]);
2196 set_flag_z(Registers[REGISTER_A]);
2197 break;
2198
2199 case 0xD5:
2200 Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_L];
2201 set_flag_n(Registers[REGISTER_A]);
2202 set_flag_z(Registers[REGISTER_A]);
2203 break;
2204
2205 case 0xE5:
2206 Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_H];
2207 set_flag_n(Registers[REGISTER_A]);
2208 set_flag_z(Registers[REGISTER_A]);
2209 break;
2210
2211 case 0xF5:
2212 Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_M];
2213 set_flag_n(Registers[REGISTER_A]);
2214 set_flag_z(Registers[REGISTER_A]);
2215 break;
2216
2217 //--------------------------DEC CASE---------------------
2218 //Decrement memory or Accumulator
2219
2220 case 0x45: //abs
2221 HB = fetch();
2222 LB = fetch();
2223 address += (WORD)((WORD)HB << 8) + LB;
2224 if (address >= 0 && address < MEMORY_SIZE) {
2225 Registers[REGISTER_A] = Memory[address];
2226 }
2227 --Registers[REGISTER_A];
2228 set_flag_n(Registers[REGISTER_A]);
2229 set_flag_z(Registers[REGISTER_A]);
2230 break;
2231
2232 case 0x55: //abs, X
2233 HB = fetch();
2234 LB = fetch();
2235 address += (WORD)((WORD)HB << 8) + LB;
2236 if (address >= 0 && address < MEMORY_SIZE) {
2237 Registers[REGISTER_A] = Memory[address];
2238 }
2239 --Registers[REGISTER_A];
2240 set_flag_n(Registers[REGISTER_A]);
2241 set_flag_z(Registers[REGISTER_A]);
2242 break;
2243
2244 }
2245}
2246
2247void Group_2_Move(BYTE opcode){
2248 BYTE destination = opcode & 0x0F;
2249 BYTE source = opcode >> 4;
2250 WORD address;
2251 int destReg, sourceReg;
2252
2253
2254 switch(destination) {
2255 case 0x08:
2256 destReg = REGISTER_A;
2257 break;
2258
2259 case 0x09:
2260 destReg = REGISTER_B;
2261 break;
2262
2263 case 0x0A:
2264 destReg = REGISTER_C;
2265 break;
2266
2267 case 0x0B:
2268 destReg = REGISTER_D;
2269 break;
2270
2271 case 0x0C:
2272 destReg = REGISTER_E;
2273 break;
2274
2275 case 0x0D:
2276 destReg = REGISTER_L;
2277 break;
2278
2279 case 0x0E:
2280 destReg = REGISTER_H;
2281 break;
2282
2283 case 0x0F:
2284 destReg = REGISTER_M;
2285 break;
2286
2287 }
2288
2289 switch (source) {
2290 case 0x07:
2291 sourceReg = REGISTER_A;
2292 break;
2293
2294 case 0x08:
2295 sourceReg = REGISTER_B;
2296 break;
2297
2298 case 0x09:
2299 sourceReg = REGISTER_C;
2300 break;
2301
2302 case 0x0A:
2303 sourceReg = REGISTER_D;
2304 break;
2305
2306 case 0x0B:
2307 sourceReg = REGISTER_E;
2308 break;
2309
2310 case 0x0C:
2311 sourceReg = REGISTER_L;
2312 break;
2313
2314 case 0x0D:
2315 sourceReg = REGISTER_H;
2316 break;
2317
2318 case 0x0E:
2319 sourceReg = REGISTER_M;
2320 break;
2321 }
2322
2323 if (sourceReg == REGISTER_M)
2324 {
2325 address = (WORD)Registers[REGISTER_H] << 8 + (WORD)Registers[REGISTER_L];
2326 Registers[REGISTER_M] = Memory[address];
2327 }
2328
2329 Registers[destReg] = Registers[sourceReg];
2330
2331 if (destReg == REGISTER_M)
2332 {
2333 address = (WORD)Registers[REGISTER_H] << 8 + (WORD)Registers[REGISTER_L];
2334 Memory[address] = Registers[REGISTER_M];
2335 }
2336}
2337
2338void execute(BYTE opcode)
2339{
2340 if (((opcode >= 0x78) && (opcode <= 0x7F))
2341 || ((opcode >= 0x88) && (opcode <= 0x8F))
2342 || ((opcode >= 0x98) && (opcode <= 0x9F))
2343 || ((opcode >= 0xA8) && (opcode <= 0xAF))
2344 || ((opcode >= 0xB8) && (opcode <= 0xBF))
2345 || ((opcode >= 0xC8) && (opcode <= 0xCF))
2346 || ((opcode >= 0xD8) && (opcode <= 0xDF))
2347 || ((opcode >= 0xE8) && (opcode <= 0xEF)))
2348 {
2349 Group_2_Move(opcode);
2350 }
2351 else
2352 {
2353 Group_1(opcode);
2354 }
2355}
2356
2357void emulate()
2358{
2359 BYTE opcode;
2360
2361 ProgramCounter = 0;
2362 halt = false;
2363 memory_in_range = true;
2364
2365 int loop = 0;
2366 printf(" A B C D E L H X SP\n");
2367
2368 while ((!halt) && (memory_in_range)) {
2369 printf("%04X ", ProgramCounter); // Print current address
2370 opcode = fetch();
2371 execute(opcode);
2372
2373 loop++;
2374 if (loop > 200) {
2375 halt = true;
2376 }
2377
2378 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
2379
2380 printf("%02X ", Registers[REGISTER_A]);
2381 printf("%02X ", Registers[REGISTER_B]);
2382 printf("%02X ", Registers[REGISTER_C]);
2383 printf("%02X ", Registers[REGISTER_D]);
2384 printf("%02X ", Registers[REGISTER_E]);
2385 printf("%02X ", Registers[REGISTER_L]);
2386 printf("%02X ", Registers[REGISTER_H]);
2387 printf("%04X ", IndexRegister);
2388 printf("%04X ", StackPointer); // Print Stack Pointer
2389
2390 if ((Flags & FLAG_I) == FLAG_I)
2391 {
2392 printf("I=1 ");
2393 }
2394 else
2395 {
2396 printf("I=0 ");
2397 }
2398 if ((Flags & FLAG_N) == FLAG_N)
2399 {
2400 printf("N=1 ");
2401 }
2402 else
2403 {
2404 printf("N=0 ");
2405 }
2406 if ((Flags & FLAG_V) == FLAG_V)
2407 {
2408 printf("V=1 ");
2409 }
2410 else
2411 {
2412 printf("V=0 ");
2413 }
2414 if ((Flags & FLAG_Z) == FLAG_Z)
2415 {
2416 printf("Z=1 ");
2417 }
2418 else
2419 {
2420 printf("Z=0 ");
2421 }
2422 if ((Flags & FLAG_C) == FLAG_C)
2423 {
2424 printf("C=1 ");
2425 }
2426 else
2427 {
2428 printf("C=0 ");
2429 }
2430
2431 printf("\n"); // New line
2432 }
2433
2434 printf("\n"); // New line
2435}
2436
2437
2438////////////////////////////////////////////////////////////////////////////////
2439// Simulator/Emulator (End) //
2440////////////////////////////////////////////////////////////////////////////////
2441
2442
2443void initialise_filenames() {
2444 int i;
2445
2446 for (i=0; i<MAX_FILENAME_SIZE; i++) {
2447 hex_file [i] = '\0';
2448 trc_file [i] = '\0';
2449 }
2450}
2451
2452
2453
2454
2455int find_dot_position(char *filename) {
2456 int dot_position;
2457 int i;
2458 char chr;
2459
2460 dot_position = 0;
2461 i = 0;
2462 chr = filename[i];
2463
2464 while (chr != '\0') {
2465 if (chr == '.') {
2466 dot_position = i;
2467 }
2468 i++;
2469 chr = filename[i];
2470 }
2471
2472 return (dot_position);
2473}
2474
2475
2476int find_end_position(char *filename) {
2477 int end_position;
2478 int i;
2479 char chr;
2480
2481 end_position = 0;
2482 i = 0;
2483 chr = filename[i];
2484
2485 while (chr != '\0') {
2486 end_position = i;
2487 i++;
2488 chr = filename[i];
2489 }
2490
2491 return (end_position);
2492}
2493
2494
2495bool file_exists(char *filename) {
2496 bool exists;
2497 FILE *ifp;
2498
2499 exists = false;
2500
2501 if ( ( ifp = fopen( filename, "r" ) ) != NULL ) {
2502 exists = true;
2503
2504 fclose(ifp);
2505 }
2506
2507 return (exists);
2508}
2509
2510
2511
2512void create_file(char *filename) {
2513 FILE *ofp;
2514
2515 if ( ( ofp = fopen( filename, "w" ) ) != NULL ) {
2516 fclose(ofp);
2517 }
2518}
2519
2520
2521
2522bool getline(FILE *fp, char *buffer) {
2523 bool rc;
2524 bool collect;
2525 char c;
2526 int i;
2527
2528 rc = false;
2529 collect = true;
2530
2531 i = 0;
2532 while (collect) {
2533 c = getc(fp);
2534
2535 switch (c) {
2536 case EOF:
2537 if (i > 0) {
2538 rc = true;
2539 }
2540 collect = false;
2541 break;
2542
2543 case '\n':
2544 if (i > 0) {
2545 rc = true;
2546 collect = false;
2547 buffer[i] = '\0';
2548 }
2549 break;
2550
2551 default:
2552 buffer[i] = c;
2553 i++;
2554 break;
2555 }
2556 }
2557
2558 return (rc);
2559}
2560
2561
2562
2563
2564
2565
2566void load_and_run(int args,_TCHAR** argv) {
2567 char chr;
2568 int ln;
2569 int dot_position;
2570 int end_position;
2571 long i;
2572 FILE *ifp;
2573 long address;
2574 long load_at;
2575 int code;
2576
2577 // Prompt for the .hex file
2578
2579 printf("\n");
2580 printf("Enter the hex filename (.hex): ");
2581
2582 if(args == 2){
2583 ln = 0;
2584 chr = argv[1][ln];
2585 while (chr != '\0')
2586 {
2587 if (ln < MAX_FILENAME_SIZE)
2588 {
2589 hex_file [ln] = chr;
2590 trc_file [ln] = chr;
2591 ln++;
2592 }
2593 chr = argv[1][ln];
2594 }
2595 } else {
2596 ln = 0;
2597 chr = '\0';
2598 while (chr != '\n') {
2599 chr = getchar();
2600
2601 switch(chr) {
2602 case '\n':
2603 break;
2604 default:
2605 if (ln < MAX_FILENAME_SIZE) {
2606 hex_file [ln] = chr;
2607 trc_file [ln] = chr;
2608 ln++;
2609 }
2610 break;
2611 }
2612 }
2613
2614 }
2615 // Tidy up the file names
2616
2617 dot_position = find_dot_position(hex_file);
2618 if (dot_position == 0) {
2619 end_position = find_end_position(hex_file);
2620
2621 hex_file[end_position + 1] = '.';
2622 hex_file[end_position + 2] = 'h';
2623 hex_file[end_position + 3] = 'e';
2624 hex_file[end_position + 4] = 'x';
2625 hex_file[end_position + 5] = '\0';
2626 } else {
2627 hex_file[dot_position + 0] = '.';
2628 hex_file[dot_position + 1] = 'h';
2629 hex_file[dot_position + 2] = 'e';
2630 hex_file[dot_position + 3] = 'x';
2631 hex_file[dot_position + 4] = '\0';
2632 }
2633
2634 dot_position = find_dot_position(trc_file);
2635 if (dot_position == 0) {
2636 end_position = find_end_position(trc_file);
2637
2638 trc_file[end_position + 1] = '.';
2639 trc_file[end_position + 2] = 't';
2640 trc_file[end_position + 3] = 'r';
2641 trc_file[end_position + 4] = 'c';
2642 trc_file[end_position + 5] = '\0';
2643 } else {
2644 trc_file[dot_position + 0] = '.';
2645 trc_file[dot_position + 1] = 't';
2646 trc_file[dot_position + 2] = 'r';
2647 trc_file[dot_position + 3] = 'c';
2648 trc_file[dot_position + 4] = '\0';
2649 }
2650
2651 if (file_exists(hex_file)) {
2652 // Clear Registers and Memory
2653
2654 Registers[REGISTER_A] = 0;
2655 Registers[REGISTER_B] = 0;
2656 Registers[REGISTER_C] = 0;
2657 Registers[REGISTER_D] = 0;
2658 Registers[REGISTER_E] = 0;
2659 Registers[REGISTER_L] = 0;
2660 Registers[REGISTER_H] = 0;
2661 IndexRegister = 0;
2662 Flags = 0;
2663 ProgramCounter = 0;
2664 StackPointer = 0;
2665
2666 for (i=0; i<MEMORY_SIZE; i++) {
2667 Memory[i] = 0x00;
2668 }
2669
2670 // Load hex file
2671
2672 if ( ( ifp = fopen( hex_file, "r" ) ) != NULL ) {
2673 printf("Loading file...\n\n");
2674
2675 load_at = 0;
2676
2677 while (getline(ifp, InputBuffer)) {
2678 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
2679 load_at = address;
2680 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
2681 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
2682 Memory[load_at] = (BYTE)code;
2683 }
2684 load_at++;
2685 } else {
2686 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
2687 }
2688 }
2689
2690 fclose(ifp);
2691 }
2692
2693 // Emulate
2694
2695 emulate();
2696 } else {
2697 printf("\n");
2698 printf("ERROR> Input file %s does not exist!\n", hex_file);
2699 printf("\n");
2700 }
2701}
2702
2703void building(int args,_TCHAR** argv){
2704 char buffer[1024];
2705 load_and_run(args,argv);
2706 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",
2707 Memory[TEST_ADDRESS_1],
2708 Memory[TEST_ADDRESS_2],
2709 Memory[TEST_ADDRESS_3],
2710 Memory[TEST_ADDRESS_4],
2711 Memory[TEST_ADDRESS_5],
2712 Memory[TEST_ADDRESS_6],
2713 Memory[TEST_ADDRESS_7],
2714 Memory[TEST_ADDRESS_8],
2715 Memory[TEST_ADDRESS_9],
2716 Memory[TEST_ADDRESS_10],
2717 Memory[TEST_ADDRESS_11],
2718 Memory[TEST_ADDRESS_12]
2719 );
2720 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2721}
2722
2723
2724
2725void test_and_mark() {
2726 char buffer[1024];
2727 bool testing_complete;
2728 int len = sizeof(SOCKADDR);
2729 char chr;
2730 int i;
2731 int j;
2732 bool end_of_program;
2733 long address;
2734 long load_at;
2735 int code;
2736 int mark;
2737 int passed;
2738
2739 printf("\n");
2740 printf("Automatic Testing and Marking\n");
2741 printf("\n");
2742
2743 testing_complete = false;
2744
2745 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
2746 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2747
2748 while (!testing_complete) {
2749 memset(buffer, '\0', sizeof(buffer));
2750
2751 if (recvfrom(sock, buffer, sizeof(buffer)-1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
2752 printf("Incoming Data: %s \n", buffer);
2753
2754 //if (strcmp(buffer, "Testing complete") == 1)
2755 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
2756 testing_complete = true;
2757 printf("Current mark = %d\n", mark);
2758
2759 }else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
2760 //testing_complete = true;
2761 printf("Passed = %d\n", passed);
2762
2763 } else if (strcmp(buffer, "Error") == 0) {
2764 printf("ERROR> Testing abnormally terminated\n");
2765 testing_complete = true;
2766 } else {
2767 // Clear Registers and Memory
2768
2769 Registers[REGISTER_A] = 0;
2770 Registers[REGISTER_B] = 0;
2771 Registers[REGISTER_C] = 0;
2772 Registers[REGISTER_D] = 0;
2773 Registers[REGISTER_E] = 0;
2774 Registers[REGISTER_L] = 0;
2775 Registers[REGISTER_H] = 0;
2776 IndexRegister = 0;
2777 Flags = 0;
2778 ProgramCounter = 0;
2779 StackPointer = 0;
2780 for (i=0; i<MEMORY_SIZE; i++) {
2781 Memory[i] = 0;
2782 }
2783
2784 // Load hex file
2785
2786 i = 0;
2787 j = 0;
2788 load_at = 0;
2789 end_of_program = false;
2790 FILE *ofp;
2791 fopen_s(&ofp ,"branch.txt", "a");
2792
2793 while (!end_of_program) {
2794 chr = buffer[i];
2795 switch (chr) {
2796 case '\0':
2797 end_of_program = true;
2798
2799 case ',':
2800 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
2801 load_at = address;
2802 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
2803 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
2804 Memory[load_at] = (BYTE)code;
2805 fprintf(ofp, "%02X\n", (BYTE)code);
2806 }
2807 load_at++;
2808 } else {
2809 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
2810 }
2811 j = 0;
2812 break;
2813
2814 default:
2815 InputBuffer[j] = chr;
2816 j++;
2817 break;
2818 }
2819 i++;
2820 }
2821 fclose(ofp);
2822 // Emulate
2823
2824 if (load_at > 1) {
2825 emulate();
2826 // Send and store results
2827 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
2828 Memory[TEST_ADDRESS_1],
2829 Memory[TEST_ADDRESS_2],
2830 Memory[TEST_ADDRESS_3],
2831 Memory[TEST_ADDRESS_4],
2832 Memory[TEST_ADDRESS_5],
2833 Memory[TEST_ADDRESS_6],
2834 Memory[TEST_ADDRESS_7],
2835 Memory[TEST_ADDRESS_8],
2836 Memory[TEST_ADDRESS_9],
2837 Memory[TEST_ADDRESS_10],
2838 Memory[TEST_ADDRESS_11],
2839 Memory[TEST_ADDRESS_12]
2840 );
2841 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2842 }
2843 }
2844 }
2845 }
2846}
2847
2848
2849
2850int _tmain(int argc, _TCHAR* argv[])
2851{
2852 char chr;
2853 char dummy;
2854
2855 printf("\n");
2856 printf("Microprocessor Emulator\n");
2857 printf("UWE Computer and Network Systems Assignment 1\n");
2858 printf("\n");
2859
2860 initialise_filenames();
2861
2862 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
2863
2864 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
2865 if (!sock) {
2866 // Creation failed!
2867 }
2868
2869 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
2870 server_addr.sin_family = AF_INET;
2871 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
2872 server_addr.sin_port = htons(PORT_SERVER);
2873
2874 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
2875 client_addr.sin_family = AF_INET;
2876 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
2877 client_addr.sin_port = htons(PORT_CLIENT);
2878
2879 chr = '\0';
2880 while ((chr != 'e') && (chr != 'E'))
2881 {
2882 printf("\n");
2883 printf("Please select option\n");
2884 printf("L - Load and run a hex file\n");
2885 printf("T - Have the server test and mark your emulator\n");
2886 printf("E - Exit\n");
2887 if(argc == 2){ building(argc,argv); exit(0);}
2888 printf("Enter option: ");
2889 chr = getchar();
2890 if (chr != 0x0A)
2891 {
2892 dummy = getchar(); // read in the <CR>
2893 }
2894 printf("\n");
2895
2896 switch (chr)
2897 {
2898 case 'L':
2899 case 'l':
2900 load_and_run(argc,argv);
2901 break;
2902
2903 case 'T':
2904 case 't':
2905 test_and_mark();
2906 break;
2907
2908 default:
2909 break;
2910 }
2911 }
2912
2913 closesocket(sock);
2914 WSACleanup();
2915
2916
2917 return 0;
2918}