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