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