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