· 7 years ago · Feb 22, 2019, 02:52 AM
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/*
418* Function: set_flag_z
419* Description: Set z flag depending on the value in a given register
420* Parameters inReg(BYTE) - the register that will be used to set the flags
421* Returns: none (void)
422* Warnings: none
423*/
424void set_flag_z(BYTE inReg) {
425
426 BYTE reg;
427 reg = inReg;
428
429 if (reg == 0) // msbit set
430 {
431 Flags = Flags | FLAG_Z;
432 }
433 else
434 {
435 Flags = Flags & (0xFF - FLAG_Z);
436 }
437}
438void set_flag_z16(WORD inReg) {
439
440 WORD reg;
441 reg = inReg;
442
443 if (reg == 0)
444 {
445 Flags = Flags | FLAG_Z;
446 }
447 else
448 {
449 Flags = Flags & (0xFF - FLAG_Z);
450 }
451}
452void set_flag_n16(WORD inReg) {
453 WORD reg;
454 reg = inReg;
455
456 if ((reg & 0x8000) != 0) // msbit set
457 {
458 Flags = Flags | FLAG_N;
459 }
460 else
461 {
462 Flags = Flags & (0xFF - FLAG_N);
463 }
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 LB = fetch();
553 HB = 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 LB = fetch();
565 HB = 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 LB = fetch();
577 HB = 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 LB = fetch();
589 HB = 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 LB = fetch();
616 HB = 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 LB = fetch();
628 HB = 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 LB = fetch();
640 HB = 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 LB = fetch();
652 HB = 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 LB = fetch();
680 HB = 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 LB = fetch();
693 HB = 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 LB = fetch();
706 HB = 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 LB = fetch();
719 HB = 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 LB = fetch();
744 HB = 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 LB = fetch();
756 HB = 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 LB = fetch();
768 HB = 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 LB = fetch();
780 HB = 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 LB = fetch();
800 HB = 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_z16(Memory[address]);
809 set_flag_n16(Memory[address]);
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 LB = fetch();
815 HB = 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_z16(Memory[address]);
825 set_flag_n16(Memory[address]);
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 LB = fetch();
831 HB = 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_z16(Memory[address]);
840 set_flag_n16(Memory[address]);
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 LB = fetch();
846 HB = 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_z16(Memory[address]);
855 set_flag_n16(Memory[address]);
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_z16(Memory[address]);
867 set_flag_n16(Memory[address]);
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 LB = fetch();
872 HB = 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 LB = fetch();
884 HB = 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 LB = fetch();
896 HB = 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 LB = fetch();
908 HB = 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 LB = fetch();
928 HB = 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 LB = fetch();
940 HB = 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 LB = fetch();
952 HB = 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 LB = fetch();
964 HB = 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 case 0xA6://CLC - clears carry flag
1446 Flags = Flags & (0xFF - FLAG_C);
1447 break;
1448
1449 case 0xA7://SEC - sets carry flag
1450 Flags = Flags | FLAG_C;
1451 break;
1452
1453 case 0xA8://CLI - clears interrupt flag
1454 Flags = Flags & (0xFF - FLAG_I);
1455 break;
1456
1457 case 0xA9://SEI - sets interrupt flag
1458 Flags = Flags | FLAG_I;
1459 break;
1460
1461 case 0xAA://CMC - compliment carry flag
1462 Flags = Flags ^ FLAG_C;
1463 break;
1464
1465 case 0xAE://PUSH REGISTER A - checks stackpointer is within memory limits, sets stack pointer to register A
1466 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1467 StackPointer--;
1468 Memory[StackPointer] = Registers[REGISTER_A];
1469 }
1470 break;
1471
1472 case 0xBE://PUSH FLAGS - checks stackpointer is within memory limits, sets stack pointer to flags
1473 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1474 StackPointer--;
1475 Memory[StackPointer] = Flags;
1476 }
1477 break;
1478
1479 case 0xCE://PUSH REGISTER B - checks stackpointer is within memory limits, sets stack pointer to register B
1480 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1481 StackPointer--;
1482 Memory[StackPointer] = Registers[REGISTER_B];
1483 }
1484 break;
1485
1486 case 0xDE://PUSH REGISTER C - checks stackpointer is within memory limits, sets stack pointer to register C
1487 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1488 StackPointer--;
1489 Memory[StackPointer] = Registers[REGISTER_C];
1490 }
1491 break;
1492
1493 case 0xEE://PUSH REGISTER L - checks stackpointer is within memory limits, sets stack pointer to register L
1494 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1495 StackPointer--;
1496 Memory[StackPointer] = Registers[REGISTER_L];
1497 }
1498 break;
1499
1500 case 0xFE://PUSH REGISTER H - checks stackpointer is within memory limits, sets stack pointer to register H
1501 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1502 StackPointer--;
1503 Memory[StackPointer] = Registers[REGISTER_H];
1504 }
1505 break;
1506
1507 case 0xAF://POP REGISTER A - checks stack pointer is within memory limits, loads stack pointer into register A, then adds one to stack pointer
1508 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1509 Registers[REGISTER_A] = Memory[StackPointer];
1510 StackPointer++;
1511 }
1512 break;
1513
1514 case 0xBF://POP FLAGS checks stack pointer is within memory limits, loads stack pointer into Flags, then adds one to stack pointer
1515 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1516 Flags = Memory[StackPointer];
1517 StackPointer++;
1518 }
1519 break;
1520
1521 case 0xCF://POP REGISTER B -checks stack pointer is within memory limits, loads stack pointer into register B, then adds one to stack pointer
1522 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1523 Registers[REGISTER_B] = Memory[StackPointer];
1524 StackPointer++;
1525 }
1526 break;
1527
1528 case 0xDF://POP REGISTER C - checks stack pointer is within memory limits, loads stack pointer into register C, then adds one to stack pointer
1529 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1530 Registers[REGISTER_C] = Memory[StackPointer];
1531 StackPointer++;
1532 }
1533 break;
1534
1535 case 0xEF://POP REGISTER L -checks stack pointer is within memory limits, loads stack pointer into register L, then adds one to stack pointer
1536 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1537 Registers[REGISTER_L] = Memory[StackPointer];
1538 StackPointer++;
1539 }
1540 break;
1541
1542 case 0xFF://POP REGISTER M - checks stack pointer is within memory limits, loads stack pointer into register M, then adds one to stack pointer
1543 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1544 Registers[REGISTER_H] = Memory[StackPointer];
1545 StackPointer++;
1546 }
1547 break;
1548
1549 case 0x38: //JUMP - contructs address from LB and HB then sets PC to address
1550 LB = fetch();
1551 HB = fetch();
1552 address = ((WORD)HB << 8) + (WORD)LB;
1553 ProgramCounter = address;
1554 break;
1555
1556
1557
1558
1559 case 0x07://JMPR - contructs address from LB and HB, uses stack pointer to jump to a subroutine, then sets PC to address
1560 LB = fetch();
1561 HB = fetch();
1562 address += ((WORD)HB << 8) + (WORD)LB;
1563 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1564
1565 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1566 StackPointer--;
1567 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1568 StackPointer--;
1569
1570
1571 }
1572 ProgramCounter = address;
1573 break;
1574
1575 case 0x23: //RT - bitwise shifts the stack pointer to get address to return from subroutine
1576 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
1577 HB = Memory[StackPointer];
1578 StackPointer++;
1579 LB = Memory[StackPointer];
1580 StackPointer++;
1581 }
1582 ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
1583 break;
1584
1585 case 0x39://JCC - constructs address from LB and HB, if the carry flag is clear jump to address
1586 LB = fetch();
1587 HB = fetch();
1588 address = ((WORD)HB << 8) + (WORD)LB;
1589 if ((Flags & FLAG_C) == 0)
1590 {
1591 ProgramCounter = address;
1592 }
1593 break;
1594
1595 case 0x3A://JCS - constructs address from LB and HB, if the carry flag is set jump to address
1596 LB = fetch();
1597 HB = fetch();
1598 address = ((WORD)HB << 8) + (WORD)LB;
1599 if ((Flags & FLAG_C) == FLAG_C)
1600 {
1601 ProgramCounter = address;
1602 }
1603 break;
1604
1605 case 0x3B://JNE - constructs address from LB and HB, if result not zero jump to address
1606 LB = fetch();
1607 HB = fetch();
1608 address = ((WORD)HB << 8) + (WORD)LB;
1609 if ((Flags & FLAG_Z) == 0)
1610 {
1611 ProgramCounter = address;
1612 }
1613 break;
1614
1615 case 0x3C://JEQ - constructs address from LB and HB, if result is zero jump to address
1616 LB = fetch();
1617 HB = fetch();
1618 address = ((WORD)HB << 8) + (WORD)LB;
1619 if ((Flags & FLAG_Z) == FLAG_Z)
1620 {
1621 ProgramCounter = address;
1622 }
1623 break;
1624
1625 case 0x3D://JMI - constructs address from LB and HB, if result is negative jump to address
1626 LB = fetch();
1627 HB = fetch();
1628 address = ((WORD)HB << 8) + (WORD)LB;
1629 if ((Flags & FLAG_N) == FLAG_N)
1630 {
1631 ProgramCounter = address;
1632 }
1633 break;
1634
1635 case 0x3E://JPL - constructs address from LB and HB, if result is positive jump to address
1636 LB = fetch();
1637 HB = fetch();
1638 address = ((WORD)HB << 8) + (WORD)LB;
1639 if ((Flags & FLAG_N) == 0)
1640 {
1641 ProgramCounter = address;
1642 }
1643 break;
1644
1645 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
1646 LB = fetch();
1647 HB = fetch();
1648 address = ((WORD)HB << 8) + (WORD)LB;
1649 if ((Flags & FLAG_C) == 0) {
1650 Memory[StackPointer] = ProgramCounter;
1651 StackPointer--;
1652 ProgramCounter = address;
1653 }
1654 break;
1655
1656 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
1657 LB = fetch();
1658 HB = fetch();
1659 address = ((WORD)HB << 8) + (WORD)LB;
1660
1661 if ((Flags & FLAG_C) != 0) {
1662 Memory[StackPointer] = ProgramCounter;
1663 StackPointer--;
1664 ProgramCounter = address;
1665 }
1666 break;
1667
1668 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
1669 LB = fetch();
1670 HB = fetch();
1671 address = ((WORD)HB << 8) + (WORD)LB;
1672
1673 if ((Flags & FLAG_Z) == 0) {
1674 Memory[StackPointer] = ProgramCounter;
1675 StackPointer--;
1676 ProgramCounter = address;
1677 }
1678 break;
1679
1680 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
1681 LB = fetch();
1682 HB = fetch();
1683 address = ((WORD)HB << 8) + (WORD)LB;
1684
1685 if ((Flags & FLAG_Z) != 0) {
1686 Memory[StackPointer] = ProgramCounter;
1687 StackPointer--;
1688 ProgramCounter = address;
1689 }
1690 break;
1691
1692 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
1693 LB = fetch();
1694 HB = fetch();
1695 address = ((WORD)HB << 8) + (WORD)LB;
1696
1697 if ((Flags & FLAG_N) != 0) {
1698 Memory[StackPointer] = ProgramCounter;
1699 StackPointer--;
1700 ProgramCounter = address;
1701 }
1702 break;
1703
1704 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
1705 LB = fetch();
1706 HB = fetch();
1707 address = ((WORD)HB << 8) + (WORD)LB;
1708
1709 if ((Flags & FLAG_N) == 0) {
1710 Memory[StackPointer] = ProgramCounter;
1711 StackPointer--;
1712 ProgramCounter = address;
1713 }
1714 break;
1715
1716 case 0x95: //INCA - increment register A
1717 ++Registers[REGISTER_A];
1718 set_flag_n(Registers[REGISTER_A]);
1719 set_flag_z(Registers[REGISTER_A]);
1720 break;
1721
1722 case 0x96: //DECA - decrement register A
1723 Registers[REGISTER_A]--;
1724 set_flag_n(Registers[REGISTER_A]);
1725 set_flag_z(Registers[REGISTER_A]);
1726 break;
1727
1728 case 0x9F: //CLRA - clear register A
1729 Registers[REGISTER_A] = 0;
1730 Flags = Flags | FLAG_Z;
1731 Flags = Flags & (0xFF - FLAG_N);
1732 Flags = Flags & (0xFF - FLAG_C);
1733 break;
1734
1735 case 0x55: // INC Absolute - constructs address from LB and HB then increment address
1736 LB = fetch();
1737 HB = fetch();
1738 address += (WORD)((WORD)HB << 8) + LB;
1739 ++Memory[address];
1740 set_flag_n(Memory[address]);
1741 set_flag_z(Memory[address]);
1742 break;
1743
1744 case 0x65: // INC Absolute X - constructs address from LB and HB in register X then increment address
1745 address += Index_Registers[REGISTER_X];
1746 LB = fetch();
1747 HB = fetch();
1748 address += (WORD)((WORD)HB << 8) + LB;
1749 if (address >= 0 && address < MEMORY_SIZE)
1750 {
1751 ++Memory[address];
1752 }
1753 set_flag_n(Memory[address]);
1754 set_flag_z(Memory[address]);
1755 break;
1756
1757 case 0x75: // INC Absolute Y - constructs address from LB and HB in register Y then increment address
1758 address += Index_Registers[REGISTER_Y];
1759 LB = fetch();
1760 HB = fetch();
1761 address += (WORD)((WORD)HB << 8) + LB;
1762 if (address >= 0 && address < MEMORY_SIZE)
1763 {
1764 ++Memory[address];
1765 }
1766 set_flag_n(Memory[address]);
1767 set_flag_z(Memory[address]);
1768 break;
1769
1770 case 0x85: // INC Absolute X,Y - constructs address from LB and HB in register X and Y then increment address
1771 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1772 LB = fetch();
1773 HB = fetch();
1774 address += (WORD)((WORD)HB << 8) + LB;
1775 if (address >= 0 && address < MEMORY_SIZE)
1776 {
1777 ++Memory[address];
1778 }
1779 set_flag_n(Memory[address]);
1780 set_flag_z(Memory[address]);
1781 break;
1782
1783 case 0x5F: // CLR Absolute - constructs address from LB and HB then clear address
1784 LB = fetch();
1785 HB = fetch();
1786 address += (WORD)((WORD)HB << 8) + LB;
1787 Memory[address] = 0;
1788 Flags = Flags | FLAG_Z;
1789 Flags = Flags & (0xFF - FLAG_N);
1790 Flags = Flags & (0xFF - FLAG_C);
1791 break;
1792
1793 case 0x6F: // CLR Absolute X - constructs address from LB and HB in register X then clear address
1794 address += Index_Registers[REGISTER_X];
1795 LB = fetch();
1796 HB = fetch();
1797 address += (WORD)((WORD)HB << 8) + LB;
1798 Memory[address] = 0;
1799 Flags = Flags | FLAG_Z;
1800 Flags = Flags & (0xFF - FLAG_N);
1801 Flags = Flags & (0xFF - FLAG_C);
1802 break;
1803
1804 case 0x7F: // CLR Absolute Y - constructs address from LB and HB in register Y then clear address
1805 address += Index_Registers[REGISTER_Y];
1806 LB = fetch();
1807 HB = fetch();
1808 address += (WORD)((WORD)HB << 8) + LB;
1809 Memory[address] = 0;
1810 Flags = Flags | FLAG_Z;
1811 Flags = Flags & (0xFF - FLAG_N);
1812 Flags = Flags & (0xFF - FLAG_C);
1813 break;
1814
1815 case 0x8F: // CLR Absolute XY - constructs address from LB and HB in register X and Y then clear address
1816 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1817 LB = fetch();
1818 HB = fetch();
1819 address += (WORD)((WORD)HB << 8) + LB;
1820 Memory[address] = 0;
1821 Flags = Flags | FLAG_Z;
1822 Flags = Flags & (0xFF - FLAG_N);
1823 Flags = Flags & (0xFF - FLAG_C);
1824 break;
1825
1826 case 0x4A: // DEX - constructs address from LB and HB in register X then increment address
1827 Index_Registers[REGISTER_X]--;
1828 set_flag_z(Index_Registers[REGISTER_X]);
1829 break;
1830
1831 case 0x4B: //INX - increment register X
1832 ++Index_Registers[REGISTER_X];
1833 set_flag_z(Index_Registers[REGISTER_X]);
1834 break;
1835
1836 case 0x4C: //DEY - decrement register Y
1837 Index_Registers[REGISTER_Y]--;
1838 set_flag_z(Index_Registers[REGISTER_Y]);
1839 break;
1840
1841 case 0x4D: //INY - increment register Y
1842 ++Index_Registers[REGISTER_Y];
1843 set_flag_z(Index_Registers[REGISTER_Y]);
1844 break;
1845
1846 case 0xBC: // AND Register A,B - bitwise ANDs register A and B
1847 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_B];
1848 set_flag_n((BYTE)temp_word);
1849 set_flag_z((BYTE)temp_word);
1850 Registers[REGISTER_A] = (BYTE)temp_word;
1851 break;
1852
1853 case 0xCC: // AND Register A,C - bitwise ANDs register A and C
1854 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_C];
1855 set_flag_n((BYTE)temp_word);
1856 set_flag_z((BYTE)temp_word);
1857 Registers[REGISTER_A] = (BYTE)temp_word;
1858 break;
1859
1860 case 0xDC: // AND Register A,L - bitwise ANDs register A and L
1861 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_L];
1862 set_flag_n((BYTE)temp_word);
1863 set_flag_z((BYTE)temp_word);
1864 Registers[REGISTER_A] = (BYTE)temp_word;
1865 break;
1866
1867 case 0xEC: // AND Register A,H - bitwise ANDs register A and H
1868 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_H];
1869 set_flag_n((BYTE)temp_word);
1870 set_flag_z((BYTE)temp_word);
1871 Registers[REGISTER_A] = (BYTE)temp_word;
1872 break;
1873
1874 case 0xFC: // AND Register A,M - bitwise ANDs register A and M
1875 HB = Registers[REGISTER_H];
1876 LB = Registers[REGISTER_L];
1877 address = ((WORD)HB << 8) + LB;
1878 param1 = Registers[REGISTER_A];
1879 param2 = Memory[address];
1880 temp_word = (WORD)param1 & (WORD)param2;
1881 set_flag_n((BYTE)temp_word);
1882 set_flag_z((BYTE)temp_word);
1883 Registers[REGISTER_A] = (BYTE)temp_word;
1884 break;
1885
1886 case 0xBB: //OR A,B - bitwise ORs A and B
1887 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_B];
1888 set_flag_n((BYTE)temp_word);
1889 set_flag_z((BYTE)temp_word);
1890 Registers[REGISTER_A] = (BYTE)temp_word;
1891 break;
1892
1893 case 0xCB: //OR A,C - bitwise ORs A and C
1894 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_C];
1895 set_flag_n((BYTE)temp_word);
1896 set_flag_z((BYTE)temp_word);
1897 Registers[REGISTER_A] = (BYTE)temp_word;
1898 break;
1899
1900 case 0xDB: //OR A,L - bitwise ORs A and L
1901 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_L];
1902 set_flag_n((BYTE)temp_word);
1903 set_flag_z((BYTE)temp_word);
1904 Registers[REGISTER_A] = (BYTE)temp_word;
1905 break;
1906
1907 case 0xEB: //OR A,H - bitwise ORs A and H
1908 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_H];
1909 set_flag_n((BYTE)temp_word);
1910 set_flag_z((BYTE)temp_word);
1911 Registers[REGISTER_A] = (BYTE)temp_word;
1912 break;
1913
1914 case 0xFB: //OR A,M - bitwise ORs A and M
1915 HB = Registers[REGISTER_H];
1916 LB = Registers[REGISTER_L];
1917 address = ((WORD)HB << 8) + LB;
1918 param1 = Registers[REGISTER_A];
1919 param2 = Memory[address];
1920 temp_word = (WORD)param1 | (WORD)param2;
1921 set_flag_n((BYTE)temp_word);
1922 set_flag_z((BYTE)temp_word);
1923 Registers[REGISTER_A] = (BYTE)temp_word;
1924 break;
1925
1926 case 0xBD: //XOR A,B - bitwise XORs A and B
1927 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_B];
1928 set_flag_n((BYTE)temp_word);
1929 set_flag_z((BYTE)temp_word);
1930 Registers[REGISTER_A] = (BYTE)temp_word;
1931 break;
1932
1933 case 0xCD: //XOR A,C - bitwise XORs A and C
1934 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_C];
1935 set_flag_n((BYTE)temp_word);
1936 set_flag_z((BYTE)temp_word);
1937 Registers[REGISTER_A] = (BYTE)temp_word;
1938 break;
1939
1940 case 0xDD: //XOR A,L - bitwise XORs A and L
1941 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_L];
1942 set_flag_n((BYTE)temp_word);
1943 set_flag_z((BYTE)temp_word);
1944 Registers[REGISTER_A] = (BYTE)temp_word;
1945 break;
1946
1947 case 0xED: //XOR A,H - bitwise XORs A and H
1948 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_H];
1949 set_flag_n((BYTE)temp_word);
1950 set_flag_z((BYTE)temp_word);
1951 Registers[REGISTER_A] = (BYTE)temp_word;
1952 break;
1953
1954 case 0xFD: //XOR A,M - bitwise XORs A and M
1955 HB = Registers[REGISTER_H];
1956 LB = Registers[REGISTER_L];
1957 address = ((WORD)HB << 8) + LB;
1958 param1 = Registers[REGISTER_A];
1959 param2 = Memory[address];
1960 temp_word = (WORD)param1 ^ (WORD)param2;
1961 set_flag_n((BYTE)temp_word);
1962 set_flag_z((BYTE)temp_word);
1963 Registers[REGISTER_A] = (BYTE)temp_word;
1964 break;
1965
1966 case 0x56: //DEC Absolute - constructs address from LB and HB then decrements address
1967 LB = fetch();
1968 HB = fetch();
1969 address += (WORD)((WORD)HB << 8) + LB;
1970 Memory[address]--;
1971 set_flag_n(Memory[address]);
1972 set_flag_z(Memory[address]);
1973 break;
1974
1975 case 0x66: //DEC Absolute X - constructs address from LB and HB in register X then decrements address
1976 address += Index_Registers[REGISTER_X];
1977 LB = fetch();
1978 HB = fetch();
1979 address += (WORD)((WORD)HB << 8) + LB;
1980 if (address >= 0 && address < MEMORY_SIZE)
1981 {
1982 Memory[address]--;
1983 }
1984 set_flag_n(Memory[address]);
1985 set_flag_z(Memory[address]);
1986 break;
1987
1988 case 0x76: //DEC Absolute Y - constructs address from LB and HB in register Y then decrements address
1989 address += Index_Registers[REGISTER_Y];
1990 LB = fetch();
1991 HB = fetch();
1992 address += (WORD)((WORD)HB << 8) + LB;
1993 if (address >= 0 && address < MEMORY_SIZE)
1994 {
1995 Memory[address]--;
1996 }
1997 set_flag_n(Memory[address]);
1998 set_flag_z(Memory[address]);
1999 break;
2000
2001 case 0x86: //DEC Absolute X,Y - constructs address from LB and HB in register X and Y then decrements address
2002 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2003 LB = fetch();
2004 HB = fetch();
2005 address += (WORD)((WORD)HB << 8) + LB;
2006 if (address >= 0 && address < MEMORY_SIZE)
2007 {
2008 Memory[address]--;
2009 }
2010 set_flag_n(Memory[address]);
2011 set_flag_z(Memory[address]);
2012 break;
2013
2014 case 0x59: //SAL Absolute - constructs address from LB and HB then checks if carry flag needs to be set, then bitwise shifts address left
2015 LB = fetch();
2016 HB = fetch();
2017 address = (WORD)((WORD)HB << 8) + LB;
2018 saved_flags = Flags;
2019 if ((Memory[address] & 0x80) == 0x80)
2020 {
2021 Flags = Flags | FLAG_C;
2022 }
2023 else {
2024 Flags = Flags & (0xFF - FLAG_C);
2025 }
2026 Memory[address] = (Memory[address] << 1) & 0xFE;
2027 set_flag_n(Memory[address]);
2028 set_flag_z(Memory[address]);
2029 break;
2030
2031 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
2032 address += Index_Registers[REGISTER_X];
2033 LB = fetch();
2034 HB = fetch();
2035 address = (WORD)((WORD)HB << 8) + LB;
2036 saved_flags = Flags;
2037 if ((Memory[address] & 0x80) == 0x80)
2038 {
2039 Flags = Flags | FLAG_C;
2040 }
2041 else {
2042 Flags = Flags & (0xFF - FLAG_C);
2043 }
2044 Memory[address] = (Memory[address] << 1) & 0xFE;
2045 set_flag_n(Memory[address]);
2046 set_flag_z(Memory[address]);
2047 break;
2048
2049 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
2050 address += Index_Registers[REGISTER_Y];
2051 LB = fetch();
2052 HB = fetch();
2053 address = (WORD)((WORD)HB << 8) + LB;
2054 saved_flags = Flags;
2055 if ((Memory[address] & 0x80) == 0x80)
2056 {
2057 Flags = Flags | FLAG_C;
2058 }
2059 else {
2060 Flags = Flags & (0xFF - FLAG_C);
2061 }
2062 Memory[address] = (Memory[address] << 1) & 0xFE;
2063 set_flag_n(Memory[address]);
2064 set_flag_z(Memory[address]);
2065 break;
2066
2067 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
2068 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2069 LB = fetch();
2070 HB = fetch();
2071 address = (WORD)((WORD)HB << 8) + LB;
2072 saved_flags = Flags;
2073 if ((Memory[address] & 0x80) == 0x80)
2074 {
2075 Flags = Flags | FLAG_C;
2076 }
2077 else {
2078 Flags = Flags & (0xFF - FLAG_C);
2079 }
2080 Memory[address] = (Memory[address] << 1) & 0xFE;
2081 set_flag_n(Memory[address]);
2082 set_flag_z(Memory[address]);
2083 break;
2084
2085 case 0x5A: //SHR Absolute - constructs address from LB and HB then checks if carry flag needs to be set, then bitwise shifts address right
2086 LB = fetch();
2087 HB = fetch();
2088 address = (WORD)((WORD)HB << 8) + LB;
2089 if ((Memory[address] & 0x01) == 0x01) {
2090 Flags = Flags | FLAG_C;
2091 }
2092 else {
2093 Flags = Flags & (0xFF - FLAG_C);
2094 }
2095 HB = Memory[address];
2096 Memory[address] = (Memory[address] >> 1) & 0x7F;
2097 if ((HB & 0x80) == 0x80) {
2098 Memory[address] = Memory[address] | 0x80;
2099 }
2100 set_flag_n(Memory[address]);
2101 set_flag_z(Memory[address]);
2102 break;
2103
2104 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
2105 address += Index_Registers[REGISTER_X];
2106 LB = fetch();
2107 HB = fetch();
2108 address = (WORD)((WORD)HB << 8) + LB;
2109 if ((Memory[address] & 0x01) == 0x01) {
2110 Flags = Flags | FLAG_C;
2111 }
2112 else {
2113 Flags = Flags & (0xFF - FLAG_C);
2114 }
2115 HB = Memory[address];
2116 Memory[address] = (Memory[address] >> 1) & 0x7F;
2117 if ((HB & 0x80) == 0x80) {
2118 Memory[address] = Memory[address] | 0x80;
2119 }
2120 set_flag_n(Memory[address]);
2121 set_flag_z(Memory[address]);
2122 break;
2123
2124 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
2125 address += Index_Registers[REGISTER_Y];
2126 LB = fetch();
2127 HB = fetch();
2128 address = (WORD)((WORD)HB << 8) + LB;
2129 if ((Memory[address] & 0x01) == 0x01) {
2130 Flags = Flags | FLAG_C;
2131 }
2132 else {
2133 Flags = Flags & (0xFF - FLAG_C);
2134 }
2135 HB = Memory[address];
2136 Memory[address] = (Memory[address] >> 1) & 0x7F;
2137 if ((HB & 0x80) == 0x80) {
2138 Memory[address] = Memory[address] | 0x80;
2139 }
2140 set_flag_n(Memory[address]);
2141 set_flag_z(Memory[address]);
2142
2143 break;
2144
2145 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
2146 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2147 LB = fetch();
2148 HB = fetch();
2149 address = (WORD)((WORD)HB << 8) + LB;
2150 if ((Memory[address] & 0x01) == 0x01) {
2151 Flags = Flags | FLAG_C;
2152 }
2153 else {
2154 Flags = Flags & (0xFF - FLAG_C);
2155 }
2156 HB = Memory[address];
2157 Memory[address] = (Memory[address] >> 1) & 0x7F;
2158 if ((HB & 0x80) == 0x80) {
2159 Memory[address] = Memory[address] | 0x80;
2160 }
2161 set_flag_n(Memory[address]);
2162 set_flag_z(Memory[address]);
2163 break;
2164
2165 case 0x02: //SWI - checks stack pointer is within memory limits, decrements it, changes stack pointer to equal register A
2166 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2167 StackPointer--;
2168 Memory[StackPointer] = Registers[REGISTER_A];
2169 }
2170 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) { // checks if stack pointer within memory limits, decrements it then changes stack pointer to equal PC
2171 StackPointer--;
2172 Memory[StackPointer] = (BYTE)ProgramCounter;
2173 }
2174 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
2175 StackPointer--;
2176 Memory[StackPointer] = (BYTE)(ProgramCounter >> 8);
2177 }
2178 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) { // checks if stack pointer within memory limits, decrements it then changes stack pointer to equal Flags
2179 StackPointer--;
2180 Memory[StackPointer] = Flags;
2181 }
2182 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) { // checks if stack pointer within memory limits, decrements it then changes stack pointer to equal register B
2183 StackPointer--;
2184 Memory[StackPointer] = Registers[REGISTER_B];
2185 }
2186 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) { // checks if stack pointer within memory limits, decrements it then changes stack pointer to equal register C
2187 StackPointer--;
2188 Memory[StackPointer] = Registers[REGISTER_C];
2189 }
2190 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) { // checks if stack pointer within memory limits, decrements it then changes stack pointer to equal register L
2191 StackPointer--;
2192 Memory[StackPointer] = Registers[REGISTER_L];
2193 }
2194 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) { // checks if stack pointer within memory limits, decrements it then changes stack pointer to equal register H
2195 StackPointer--;
2196 Memory[StackPointer] = Registers[REGISTER_H];
2197 }
2198 break;
2199
2200 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
2201 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2202 Registers[REGISTER_H] = Memory[StackPointer];
2203 StackPointer++;
2204 }
2205 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
2206 Registers[REGISTER_L] = Memory[StackPointer];
2207 StackPointer++;
2208 }
2209 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
2210 Registers[REGISTER_C] = Memory[StackPointer];
2211 StackPointer++;
2212 }
2213 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
2214 Registers[REGISTER_B] = Memory[StackPointer];
2215 StackPointer++;
2216 }
2217 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
2218 Flags = Memory[StackPointer];
2219 StackPointer++;
2220 }
2221 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
2222 ProgramCounter = (WORD)(Memory[StackPointer] << 8);
2223 StackPointer++;
2224 }
2225 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
2226 ProgramCounter += Memory[StackPointer];
2227 StackPointer++;
2228 }
2229 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
2230 Registers[REGISTER_A] = Memory[StackPointer];
2231 StackPointer++;
2232 }
2233 break;
2234
2235 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
2236 saved_flags = Flags;
2237 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
2238 Flags = Flags | FLAG_C;
2239 }
2240 else {
2241 Flags = Flags & (0xFF - FLAG_C);
2242 }
2243 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
2244 if ((saved_flags & FLAG_C) == FLAG_C) {
2245 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
2246 }
2247 set_flag_n(Registers[REGISTER_A]);
2248 set_flag_z(Registers[REGISTER_A]);
2249 break;
2250
2251 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
2252 data = fetch();
2253 temp_word = (WORD)Registers[REGISTER_A] + data;
2254 if ((Flags & FLAG_C) != 0)
2255 {
2256 temp_word++;
2257 }
2258 if (temp_word >= 0x100)
2259 {
2260 Flags = Flags | FLAG_C;
2261 }
2262 else
2263 {
2264 Flags = Flags & (0xFF - FLAG_C);
2265 }
2266 set_flag_n((BYTE)temp_word);
2267 set_flag_z((BYTE)temp_word);
2268 Registers[REGISTER_A] = (BYTE)temp_word;
2269 break;
2270
2271 case 0x1D: //CPI - compares fetched data with register A, if fetched data is greater than, set the carry flag, else clear flag
2272 data = fetch();
2273 temp_word = (WORD)data - (WORD)Registers[REGISTER_A];
2274 if (temp_word >= 0x100) {
2275 Flags = Flags | FLAG_C; // Set carry flag
2276 }
2277 else {
2278 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
2279 }
2280 set_flag_z((BYTE)temp_word);
2281 set_flag_n((BYTE)temp_word);
2282 break;
2283
2284 case 0x1E: //ANI - biwise ANDs fetched data with register A, if carry flag needed set carry flag, if not clear flag
2285 data = fetch();
2286 temp_word = (WORD)Registers[REGISTER_A] & data;
2287 if (temp_word >= 0x100)
2288 {
2289 Flags = Flags | FLAG_C;
2290 }
2291 else
2292 {
2293 Flags = Flags & (0xFF - FLAG_C);
2294 }
2295 Registers[REGISTER_A] = (BYTE)temp_word;
2296 set_flag_n((BYTE)temp_word);
2297 set_flag_z((BYTE)temp_word);
2298 break;
2299
2300 case 0x54: //TEST Absolute - address is constructed from LB and HB, loads address into variable data
2301 LB = fetch();
2302 HB = fetch();
2303 address += (WORD)((WORD)HB << 8) + LB;
2304 data = Memory[address];
2305 set_flag_n(data);
2306 set_flag_z(data);
2307 break;
2308
2309 case 0x64: //TEST Absolute X - address is constructed from LB and HB in register X, loads address into variable data
2310 address += Index_Registers[REGISTER_X];
2311 LB = fetch();
2312 HB = fetch();
2313 address += (WORD)((WORD)HB << 8) + LB;
2314 data = Memory[address];
2315 set_flag_n(data);
2316 set_flag_z(data);
2317 break;
2318
2319 case 0x74: //TEST Absolute Y - address is constructed from LB and HB in register Y, loads address into variable data
2320 address += Index_Registers[REGISTER_Y];
2321 LB = fetch();
2322 HB = fetch();
2323 address += (WORD)((WORD)HB << 8) + LB;
2324 data = Memory[address];
2325 set_flag_n(data);
2326 set_flag_z(data);
2327 break;
2328
2329 case 0x84: //TEST Absolute X,Y - address is constructed from LB and HB in X and Y, loads address into variable data
2330 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2331 LB = fetch();
2332 HB = fetch();
2333 address += (WORD)((WORD)HB << 8) + LB;
2334 data = Memory[address];
2335 set_flag_n(data);
2336 set_flag_z(data);
2337 break;
2338
2339 case 0x94: //TESTA - sets flags N and Z to register A
2340 set_flag_n(Registers[REGISTER_A]);
2341 set_flag_z(Registers[REGISTER_A]);
2342 break;
2343
2344 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
2345 LB = fetch();
2346 HB = fetch();
2347 address += (WORD)((WORD)HB << 8) + LB;
2348 saved_flags = Flags;
2349
2350 if ((Memory[address] & 0x01) == 0x01) {
2351 Flags = Flags | FLAG_C;
2352 }
2353 else {
2354 Flags = Flags & (0xFF - FLAG_C);
2355 }
2356 Memory[address] = (Memory[address] >> 1) & 0x7F;
2357
2358 if ((saved_flags & FLAG_C) == FLAG_C) { // if the carry was set, add it on
2359 Memory[address] = Memory[address] | 0x80;
2360 }
2361 set_flag_n((BYTE)Memory[address]);
2362 set_flag_z((BYTE)Memory[address]);
2363 break;
2364
2365 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
2366 address += Index_Registers[REGISTER_X];
2367 LB = fetch();
2368 HB = fetch();
2369 address += (WORD)((WORD)HB << 8) + LB;
2370 saved_flags = Flags;
2371
2372 if ((Memory[address] & 0x01) == 0x01) {
2373 Flags = Flags | FLAG_C;
2374 }
2375 else {
2376 Flags = Flags & (0xFF - FLAG_C);
2377 }
2378 Memory[address] = (Memory[address] >> 1) & 0x7F;
2379
2380 if ((saved_flags & FLAG_C) == FLAG_C) { // if carry flag set, add it on
2381 Memory[address] = Memory[address] | 0x80;
2382 }
2383 set_flag_n((BYTE)Memory[address]);
2384 set_flag_z((BYTE)Memory[address]);
2385 break;
2386
2387 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
2388 address += Index_Registers[REGISTER_Y];
2389 LB = fetch();
2390 HB = fetch();
2391 address += (WORD)((WORD)HB << 8) + LB;
2392 saved_flags = Flags;
2393
2394 if ((Memory[address] & 0x01) == 0x01) {
2395 Flags = Flags | FLAG_C;
2396 }
2397 else {
2398 Flags = Flags & (0xFF - FLAG_C);
2399 }
2400 Memory[address] = (Memory[address] >> 1) & 0x7F;
2401
2402 if ((saved_flags & FLAG_C) == FLAG_C) { // if carry flag set, add it on
2403 Memory[address] = Memory[address] | 0x80;
2404 }
2405 set_flag_n((BYTE)Memory[address]);
2406 set_flag_z((BYTE)Memory[address]);
2407 break;
2408
2409 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
2410 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2411 LB = fetch();
2412 HB = fetch();
2413 address += (WORD)((WORD)HB << 8) + LB;
2414 saved_flags = Flags;
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 if ((saved_flags & FLAG_C) == FLAG_C) { // if carry flag set, add it on
2423 Memory[address] = Memory[address] | 0x80;
2424 }
2425 set_flag_n((BYTE)Memory[address]);
2426 set_flag_z((BYTE)Memory[address]);
2427 break;
2428
2429 case 0x97: //RRA - saves flags in saved flags, checks if carry flag needed, if so set, if not clear, bitwise shift register A right
2430 saved_flags = Flags;
2431 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
2432 Flags = Flags | FLAG_C;
2433 }
2434 else {
2435 Flags = Flags & (0xFF - FLAG_C);
2436 }
2437 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
2438 if ((saved_flags & FLAG_C) == FLAG_C) { // if carry flag set, add it on
2439 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
2440 }
2441 set_flag_n((BYTE)Registers[REGISTER_A]);
2442 set_flag_z((BYTE)Registers[REGISTER_A]);
2443 break;
2444
2445 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
2446 LB = fetch();
2447 HB = fetch();
2448 address += (WORD)((WORD)HB << 8) + LB;
2449 saved_flags = Flags;
2450 if ((Memory[address] & 0x80) == 0x80) {
2451 Flags = Flags | FLAG_C;
2452 }
2453 else {
2454 Flags = Flags & (0xFF - FLAG_C);
2455 }
2456 Memory[address] = (Memory[address] << 1) & 0xFE;
2457 if ((saved_flags & FLAG_C) == FLAG_C) { // if carry flag set, add it on
2458 Memory[address] = Memory[address] | 0x01;
2459 }
2460 set_flag_n((BYTE)Memory[address]);
2461 set_flag_z((BYTE)Memory[address]);
2462 break;
2463
2464 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
2465 address += Index_Registers[REGISTER_X];
2466 LB = fetch();
2467 HB = fetch();
2468 address += (WORD)((WORD)HB << 8) + LB;
2469 saved_flags = Flags;
2470 if ((Memory[address] & 0x80) == 0x80) {
2471 Flags = Flags | FLAG_C;
2472 }
2473 else {
2474 Flags = Flags & (0xFF - FLAG_C);
2475 }
2476 Memory[address] = (Memory[address] << 1) & 0xFE;
2477 if ((saved_flags & FLAG_C) == FLAG_C) { // if carry flag set, add it on
2478 Memory[address] = Memory[address] | 0x01;
2479 }
2480 set_flag_n((BYTE)Memory[address]);
2481 set_flag_z((BYTE)Memory[address]);
2482 break;
2483
2484 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
2485 address += Index_Registers[REGISTER_Y];
2486 LB = fetch();
2487 HB = fetch();
2488 address += (WORD)((WORD)HB << 8) + LB;
2489 saved_flags = Flags;
2490 if ((Memory[address] & 0x80) == 0x80) {
2491 Flags = Flags | FLAG_C;
2492 }
2493 else {
2494 Flags = Flags & (0xFF - FLAG_C);
2495 }
2496 Memory[address] = (Memory[address] << 1) & 0xFE;
2497 if ((saved_flags & FLAG_C) == FLAG_C) { // if carry flag set, add it on
2498 Memory[address] = Memory[address] | 0x01;
2499 }
2500 set_flag_n((BYTE)Memory[address]);
2501 set_flag_z((BYTE)Memory[address]);
2502 break;
2503
2504 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
2505 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2506 LB = fetch();
2507 HB = fetch();
2508 address += (WORD)((WORD)HB << 8) + LB;
2509 saved_flags = Flags;
2510 if ((Memory[address] & 0x80) == 0x80) {
2511 Flags = Flags | FLAG_C;
2512 }
2513 else {
2514 Flags = Flags & (0xFF - FLAG_C);
2515 }
2516 Memory[address] = (Memory[address] << 1) & 0xFE;
2517 if ((saved_flags & FLAG_C) == FLAG_C) { // if carry flag set, add it on
2518 Memory[address] = Memory[address] | 0x01;
2519 }
2520 set_flag_n((BYTE)Memory[address]);
2521 set_flag_z((BYTE)Memory[address]);
2522 break;
2523
2524 case 0x99: //SALA - saves Flags in saved flags, checks if carry flag needed, if so set, if not clear, bitwise shifts register A left
2525 saved_flags = Flags;
2526 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
2527 Flags = Flags | FLAG_C;
2528 }
2529 else {
2530 Flags = Flags & (0xFF - FLAG_C);
2531 }
2532 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
2533 set_flag_n(Registers[REGISTER_A]);
2534 set_flag_z(Registers[REGISTER_A]);
2535 break;
2536
2537 case 0x9A: //SHRA - checks if carry flag needed, if so set, if not clear, bitwise shifts register A right
2538 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
2539 Flags = Flags | FLAG_C;
2540 }
2541 else {
2542 Flags = Flags & (0xFF - FLAG_C);
2543 }
2544 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
2545 if ((Flags & FLAG_N) == FLAG_N) { // if negative flag set, change register A to negative
2546 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
2547 }
2548 set_flag_n(Registers[REGISTER_A]);
2549 set_flag_z(Registers[REGISTER_A]);
2550 break;
2551
2552 case 0x5B: //COM Absolute - constructs address from LB and HB, negates address in memory, sets carry flag
2553 LB = fetch();
2554 HB = fetch();
2555 address += (WORD)((WORD)HB << 8) + LB;
2556 Memory[address] = Memory[address] ^ 0xFFFF;
2557 Flags = Flags | FLAG_C;
2558 set_flag_n(Memory[address]);
2559 set_flag_z(Memory[address]);
2560 break;
2561
2562 case 0x6B: //COM Absolute X - constructs address from LB and HB in register X, negates address in memory, sets carry flag
2563 address += Index_Registers[REGISTER_X];
2564 LB = fetch();
2565 HB = fetch();
2566 address += (WORD)((WORD)HB << 8) + LB;
2567 Memory[address] = Memory[address] ^ 0xFFFF;
2568 Flags = Flags | FLAG_C;
2569 set_flag_n(Memory[address]);
2570 set_flag_z(Memory[address]);
2571 break;
2572
2573 case 0x7B: //COM Absolute Y - constructs address from LB and HB in register Y, negates address in memory, sets carry flag
2574 address += Index_Registers[REGISTER_Y];
2575 LB = fetch();
2576 HB = fetch();
2577 address += (WORD)((WORD)HB << 8) + LB;
2578 Memory[address] = Memory[address] ^ 0xFFFF;
2579 Flags = Flags | FLAG_C;
2580 set_flag_n(Memory[address]);
2581 set_flag_z(Memory[address]);
2582 break;
2583
2584 case 0x8B: //COM Absolute X,Y - constructs address from LB and HB in register X and Y, negates address in memory, sets carry flag
2585 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2586 LB = fetch();
2587 HB = fetch();
2588 address += (WORD)((WORD)HB << 8) + LB;
2589 Memory[address] = Memory[address] ^ 0xFFFF;
2590 Flags = Flags | FLAG_C;
2591 set_flag_n(Memory[address]);
2592 set_flag_z(Memory[address]);
2593 break;
2594
2595 case 0x9B: //COMA - negates register A, checks if carry flag needed, if so set, if not clear
2596 temp_word = (WORD)Registers[REGISTER_A] ^ 0xFFFF;
2597 if (temp_word >= 0x100)
2598 {
2599 Flags = Flags | FLAG_C;
2600 }
2601 else
2602 {
2603 Flags = Flags & (0xFF - FLAG_C);
2604 }
2605 set_flag_n((BYTE)temp_word);
2606 set_flag_z((BYTE)temp_word);
2607 Registers[REGISTER_A] = (BYTE)temp_word;
2608 break;
2609
2610 case 0x5C: //NEG Absolute - constructs address from LB and HB, clears address then takes itself away
2611 LB = fetch();
2612 HB = fetch();
2613 address += (WORD)((WORD)HB << 8) + LB;
2614 Memory[address] = 0 - Memory[address];
2615 set_flag_n(Memory[address]);
2616 set_flag_z(Memory[address]);
2617 break;
2618
2619 case 0x6C: //NEG Absolute X - constructs address from LB and HB in register X, clears address then takes itself away
2620 address += Index_Registers[REGISTER_X];
2621 LB = fetch();
2622 HB = fetch();
2623 address += (WORD)((WORD)HB << 8) + LB;
2624 Memory[address] = 0 - Memory[address];
2625 set_flag_n(Memory[address]);
2626 set_flag_z(Memory[address]);
2627 break;
2628
2629 case 0x7C: //NEG Absolute Y - constructs address from LB and HB in register Y, clears address then takes itself away
2630 address += Index_Registers[REGISTER_Y];
2631 LB = fetch();
2632 HB = fetch();
2633 address += (WORD)((WORD)HB << 8) + LB;
2634 Memory[address] = 0 - Memory[address];
2635 set_flag_n(Memory[address]);
2636 set_flag_z(Memory[address]);
2637 break;
2638
2639 case 0x8C: //NEG Absolute X,Y - constructs address from LB and HB in register X and Y, clears address then takes itself away
2640 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2641 LB = fetch();
2642 HB = fetch();
2643 address += (WORD)((WORD)HB << 8) + LB;
2644 Memory[address] = 0 - Memory[address];
2645 set_flag_n(Memory[address]);
2646 set_flag_z(Memory[address]);
2647 break;
2648
2649 case 0x9C: //NEGA - converts register A into 2's compliments
2650 Registers[REGISTER_A] = Registers[REGISTER_A] ^ 0xFF;
2651 Registers[REGISTER_A]++;
2652 set_flag_n(Registers[REGISTER_A]);
2653 set_flag_z(Registers[REGISTER_A]);
2654 break;
2655
2656 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
2657 LB = fetch();
2658 HB = fetch();
2659 address += (WORD)((WORD)HB << 8) + LB;
2660 saved_flags = Flags;
2661 if ((Memory[address] & 0x80) == 0x80) {
2662 Flags = Flags | FLAG_C;
2663 }
2664 else {
2665 Flags = Flags & (0xFF - FLAG_C);
2666 }
2667 Memory[address] = (Memory[address] << 1) & 0xFE;
2668 if ((Flags & FLAG_C) == FLAG_C) { // check if carry flag set, if so add it on, then sets flags to how they were
2669 Memory[address] = Memory[address] | 0x01;
2670 }
2671 Flags = saved_flags;
2672 set_flag_n((BYTE)Memory[address]);
2673 set_flag_z((BYTE)Memory[address]);
2674 break;
2675
2676 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
2677 address += Index_Registers[REGISTER_X];
2678 LB = fetch();
2679 HB = 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 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
2698 address += Index_Registers[REGISTER_Y];
2699 LB = fetch();
2700 HB = 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 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
2719 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2720 LB = fetch();
2721 HB = 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 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
2740 saved_flags = Flags;
2741 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
2742 Flags = Flags | FLAG_C;
2743 }
2744 else {
2745 Flags = Flags & (0xFF - FLAG_C);
2746 }
2747 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
2748 if ((Flags & FLAG_C) == FLAG_C) { // check if carry flag set, if so add it on, then sets flags to how they were
2749 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
2750 }
2751 Flags = saved_flags;
2752 set_flag_n((BYTE)Registers[REGISTER_A]);
2753 set_flag_z((BYTE)Registers[REGISTER_A]);
2754 break;
2755
2756 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
2757 LB = fetch();
2758 HB = fetch();
2759 address += (WORD)((WORD)HB << 8) + LB;
2760 saved_flags = Flags;
2761 if ((Memory[address] & 0x01) == 0x01) {
2762 Flags = Flags | FLAG_C;
2763 }
2764 else {
2765 Flags = Flags & (0xFF - FLAG_C);
2766 }
2767 Memory[address] = (Memory[address] >> 1) & 0x7F;
2768 if ((Flags & FLAG_C) == FLAG_C) { // if carry flag set, add it on
2769 Memory[address] = Memory[address] | 0x80;
2770 }
2771 Flags = saved_flags;
2772 set_flag_n((BYTE)Memory[address]);
2773 set_flag_z((BYTE)Memory[address]);
2774 break;
2775
2776 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
2777 address += Index_Registers[REGISTER_X];
2778 LB = fetch();
2779 HB = 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 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
2798 address += Index_Registers[REGISTER_Y];
2799 LB = fetch();
2800 HB = 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
2811 if ((Flags & FLAG_C) == FLAG_C) { // if carry flag set, add it on
2812 Memory[address] = Memory[address] | 0x80;
2813 }
2814 Flags = saved_flags;
2815 set_flag_n((BYTE)Memory[address]);
2816 set_flag_z((BYTE)Memory[address]);
2817 break;
2818
2819 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
2820 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2821 LB = fetch();
2822 HB = fetch();
2823 address += (WORD)((WORD)HB << 8) + LB;
2824 saved_flags = Flags;
2825 if ((Memory[address] & 0x01) == 0x01) {
2826 Flags = Flags | FLAG_C;
2827 }
2828 else {
2829 Flags = Flags & (0xFF - FLAG_C);
2830 }
2831 Memory[address] = (Memory[address] >> 1) & 0x7F;
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 0x9E: //RORA - flags are saved to saved flags, checks if carry is needed, if so set, if not clear, bitwise shift register A right
2841 saved_flags = Flags;
2842 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
2843 Flags = Flags | FLAG_C;
2844 }
2845 else {
2846 Flags = Flags & (0xFF - FLAG_C);
2847 }
2848 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
2849 if ((Flags & FLAG_C) == FLAG_C) { // if carry flag set, add it on
2850 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
2851 }
2852 Flags = saved_flags;
2853 set_flag_n((BYTE)Registers[REGISTER_A]);
2854 set_flag_z((BYTE)Registers[REGISTER_A]);
2855 break;
2856
2857 //No Operation
2858 case 0x17: //NOP
2859 break;
2860
2861 case 0x18: //WAI - halts
2862 halt = true;
2863 break;
2864 }
2865}
2866
2867void Group_2_Move(BYTE opcode)
2868{
2869 BYTE source = opcode >> 4;
2870 BYTE destination = opcode & 0x0F;
2871 int destReg;
2872 int sourceReg;
2873 WORD address = 0;
2874 switch (destination) {
2875 case 0x00: // sets destination to register A
2876 destReg = REGISTER_A;
2877 break;
2878
2879 case 0x01: // sets destination to register B
2880 destReg = REGISTER_B;
2881 break;
2882
2883 case 0x02: // sets destination to register C
2884 destReg = REGISTER_C;
2885 break;
2886
2887 case 0x03: // sets destination to register L
2888 destReg = REGISTER_L;
2889 break;
2890
2891 case 0x04: // sets destination to register H
2892 destReg = REGISTER_H;
2893 break;
2894
2895 case 0x05: // sets destination to register M
2896 destReg = REGISTER_M;
2897 break;
2898 }
2899
2900 switch (source) {
2901
2902 case 0x0A: // sets the source to register A
2903 sourceReg = REGISTER_A;
2904 break;
2905
2906 case 0x0B: // sets the source to register B
2907 sourceReg = REGISTER_B;
2908 break;
2909
2910 case 0x0C: // sets the source to register C
2911 sourceReg = REGISTER_C;
2912 break;
2913
2914 case 0x0D: // sets the source to register L
2915 sourceReg = REGISTER_L;
2916 break;
2917
2918 case 0x0E: // sets the source to register H
2919 sourceReg = REGISTER_H;
2920 break;
2921
2922 case 0x0F: // sets the source to register M
2923 sourceReg = REGISTER_M;
2924 break;
2925 }
2926
2927 if (sourceReg == REGISTER_M) { // creates register M, as it does not technically exist how the others do
2928
2929 address = Registers[REGISTER_L];
2930 address += (WORD)Registers[REGISTER_H] << 8;
2931
2932 if (address >= 0 && address <= MEMORY_SIZE) {
2933 Registers[REGISTER_M] = Memory[address];
2934 }
2935 }
2936
2937 if (destReg == REGISTER_M) { // creates register M, as it does not technically exist how the others do
2938 address = Registers[REGISTER_L];
2939 address += (WORD)Registers[REGISTER_H] << 8;
2940 if (address >= 0 && address <= MEMORY_SIZE) {
2941 Memory[address] = Registers[sourceReg];
2942 }
2943 }
2944 else {
2945 Registers[destReg] = Registers[sourceReg];
2946 }
2947}
2948
2949
2950
2951
2952
2953void execute(BYTE opcode)
2954{
2955 BYTE source = opcode >> 4;
2956 BYTE destination = opcode & 0x0F;
2957
2958 if (((source >= 0x0A) && (source <= 0x0F)) && ((destination >= 0x00) && (destination <= 0x05)))
2959 {
2960 Group_2_Move(opcode);
2961 }
2962 else
2963 {
2964 Group_1(opcode);
2965 }
2966}
2967
2968void emulate()
2969{
2970 BYTE opcode;
2971 int sanity;
2972
2973 ProgramCounter = 0;
2974 halt = false;
2975 memory_in_range = true;
2976 sanity = 0;
2977
2978 printf(" A B C L H X Y SP\n");
2979
2980 while ((!halt) && (memory_in_range)) {
2981 printf("%04X ", ProgramCounter); // Print current address
2982 opcode = fetch();
2983 execute(opcode);
2984
2985 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
2986
2987 printf("%02X ", Registers[REGISTER_A]);
2988 printf("%02X ", Registers[REGISTER_B]);
2989 printf("%02X ", Registers[REGISTER_C]);
2990 printf("%02X ", Registers[REGISTER_L]);
2991 printf("%02X ", Registers[REGISTER_H]);
2992 printf("%02X ", Index_Registers[REGISTER_X]);
2993 printf("%02X ", Index_Registers[REGISTER_Y]);
2994 printf("%04X ", StackPointer); // Print Stack Pointer
2995
2996 if ((Flags & FLAG_Z) == FLAG_Z)
2997 {
2998 printf("Z=1 ");
2999 }
3000 else
3001 {
3002 printf("Z=0 ");
3003 }
3004 if ((Flags & FLAG_I) == FLAG_I)
3005 {
3006 printf("I=1 ");
3007 }
3008 else
3009 {
3010 printf("I=0 ");
3011 }
3012 if ((Flags & FLAG_N) == FLAG_N)
3013 {
3014 printf("N=1 ");
3015 }
3016 else
3017 {
3018 printf("N=0 ");
3019 }
3020 if ((Flags & FLAG_C) == FLAG_C)
3021 {
3022 printf("C=1 ");
3023 }
3024 else
3025 {
3026 printf("C=0 ");
3027 }
3028
3029 printf("\n"); // New line
3030 sanity++;
3031 if (sanity > 200) halt = true;
3032
3033 }
3034
3035 printf("\n"); // New line
3036}
3037
3038
3039////////////////////////////////////////////////////////////////////////////////
3040// Simulator/Emulator (End) //
3041////////////////////////////////////////////////////////////////////////////////
3042
3043
3044void initialise_filenames() {
3045 int i;
3046
3047 for (i = 0; i < MAX_FILENAME_SIZE; i++) {
3048 hex_file[i] = '\0';
3049 trc_file[i] = '\0';
3050 }
3051}
3052
3053
3054
3055
3056int find_dot_position(char *filename) {
3057 int dot_position;
3058 int i;
3059 char chr;
3060
3061 dot_position = 0;
3062 i = 0;
3063 chr = filename[i];
3064
3065 while (chr != '\0') {
3066 if (chr == '.') {
3067 dot_position = i;
3068 }
3069 i++;
3070 chr = filename[i];
3071 }
3072
3073 return (dot_position);
3074}
3075
3076
3077int find_end_position(char *filename) {
3078 int end_position;
3079 int i;
3080 char chr;
3081
3082 end_position = 0;
3083 i = 0;
3084 chr = filename[i];
3085
3086 while (chr != '\0') {
3087 end_position = i;
3088 i++;
3089 chr = filename[i];
3090 }
3091
3092 return (end_position);
3093}
3094
3095
3096bool file_exists(char *filename) {
3097 bool exists;
3098 FILE *ifp;
3099
3100 exists = false;
3101
3102 if ((ifp = fopen(filename, "r")) != NULL) {
3103 exists = true;
3104
3105 fclose(ifp);
3106 }
3107
3108 return (exists);
3109}
3110
3111
3112
3113void create_file(char *filename) {
3114 FILE *ofp;
3115
3116 if ((ofp = fopen(filename, "w")) != NULL) {
3117 fclose(ofp);
3118 }
3119}
3120
3121
3122
3123bool getline(FILE *fp, char *buffer) {
3124 bool rc;
3125 bool collect;
3126 char c;
3127 int i;
3128
3129 rc = false;
3130 collect = true;
3131
3132 i = 0;
3133 while (collect) {
3134 c = getc(fp);
3135
3136 switch (c) {
3137 case EOF:
3138 if (i > 0) {
3139 rc = true;
3140 }
3141 collect = false;
3142 break;
3143
3144 case '\n':
3145 if (i > 0) {
3146 rc = true;
3147 collect = false;
3148 buffer[i] = '\0';
3149 }
3150 break;
3151
3152 default:
3153 buffer[i] = c;
3154 i++;
3155 break;
3156 }
3157 }
3158
3159 return (rc);
3160}
3161
3162
3163
3164
3165
3166
3167void load_and_run(int args, _TCHAR** argv) {
3168 char chr;
3169 int ln;
3170 int dot_position;
3171 int end_position;
3172 long i;
3173 FILE *ifp;
3174 long address;
3175 long load_at;
3176 int code;
3177
3178 // Prompt for the .hex file
3179
3180 printf("\n");
3181 printf("Enter the hex filename (.hex): ");
3182
3183 if (args == 2) {
3184 ln = 0;
3185 chr = argv[1][ln];
3186 while (chr != '\0')
3187 {
3188 if (ln < MAX_FILENAME_SIZE)
3189 {
3190 hex_file[ln] = chr;
3191 trc_file[ln] = chr;
3192 ln++;
3193 }
3194 chr = argv[1][ln];
3195 }
3196 }
3197 else {
3198 ln = 0;
3199 chr = '\0';
3200 while (chr != '\n') {
3201 chr = getchar();
3202
3203 switch (chr) {
3204 case '\n':
3205 break;
3206 default:
3207 if (ln < MAX_FILENAME_SIZE) {
3208 hex_file[ln] = chr;
3209 trc_file[ln] = chr;
3210 ln++;
3211 }
3212 break;
3213 }
3214 }
3215
3216 }
3217 // Tidy up the file names
3218
3219 dot_position = find_dot_position(hex_file);
3220 if (dot_position == 0) {
3221 end_position = find_end_position(hex_file);
3222
3223 hex_file[end_position + 1] = '.';
3224 hex_file[end_position + 2] = 'h';
3225 hex_file[end_position + 3] = 'e';
3226 hex_file[end_position + 4] = 'x';
3227 hex_file[end_position + 5] = '\0';
3228 }
3229 else {
3230 hex_file[dot_position + 0] = '.';
3231 hex_file[dot_position + 1] = 'h';
3232 hex_file[dot_position + 2] = 'e';
3233 hex_file[dot_position + 3] = 'x';
3234 hex_file[dot_position + 4] = '\0';
3235 }
3236
3237 dot_position = find_dot_position(trc_file);
3238 if (dot_position == 0) {
3239 end_position = find_end_position(trc_file);
3240
3241 trc_file[end_position + 1] = '.';
3242 trc_file[end_position + 2] = 't';
3243 trc_file[end_position + 3] = 'r';
3244 trc_file[end_position + 4] = 'c';
3245 trc_file[end_position + 5] = '\0';
3246 }
3247 else {
3248 trc_file[dot_position + 0] = '.';
3249 trc_file[dot_position + 1] = 't';
3250 trc_file[dot_position + 2] = 'r';
3251 trc_file[dot_position + 3] = 'c';
3252 trc_file[dot_position + 4] = '\0';
3253 }
3254
3255 if (file_exists(hex_file)) {
3256 // Clear Registers and Memory
3257
3258 Registers[REGISTER_A] = 0;
3259 Registers[REGISTER_B] = 0;
3260 Registers[REGISTER_C] = 0;
3261 Registers[REGISTER_L] = 0;
3262 Registers[REGISTER_H] = 0;
3263 Index_Registers[REGISTER_X] = 0;
3264 Index_Registers[REGISTER_Y] = 0;
3265 Flags = 0;
3266 ProgramCounter = 0;
3267 StackPointer = 0;
3268
3269 for (i = 0; i < MEMORY_SIZE; i++) {
3270 Memory[i] = 0x00;
3271 }
3272
3273 // Load hex file
3274
3275 if ((ifp = fopen(hex_file, "r")) != NULL) {
3276 printf("Loading file...\n\n");
3277
3278 load_at = 0;
3279
3280 while (getline(ifp, InputBuffer)) {
3281 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
3282 load_at = address;
3283 }
3284 else if (sscanf(InputBuffer, "%x", &code) == 1) {
3285 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
3286 Memory[load_at] = (BYTE)code;
3287 }
3288 load_at++;
3289 }
3290 else {
3291 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
3292 }
3293 }
3294
3295 fclose(ifp);
3296 }
3297
3298 // Emulate
3299
3300 emulate();
3301 }
3302 else {
3303 printf("\n");
3304 printf("ERROR> Input file %s does not exist!\n", hex_file);
3305 printf("\n");
3306 }
3307}
3308
3309void building(int args, _TCHAR** argv) {
3310 char buffer[1024];
3311 load_and_run(args, argv);
3312 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",
3313 Memory[TEST_ADDRESS_1],
3314 Memory[TEST_ADDRESS_2],
3315 Memory[TEST_ADDRESS_3],
3316 Memory[TEST_ADDRESS_4],
3317 Memory[TEST_ADDRESS_5],
3318 Memory[TEST_ADDRESS_6],
3319 Memory[TEST_ADDRESS_7],
3320 Memory[TEST_ADDRESS_8],
3321 Memory[TEST_ADDRESS_9],
3322 Memory[TEST_ADDRESS_10],
3323 Memory[TEST_ADDRESS_11],
3324 Memory[TEST_ADDRESS_12]
3325 );
3326 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
3327}
3328
3329
3330
3331void test_and_mark() {
3332 char buffer[1024];
3333 bool testing_complete;
3334 int len = sizeof(SOCKADDR);
3335 char chr;
3336 int i;
3337 int j;
3338 bool end_of_program;
3339 long address;
3340 long load_at;
3341 int code;
3342 int mark;
3343 int passed;
3344
3345 printf("\n");
3346 printf("Automatic Testing and Marking\n");
3347 printf("\n");
3348
3349 testing_complete = false;
3350
3351 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
3352 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
3353
3354 while (!testing_complete) {
3355 memset(buffer, '\0', sizeof(buffer));
3356
3357 if (recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
3358 printf("Incoming Data: %s \n", buffer);
3359
3360 //if (strcmp(buffer, "Testing complete") == 1)
3361 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
3362 testing_complete = true;
3363 printf("Current mark = %d\n", mark);
3364
3365 }
3366 else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
3367 //testing_complete = true;
3368 printf("Passed = %d\n", passed);
3369
3370 }
3371 else if (strcmp(buffer, "Error") == 0) {
3372 printf("ERROR> Testing abnormally terminated\n");
3373 testing_complete = true;
3374 }
3375 else {
3376 // Clear Registers and Memory
3377
3378 Registers[REGISTER_A] = 0;
3379 Registers[REGISTER_B] = 0;
3380 Registers[REGISTER_C] = 0;
3381 Registers[REGISTER_L] = 0;
3382 Registers[REGISTER_H] = 0;
3383 Index_Registers[REGISTER_X] = 0;
3384 Index_Registers[REGISTER_Y] = 0;
3385 Flags = 0;
3386 ProgramCounter = 0;
3387 StackPointer = 0;
3388 for (i = 0; i < MEMORY_SIZE; i++) {
3389 Memory[i] = 0;
3390 }
3391
3392 // Load hex file
3393
3394 i = 0;
3395 j = 0;
3396 load_at = 0;
3397 end_of_program = false;
3398 FILE *ofp;
3399 fopen_s(&ofp, "branch.txt", "a");
3400
3401 while (!end_of_program) {
3402 chr = buffer[i];
3403 switch (chr) {
3404 case '\0':
3405 end_of_program = true;
3406
3407 case ',':
3408 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
3409 load_at = address;
3410 }
3411 else if (sscanf(InputBuffer, "%x", &code) == 1) {
3412 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
3413 Memory[load_at] = (BYTE)code;
3414 fprintf(ofp, "%02X\n", (BYTE)code);
3415 }
3416 load_at++;
3417 }
3418 else {
3419 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
3420 }
3421 j = 0;
3422 break;
3423
3424 default:
3425 InputBuffer[j] = chr;
3426 j++;
3427 break;
3428 }
3429 i++;
3430 }
3431 fclose(ofp);
3432 // Emulate
3433
3434 if (load_at > 1) {
3435 emulate();
3436 // Send and store results
3437 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
3438 Memory[TEST_ADDRESS_1],
3439 Memory[TEST_ADDRESS_2],
3440 Memory[TEST_ADDRESS_3],
3441 Memory[TEST_ADDRESS_4],
3442 Memory[TEST_ADDRESS_5],
3443 Memory[TEST_ADDRESS_6],
3444 Memory[TEST_ADDRESS_7],
3445 Memory[TEST_ADDRESS_8],
3446 Memory[TEST_ADDRESS_9],
3447 Memory[TEST_ADDRESS_10],
3448 Memory[TEST_ADDRESS_11],
3449 Memory[TEST_ADDRESS_12]
3450 );
3451 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
3452 }
3453 }
3454 }
3455 }
3456}
3457
3458
3459
3460int _tmain(int argc, _TCHAR* argv[])
3461{
3462 char chr;
3463 char dummy;
3464
3465 printf("\n");
3466 printf("Microprocessor Emulator\n");
3467 printf("UWE Computer and Network Systems Assignment 1\n");
3468 printf("\n");
3469
3470 initialise_filenames();
3471
3472 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
3473
3474 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
3475 if (!sock) {
3476 // Creation failed!
3477 }
3478
3479 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
3480 server_addr.sin_family = AF_INET;
3481 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
3482 server_addr.sin_port = htons(PORT_SERVER);
3483
3484 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
3485 client_addr.sin_family = AF_INET;
3486 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
3487 client_addr.sin_port = htons(PORT_CLIENT);
3488
3489 chr = '\0';
3490 while ((chr != 'e') && (chr != 'E'))
3491 {
3492 printf("\n");
3493 printf("Please select option\n");
3494 printf("L - Load and run a hex file\n");
3495 printf("T - Have the server test and mark your emulator\n");
3496 printf("E - Exit\n");
3497 if (argc == 2) { building(argc, argv); exit(0); }
3498 printf("Enter option: ");
3499 chr = getchar();
3500 if (chr != 0x0A)
3501 {
3502 dummy = getchar(); // read in the <CR>
3503 }
3504 printf("\n");
3505
3506 switch (chr)
3507 {
3508 case 'L':
3509 case 'l':
3510 load_and_run(argc, argv);
3511 break;
3512
3513 case 'T':
3514 case 't':
3515 test_and_mark();
3516 break;
3517
3518 default:
3519 break;
3520 }
3521 }
3522
3523 closesocket(sock);
3524 WSACleanup();
3525
3526
3527 return 0;
3528}