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