· 7 years ago · Feb 19, 2019, 10:12 AM
1/*
2* Author: Jan Klimaszewski (17026846)
3* Created: 05/02/2019
4* Revised: 20/02/2019
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
395void set_flag_n(BYTE inReg) {
396 BYTE reg;
397 reg = inReg;
398
399 if ((reg & 0x80) != 0) // msbit set
400 {
401 Flags = Flags | FLAG_N;
402 }
403 else
404 {
405 Flags = Flags & (0xFF - FLAG_N);
406 }
407}
408
409void set_flag_z(BYTE inReg) {
410
411 BYTE reg;
412 reg = inReg;
413
414 if (reg == 0) // msbit set
415 {
416 Flags = Flags | FLAG_Z;
417 }
418 else
419 {
420 Flags = Flags & (0xFF - FLAG_Z);
421 }
422}
423
424void Group_1(BYTE opcode) {
425 BYTE LB = 0;
426 BYTE HB = 0;
427 WORD address = 0;
428 WORD data = 0;
429 WORD temp_word = 0;
430
431 switch (opcode) {
432 case 0x43: //LD Immediate
433 data = fetch();
434 Registers[REGISTER_A] = data;
435 set_flag_n((BYTE)Registers[REGISTER_A]);
436 set_flag_z((BYTE)Registers[REGISTER_A]);
437 break;
438
439 case 0x53: //LD Absoulute
440 LB = fetch();
441 HB = fetch();
442 address += (WORD)((WORD)HB << 8) + LB;
443 if (address >= 0 && address < MEMORY_SIZE) {
444 Registers[REGISTER_A] = Memory[address];
445 }
446 set_flag_n((BYTE)Registers[REGISTER_A]);
447 set_flag_z((BYTE)Registers[REGISTER_A]);
448 break;
449
450 case 0x63://LD Absoulte X
451 address += Index_Registers[REGISTER_X];
452 LB = fetch();
453 HB = fetch();
454 address += (WORD)((WORD)HB << 8) + LB;
455 if (address >= 0 && address < MEMORY_SIZE) {
456 Registers[REGISTER_A] = Memory[address];
457 }
458 set_flag_n((BYTE)Registers[REGISTER_A]);
459 set_flag_z((BYTE)Registers[REGISTER_A]);
460 break;
461
462 case 0x73://LD Absoulte Y
463 address += Index_Registers[REGISTER_Y];
464 LB = fetch();
465 HB = fetch();
466 address += (WORD)((WORD)HB << 8) + LB;
467 if (address >= 0 && address < MEMORY_SIZE) {
468 Registers[REGISTER_A] = Memory[address];
469 }
470 set_flag_n((BYTE)Registers[REGISTER_A]);
471 set_flag_z((BYTE)Registers[REGISTER_A]);
472 break;
473
474 case 0x83://LD Absoulte XY
475 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
476 LB = fetch();
477 HB = fetch();
478 address += (WORD)((WORD)HB << 8) + LB;
479 if (address >= 0 && address < MEMORY_SIZE) {
480 Registers[REGISTER_A] = Memory[address];
481 }
482 set_flag_n((BYTE)Registers[REGISTER_A]);
483 set_flag_z((BYTE)Registers[REGISTER_A]);
484 break;
485
486 case 0x93://LD zpg
487 address += 0x0000 | (WORD)fetch();
488 if (address >= 0 && address < MEMORY_SIZE) {
489 Registers[REGISTER_A] = Memory[address];
490 }
491 set_flag_n((BYTE)Registers[REGISTER_A]);
492 set_flag_z((BYTE)Registers[REGISTER_A]);
493 break;
494
495 case 0x04://STO Absolute
496 LB = fetch();
497 HB = fetch();
498 address += (WORD)((WORD)HB << 8) + LB;
499 if (address >= 0 && address < MEMORY_SIZE) {
500 Memory[address] = Registers[REGISTER_A];
501 }
502 set_flag_n((BYTE)Memory[address]);
503 set_flag_z((BYTE)Memory[address]);
504 break;
505
506 case 0x14://STO Absolute X
507 address += Index_Registers[REGISTER_X];
508 LB = fetch();
509 HB = fetch();
510 address += (WORD)((WORD)HB << 8) + LB;
511 if (address >= 0 && address < MEMORY_SIZE) {
512 Memory[address] = Registers[REGISTER_A];
513 }
514 set_flag_n((BYTE)Memory[address]);
515 set_flag_z((BYTE)Memory[address]);
516 break;
517
518 case 0x24: //STO Absolute Y
519 address += Index_Registers[REGISTER_Y];
520 LB = fetch();
521 HB = fetch();
522 address += (WORD)((WORD)HB << 8) + LB;
523 if (address >= 0 && address < MEMORY_SIZE) {
524 Memory[address] = Registers[REGISTER_A];
525 }
526 set_flag_n((BYTE)Memory[address]);
527 set_flag_z((BYTE)Memory[address]);
528 break;
529
530 case 0x34://STO Absolute XY
531 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
532 LB = fetch();
533 HB = fetch();
534 address += (WORD)((WORD)HB << 8) + LB;
535 if (address >= 0 && address < MEMORY_SIZE) {
536 Memory[address] = Registers[REGISTER_A];
537 }
538 set_flag_n((BYTE)Memory[address]);
539 set_flag_z((BYTE)Memory[address]);
540 break;
541
542 case 0x44://STO zpg
543 address += 0x0000 | (WORD)fetch();
544 if (address >= 0 && address < MEMORY_SIZE) {
545 Memory[address] = Registers[REGISTER_A];
546 }
547 set_flag_n((BYTE)Memory[address]);
548 set_flag_z((BYTE)Memory[address]);
549 break;
550
551 case 0x21://LDX Immediate
552 data = fetch();
553 Index_Registers[REGISTER_X] = data;
554 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
555 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
556 break;
557
558 case 0x31: //LDX Absoulute
559 LB = fetch();
560 HB = fetch();
561 address += (WORD)((WORD)HB << 8) + LB;
562 if (address >= 0 && address < MEMORY_SIZE) {
563 Index_Registers[REGISTER_X] = Memory[address];
564 }
565 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
566 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
567 break;
568
569 case 0x41://LDX Absoulte X
570 address += Index_Registers[REGISTER_X];
571 LB = fetch();
572 HB = fetch();
573 address += (WORD)((WORD)HB << 8) + LB;
574 if (address >= 0 && address < MEMORY_SIZE) {
575 Index_Registers[REGISTER_X] = Memory[address];
576 }
577 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
578 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
579 break;
580
581 case 0x51://LDX Absoulte Y
582 address += Index_Registers[REGISTER_Y];
583 LB = fetch();
584 HB = fetch();
585 address += (WORD)((WORD)HB << 8) + LB;
586 if (address >= 0 && address < MEMORY_SIZE) {
587 Index_Registers[REGISTER_X] = Memory[address];
588 }
589 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
590 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
591 break;
592
593 case 0x61://LDX Absoulte XY
594 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
595 LB = fetch();
596 HB = fetch();
597 address += (WORD)((WORD)HB << 8) + LB;
598 if (address >= 0 && address < MEMORY_SIZE) {
599 Index_Registers[REGISTER_X] = Memory[address];
600 }
601 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
602 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
603 break;
604
605 case 0x71://LDX zpg
606 address += 0x0000 | (WORD)fetch();
607 if (address >= 0 && address < MEMORY_SIZE) {
608 Index_Registers[REGISTER_X] = Memory[address];
609 }
610 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
611 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
612 break;
613
614 case 0x22://LODY Immediate
615 data = fetch();
616 Index_Registers[REGISTER_Y] = data;
617 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
618 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
619 break;
620
621 case 0x32: //LODY Absoulute
622 LB = fetch();
623 HB = fetch();
624 address += (WORD)((WORD)HB << 8) + LB;
625 if (address >= 0 && address < MEMORY_SIZE) {
626 Index_Registers[REGISTER_Y] = Memory[address];
627 }
628 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
629 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
630 break;
631
632 case 0x42://LODY Absoulte X
633 address += Index_Registers[REGISTER_X];
634 LB = fetch();
635 HB = fetch();
636 address += (WORD)((WORD)HB << 8) + LB;
637 if (address >= 0 && address < MEMORY_SIZE) {
638 Index_Registers[REGISTER_Y] = Memory[address];
639 }
640 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
641 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
642 break;
643
644 case 0x52://LODY Absoulte Y
645 address += Index_Registers[REGISTER_Y];
646 LB = fetch();
647 HB = fetch();
648 address += (WORD)((WORD)HB << 8) + LB;
649 if (address >= 0 && address < MEMORY_SIZE) {
650 Index_Registers[REGISTER_Y] = Memory[address];
651 }
652 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
653 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
654 break;
655
656 case 0x62://LODY Absoulte XY
657 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
658 LB = fetch();
659 HB = fetch();
660 address += (WORD)((WORD)HB << 8) + LB;
661 if (address >= 0 && address < MEMORY_SIZE) {
662 Index_Registers[REGISTER_Y] = Memory[address];
663 }
664 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
665 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
666 break;
667
668 case 0x72://LODY zpg
669 address += 0x0000 | (WORD)fetch();
670 if (address >= 0 && address < MEMORY_SIZE) {
671 Index_Registers[REGISTER_Y] = Memory[address];
672 }
673 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
674 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
675 break;
676
677 case 0x27://Register B MVR Intermediate
678 data = fetch();
679 Registers[REGISTER_B] = data;
680 set_flag_n((BYTE)Registers[REGISTER_B]);
681 set_flag_z((BYTE)Registers[REGISTER_B]);
682 break;
683
684 case 0x28://Register C MVR Intermediate
685 data = fetch();
686 Registers[REGISTER_C] = data;
687 set_flag_n((BYTE)Registers[REGISTER_C]);
688 set_flag_z((BYTE)Registers[REGISTER_C]);
689 break;
690
691 case 0x29://Register L MVR Intermediate
692 data = fetch();
693 Registers[REGISTER_L] = data;
694 set_flag_n((BYTE)Registers[REGISTER_L]);
695 set_flag_z((BYTE)Registers[REGISTER_L]);
696 break;
697
698 case 0x2A://Register H MVR Intermediate
699 data = fetch();
700 Registers[REGISTER_H] = data;
701 set_flag_n((BYTE)Registers[REGISTER_H]);
702 set_flag_z((BYTE)Registers[REGISTER_H]);
703 break;
704
705 case 0x20://LODS Immediate
706 data = fetch();
707 StackPointer = data;
708 StackPointer += (WORD)fetch() << 8;
709 set_flag_n((BYTE)StackPointer);
710 set_flag_z((BYTE)StackPointer);
711 break;
712
713 case 0x30://LODS Absoulte
714 LB = fetch();
715 HB = fetch();
716 address += (WORD)((WORD)HB << 8) + LB;
717 if (address >= 0 && address < MEMORY_SIZE - 1) {
718 StackPointer = Memory[address];
719 StackPointer += (WORD)Memory[address + 1] << 8;
720 }
721 set_flag_n((BYTE)StackPointer);
722 set_flag_z((BYTE)StackPointer);
723 break;
724
725 case 0x40://LODS Absoulte X
726 address += Index_Registers[REGISTER_X];
727 LB = fetch();
728 HB = fetch();
729 address += (WORD)((WORD)HB << 8) + LB;
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 case 0x50://LODS Absoulte Y
739 address += Index_Registers[REGISTER_Y];
740 LB = fetch();
741 HB = fetch();
742 address += (WORD)((WORD)HB << 8) + LB;
743 if (address >= 0 && address < MEMORY_SIZE - 1) {
744 StackPointer = Memory[address];
745 StackPointer += (WORD)Memory[address + 1] << 8;
746 }
747 set_flag_n((BYTE)StackPointer);
748 set_flag_z((BYTE)StackPointer);
749 break;
750
751 case 0x60://LODS Absolute XY
752 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
753 LB = fetch();
754 HB = fetch();
755 address += (WORD)((WORD)HB << 8) + LB;
756 if (address >= 0 && address < MEMORY_SIZE - 1) {
757 StackPointer = Memory[address];
758 StackPointer += (WORD)Memory[address + 1] << 8;
759 }
760 set_flag_n((BYTE)StackPointer);
761 set_flag_z((BYTE)StackPointer);
762 break;
763
764 case 0x70://LODS zpg
765 address += 0x0000 | (WORD)fetch();
766 if (address >= 0 && address < MEMORY_SIZE - 1) {
767 StackPointer = Memory[address];
768 StackPointer += (WORD)Memory[address + 1] << 8;
769 }
770 set_flag_n((BYTE)StackPointer);
771 set_flag_z((BYTE)StackPointer);
772 break;
773
774 case 0x0F://STOS Absoulte
775 LB = fetch();
776 HB = fetch();
777 address += (WORD)((WORD)HB << 8) + LB;
778 if (address >= 0 && address < MEMORY_SIZE - 1) {
779 HB = (BYTE)(StackPointer >> 8);
780 LB = (BYTE)StackPointer;
781 Memory[address] = LB;
782 Memory[address + 1] = HB;
783 }
784 set_flag_n((BYTE)StackPointer);
785 set_flag_z((BYTE)StackPointer);
786 break;
787
788 case 0x1F://STOS Absoulte X
789 address += Index_Registers[REGISTER_X];
790 LB = fetch();
791 HB = fetch();
792 address += (WORD)((WORD)HB << 8) + LB;
793 if (address >= 0 && address < MEMORY_SIZE - 1) {
794 HB = (BYTE)(StackPointer >> 8);
795 LB = (BYTE)StackPointer;
796 Memory[address] = LB;
797 Memory[address + 1] = HB;
798
799 }
800 set_flag_n((BYTE)StackPointer);
801 set_flag_z((BYTE)StackPointer);
802 break;
803
804 case 0x2F://STOS Absoulte Y
805 address += Index_Registers[REGISTER_Y];
806 LB = fetch();
807 HB = fetch();
808 address += (WORD)((WORD)HB << 8) + LB;
809 if (address >= 0 && address < MEMORY_SIZE - 1) {
810 HB = (BYTE)(StackPointer >> 8);
811 LB = (BYTE)StackPointer;
812 Memory[address] = LB;
813 Memory[address + 1] = HB;
814 }
815 set_flag_n((BYTE)StackPointer);
816 set_flag_z((BYTE)StackPointer);
817 break;
818
819 case 0x3F://STOS Absolute XY
820 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
821 LB = fetch();
822 HB = fetch();
823 address += (WORD)((WORD)HB << 8) + LB;
824 if (address >= 0 && address < MEMORY_SIZE - 1) {
825 HB = (BYTE)(StackPointer >> 8);
826 LB = (BYTE)StackPointer;
827 Memory[address] = LB;
828 Memory[address + 1] = HB;
829 }
830 set_flag_n((BYTE)StackPointer);
831 set_flag_z((BYTE)StackPointer);
832 break;
833
834 case 0x4F://STOS zpg
835 address += 0x0000 | (WORD)fetch();
836 if (address >= 0 && address < MEMORY_SIZE - 1) {
837 HB = (BYTE)(StackPointer >> 8);
838 LB = (BYTE)StackPointer;
839 Memory[address] = LB;
840 Memory[address + 1] = HB;
841 }
842 set_flag_n((BYTE)StackPointer);
843 set_flag_z((BYTE)StackPointer);
844 break;
845
846 case 0x05://STOX Absolute
847 LB = fetch();
848 HB = fetch();
849 address += (WORD)((WORD)HB << 8) + LB;
850 if (address >= 0 && address < MEMORY_SIZE) {
851 Memory[address] = Index_Registers[REGISTER_X];
852 }
853 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
854 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
855 break;
856
857 case 0x15://STOX Absolute X
858 address += Index_Registers[REGISTER_X];
859 LB = fetch();
860 HB = fetch();
861 address += (WORD)((WORD)HB << 8) + LB;
862 if (address >= 0 && address < MEMORY_SIZE) {
863 Memory[address] = Index_Registers[REGISTER_X];
864 }
865 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
866 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
867 break;
868
869 case 0x25: //STOX Absolute Y
870 address += Index_Registers[REGISTER_Y];
871 LB = fetch();
872 HB = fetch();
873 address += (WORD)((WORD)HB << 8) + LB;
874 if (address >= 0 && address < MEMORY_SIZE) {
875 Memory[address] = Index_Registers[REGISTER_X];
876 }
877 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
878 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
879 break;
880
881 case 0x35://STOX Absolute XY
882 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
883 LB = fetch();
884 HB = fetch();
885 address += (WORD)((WORD)HB << 8) + LB;
886 if (address >= 0 && address < MEMORY_SIZE) {
887 Memory[address] = Index_Registers[REGISTER_X];
888 }
889 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
890 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
891 break;
892
893 case 0x45://STOX zpg
894 address += 0x0000 | (WORD)fetch();
895 if (address >= 0 && address < MEMORY_SIZE) {
896 Memory[address] = Index_Registers[REGISTER_X];
897 }
898 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
899 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
900 break;
901
902 case 0x06://STOY Absolute
903 LB = fetch();
904 HB = fetch();
905 address += (WORD)((WORD)HB << 8) + LB;
906 if (address >= 0 && address < MEMORY_SIZE) {
907 Memory[address] = Index_Registers[REGISTER_Y];
908 }
909 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
910 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
911 break;
912
913 case 0x16://STOY Absolute X
914 address += Index_Registers[REGISTER_X];
915 LB = fetch();
916 HB = fetch();
917 address += (WORD)((WORD)HB << 8) + LB;
918 if (address >= 0 && address < MEMORY_SIZE) {
919 Memory[address] = Index_Registers[REGISTER_Y];
920 }
921 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
922 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
923 break;
924
925 case 0x26: //STOY Absolute Y
926 address += Index_Registers[REGISTER_Y];
927 LB = fetch();
928 HB = fetch();
929 address += (WORD)((WORD)HB << 8) + LB;
930 if (address >= 0 && address < MEMORY_SIZE) {
931 Memory[address] = Index_Registers[REGISTER_Y];
932 }
933 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
934 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
935 break;
936
937 case 0x36://STOY Absolute XY
938 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
939 LB = fetch();
940 HB = fetch();
941 address += (WORD)((WORD)HB << 8) + LB;
942 if (address >= 0 && address < MEMORY_SIZE) {
943 Memory[address] = Index_Registers[REGISTER_Y];
944 }
945 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
946 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
947 break;
948
949 case 0x46://STOY zpg
950 address += 0x0000 | (WORD)fetch();
951 if (address >= 0 && address < MEMORY_SIZE) {
952 Memory[address] = Index_Registers[REGISTER_Y];
953 }
954 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
955 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
956 break;
957
958 case 0xB6://ADC A,B
959 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
960 if ((Flags & FLAG_C) != 0)
961 {
962 temp_word++;
963 }
964 if (temp_word >= 0x100)
965 {
966 Flags = Flags | FLAG_C;
967 }
968 else
969 {
970 Flags = Flags & (0xFF - FLAG_C);
971 }
972 set_flag_n((BYTE)temp_word);
973 set_flag_z((BYTE)temp_word);
974 Registers[REGISTER_A] = (BYTE)temp_word;
975 break;
976
977 case 0xC6://ADC A,C
978 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
979 if ((Flags & FLAG_C) != 0)
980 {
981 temp_word++;
982 }
983 if (temp_word >= 0x100)
984 {
985 Flags = Flags | FLAG_C;
986 }
987 else
988 {
989 Flags = Flags & (0xFF - FLAG_C);
990 }
991 set_flag_n((BYTE)temp_word);
992 set_flag_z((BYTE)temp_word);
993 Registers[REGISTER_A] = (BYTE)temp_word;
994 break;
995
996 case 0xD6://ADC A,L
997 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
998 if ((Flags & FLAG_C) != 0)
999 {
1000 temp_word++;
1001 }
1002 if (temp_word >= 0x100)
1003 {
1004 Flags = Flags | FLAG_C;
1005 }
1006 else
1007 {
1008 Flags = Flags & (0xFF - FLAG_C);
1009 }
1010 set_flag_n((BYTE)temp_word);
1011 set_flag_z((BYTE)temp_word);
1012 Registers[REGISTER_A] = (BYTE)temp_word;
1013 break;
1014
1015 case 0xE6://ADC A,H
1016 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
1017 if ((Flags & FLAG_C) != 0)
1018 {
1019 temp_word++;
1020 }
1021 if (temp_word >= 0x100)
1022 {
1023 Flags = Flags | FLAG_C;
1024 }
1025 else
1026 {
1027 Flags = Flags & (0xFF - FLAG_C);
1028 }
1029 set_flag_n((BYTE)temp_word);
1030 set_flag_z((BYTE)temp_word);
1031 Registers[REGISTER_A] = (BYTE)temp_word;
1032 break;
1033
1034 case 0xF6://ADC A,M
1035 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_M];
1036 if ((Flags & FLAG_C) != 0)
1037 {
1038 temp_word++;
1039 }
1040 if (temp_word >= 0x100)
1041 {
1042 Flags = Flags | FLAG_C;
1043 }
1044 else
1045 {
1046 Flags = Flags & (0xFF - FLAG_C);
1047 }
1048 set_flag_n((BYTE)temp_word);
1049 set_flag_z((BYTE)temp_word);
1050 Registers[REGISTER_A] = (BYTE)temp_word;
1051 break;
1052
1053 case 0xB8://ADD A,B
1054 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
1055 if (temp_word >= 0x100)
1056 {
1057 Flags = Flags | FLAG_C;
1058 }
1059 else
1060 {
1061 Flags = Flags & (0xFF - FLAG_C);
1062 }
1063 set_flag_n((BYTE)temp_word);
1064 set_flag_z((BYTE)temp_word);
1065 Registers[REGISTER_A] = (BYTE)temp_word;
1066 break;
1067
1068 case 0xC8://ADD A,C
1069 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
1070 if (temp_word >= 0x100)
1071 {
1072 Flags = Flags | FLAG_C;
1073 }
1074 else
1075 {
1076 Flags = Flags & (0xFF - FLAG_C);
1077 }
1078 set_flag_n((BYTE)temp_word);
1079 set_flag_z((BYTE)temp_word);
1080 Registers[REGISTER_A] = (BYTE)temp_word;
1081 break;
1082
1083 case 0xD8://ADD A,L
1084 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
1085 if (temp_word >= 0x100)
1086 {
1087 Flags = Flags | FLAG_C;
1088 }
1089 else
1090 {
1091 Flags = Flags & (0xFF - FLAG_C);
1092 }
1093 set_flag_n((BYTE)temp_word);
1094 set_flag_z((BYTE)temp_word);
1095 Registers[REGISTER_A] = (BYTE)temp_word;
1096 break;
1097
1098 case 0xE8://ADD A,H
1099 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
1100 if (temp_word >= 0x100)
1101 {
1102 Flags = Flags | FLAG_C;
1103 }
1104 else
1105 {
1106 Flags = Flags & (0xFF - FLAG_C);
1107 }
1108 set_flag_n((BYTE)temp_word);
1109 set_flag_z((BYTE)temp_word);
1110 Registers[REGISTER_A] = (BYTE)temp_word;
1111 break;
1112
1113 case 0xF8://ADD A,M
1114 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_M];
1115 if (temp_word >= 0x100)
1116 {
1117 Flags = Flags | FLAG_C;
1118 }
1119 else
1120 {
1121 Flags = Flags & (0xFF - FLAG_C);
1122 }
1123 set_flag_n((BYTE)temp_word);
1124 set_flag_z((BYTE)temp_word);
1125 Registers[REGISTER_A] = (BYTE)temp_word;
1126 break;
1127
1128 case 0xBA://CMP A,B
1129 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
1130 if (temp_word >= 0x100) {
1131 Flags = Flags | FLAG_C; // Set carry flag
1132 }
1133 else {
1134 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1135 }
1136 set_flag_n((BYTE)temp_word);
1137 set_flag_z((BYTE)temp_word);
1138 break;
1139
1140 case 0xCA://CMP A,C
1141 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
1142 if (temp_word >= 0x100) {
1143 Flags = Flags | FLAG_C; // Set carry flag
1144 }
1145 else {
1146 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1147 }
1148 set_flag_n((BYTE)temp_word);
1149 set_flag_z((BYTE)temp_word);
1150 break;
1151
1152 case 0xDA://CMP A,L
1153 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1154 if (temp_word >= 0x100) {
1155 Flags = Flags | FLAG_C; // Set carry flag
1156 }
1157 else {
1158 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1159 }
1160 set_flag_n((BYTE)temp_word);
1161 set_flag_z((BYTE)temp_word);
1162 break;
1163
1164 case 0xEA://CMP A,H
1165 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1166 if (temp_word >= 0x100)
1167 {
1168 Flags = Flags | FLAG_C; // Set carry flag
1169 }
1170 else
1171 {
1172 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1173 }
1174 set_flag_n((BYTE)temp_word);
1175 set_flag_z((BYTE)temp_word);
1176 break;
1177
1178 case 0xFA://CMP A,M
1179 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
1180 if (temp_word >= 0x100)
1181 {
1182 Flags = Flags | FLAG_C; // Set carry flag
1183 }
1184 else
1185 {
1186 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1187 }
1188 set_flag_n((BYTE)temp_word);
1189 set_flag_z((BYTE)temp_word);
1190 break;
1191
1192 case 0x2D://MSA
1193 Registers[REGISTER_A] = Flags;
1194 break;
1195
1196 case 0x2B://TAY
1197 Index_Registers[REGISTER_Y] = Registers[REGISTER_A];
1198 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
1199 break;
1200
1201 case 0x2C://TYA
1202 Registers[REGISTER_A] = Index_Registers[REGISTER_Y];
1203 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
1204 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
1205 break;
1206
1207 case 0xA6://CLC
1208 Flags = Flags & (0xFF - FLAG_C);
1209 break;
1210
1211 case 0xA7://SEC
1212 Flags = Flags | FLAG_C;
1213 break;
1214
1215 case 0xA8://CLI
1216 Flags = Flags & (0xFF - FLAG_I);
1217 break;
1218
1219 case 0xA9://SEI
1220 Flags = Flags | FLAG_I;
1221 break;
1222
1223 case 0xAA://CMC
1224 Flags = Flags ^ FLAG_C;
1225 break;
1226
1227 case 0xAE://PUSH REGISTER A
1228 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1229 StackPointer--;
1230 Memory[StackPointer] = Registers[REGISTER_A];
1231 }
1232 break;
1233
1234 case 0xBE://PUSH FLAGS
1235 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1236 StackPointer--;
1237 Memory[StackPointer] = Flags;
1238 }
1239 break;
1240
1241 case 0xCE://PUSH REGISTER B
1242 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1243 StackPointer--;
1244 Memory[StackPointer] = Registers[REGISTER_B];
1245 }
1246 break;
1247
1248 case 0xDE://PUSH REGISTER C
1249 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1250 StackPointer--;
1251 Memory[StackPointer] = Registers[REGISTER_C];
1252 }
1253 break;
1254
1255 case 0xEE://PUSH REGISTER L
1256 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1257 StackPointer--;
1258 Memory[StackPointer] = Registers[REGISTER_L];
1259 }
1260 break;
1261
1262 case 0xFE://PUSH REGISTER H
1263 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1264 StackPointer--;
1265 Memory[StackPointer] = Registers[REGISTER_H];
1266 }
1267 break;
1268
1269 case 0xAF://POP REGISTER A
1270 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1271 Registers[REGISTER_A] = Memory[StackPointer];
1272 StackPointer++;
1273 }
1274 break;
1275
1276 case 0xBF://POP FLAGS
1277 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1278 Flags = Memory[StackPointer];
1279 StackPointer++;
1280 }
1281 break;
1282
1283 case 0xCF://POP REGISTER B
1284 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1285 Registers[REGISTER_B] = Memory[StackPointer];
1286 StackPointer++;
1287 }
1288 break;
1289
1290 case 0xDF://POP REGISTER C
1291 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1292 Registers[REGISTER_C] = Memory[StackPointer];
1293 StackPointer++;
1294 }
1295 break;
1296
1297 case 0xEF://POP REGISTER L
1298 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1299 Registers[REGISTER_L] = Memory[StackPointer];
1300 StackPointer++;
1301 }
1302 break;
1303
1304 case 0xFF://POP REGISTER M
1305 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1306 Registers[REGISTER_H] = Memory[StackPointer];
1307 StackPointer++;
1308 }
1309 break;
1310
1311 case 0x38: //JUMP abs
1312 LB = fetch();
1313 HB = fetch();
1314 address = ((WORD)HB << 8) + (WORD)LB;
1315 ProgramCounter = address;
1316 break;
1317
1318 case 0x07://JMPR abs
1319 HB = fetch();
1320 LB = fetch();
1321 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1322 StackPointer--;
1323 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1324 StackPointer--;
1325 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1326 ProgramCounter = address;
1327 }
1328 break;
1329
1330 case 0x23: //RT impl
1331 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
1332 LB = Memory[StackPointer];
1333 StackPointer++;
1334 HB = Memory[StackPointer];
1335 StackPointer++;
1336 ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
1337 }
1338 break;
1339
1340 case 0x39://JCC
1341 LB = fetch();
1342 HB = fetch();
1343 address = ((WORD)HB << 8) + (WORD)LB;
1344 if ((Flags & FLAG_C) == 0)
1345 {
1346 ProgramCounter = address;
1347 }
1348 break;
1349
1350 case 0x3A://JCS
1351 LB = fetch();
1352 HB = fetch();
1353 address = ((WORD)HB << 8) + (WORD)LB;
1354 if ((Flags & FLAG_C) == FLAG_C)
1355 {
1356 ProgramCounter = address;
1357 }
1358 break;
1359
1360 case 0x3B://JNE abs
1361 LB = fetch();
1362 HB = fetch();
1363 address = ((WORD)HB << 8) + (WORD)LB;
1364 if ((Flags & FLAG_Z) == 0)
1365 {
1366 ProgramCounter = address;
1367 }
1368 break;
1369
1370 case 0x3C://JEQ
1371 LB = fetch();
1372 HB = fetch();
1373 address = ((WORD)HB << 8) + (WORD)LB;
1374 if ((Flags & FLAG_Z) == FLAG_Z)
1375 {
1376 ProgramCounter = address;
1377 }
1378 break;
1379
1380 case 0x3D://JMI abs
1381 LB = fetch();
1382 HB = fetch();
1383 address = ((WORD)HB << 8) + (WORD)LB;
1384 if ((Flags & FLAG_N) == FLAG_N)
1385 {
1386 ProgramCounter = address;
1387 }
1388 break;
1389
1390 case 0x3E://JPL abs
1391 LB = fetch();
1392 HB = fetch();
1393 address = ((WORD)HB << 8) + (WORD)LB;
1394 if ((Flags & FLAG_N) == 0)
1395 {
1396 ProgramCounter = address;
1397 }
1398 break;
1399
1400 case 0x08: //CCC abs
1401 LB = fetch();
1402 HB = fetch();
1403 address = ((WORD)HB << 8) + (WORD)LB;
1404 if ((Flags & FLAG_C) == 0)
1405 {
1406 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1407 StackPointer--;
1408 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1409 StackPointer--;
1410 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1411 ProgramCounter = address;
1412 }
1413 }
1414 break;
1415
1416 case 0x09:// CCS abs
1417 LB = fetch();
1418 HB = fetch();
1419 address = ((WORD)HB << 8) + (WORD)LB;
1420 if ((Flags & FLAG_C) == FLAG_C)
1421 {
1422 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1423 StackPointer--;
1424 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1425 StackPointer--;
1426 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1427 ProgramCounter = address;
1428 }
1429 }
1430 break;
1431
1432 case 0x0A: //CNE abs
1433 LB = fetch();
1434 HB = fetch();
1435 address = ((WORD)HB << 8) + (WORD)LB;
1436 if ((Flags & FLAG_Z) == 0)
1437 {
1438 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1439 StackPointer--;
1440 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1441 StackPointer--;
1442 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1443 ProgramCounter = address;
1444 }
1445 }
1446 break;
1447
1448 case 0x0B:// CEQ abs
1449 LB = fetch();
1450 HB = fetch();
1451 address = ((WORD)HB << 8) + (WORD)LB;
1452 if ((Flags & FLAG_Z) == FLAG_Z)
1453 {
1454 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1455 StackPointer--;
1456 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1457 StackPointer--;
1458 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1459 ProgramCounter = address;
1460 }
1461 }
1462 break;
1463
1464 case 0x0C: //CMI abs
1465 LB = fetch();
1466 HB = fetch();
1467 address = ((WORD)HB << 8) + (WORD)LB;
1468 if ((Flags & FLAG_N) == FLAG_N)
1469 {
1470 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1471 StackPointer--;
1472 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1473 StackPointer--;
1474 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1475 ProgramCounter = address;
1476 }
1477 }
1478 break;
1479
1480 case 0x0D: // CPL abs
1481 LB = fetch();
1482 HB = fetch();
1483 address = ((WORD)HB << 8) + (WORD)LB;
1484 if ((Flags & FLAG_N) == 0)
1485 {
1486 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1487 StackPointer--;
1488 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1489 StackPointer--;
1490 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1491 ProgramCounter = address;
1492 }
1493 }
1494 break;
1495
1496 case 0x95: //INCA
1497 ++Registers[REGISTER_A];
1498 set_flag_n(Registers[REGISTER_A]);
1499 set_flag_z(Registers[REGISTER_A]);
1500 break;
1501
1502 case 0xBC: // AND Register A,B
1503 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_B];
1504 set_flag_n((BYTE)temp_word);
1505 set_flag_z((BYTE)temp_word);
1506 Registers[REGISTER_A] = (BYTE)temp_word;
1507 break;
1508
1509 case 0xCC: // AND Register A,C
1510 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_C];
1511 set_flag_n((BYTE)temp_word);
1512 set_flag_z((BYTE)temp_word);
1513 Registers[REGISTER_A] = (BYTE)temp_word;
1514 break;
1515
1516 case 0xDC: // AND Register A,L
1517 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_L];
1518 set_flag_n((BYTE)temp_word);
1519 set_flag_z((BYTE)temp_word);
1520 Registers[REGISTER_A] = (BYTE)temp_word;
1521 break;
1522
1523 case 0xEC: // AND Register A,H
1524 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_H];
1525 set_flag_n((BYTE)temp_word);
1526 set_flag_z((BYTE)temp_word);
1527 Registers[REGISTER_A] = (BYTE)temp_word;
1528 break;
1529
1530 case 0xFC: // AND Register A,M
1531 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_M];
1532 set_flag_n((BYTE)temp_word);
1533 set_flag_z((BYTE)temp_word);
1534 Registers[REGISTER_A] = (BYTE)temp_word;
1535 break;
1536
1537 case 0x9F: //CLRA
1538 Registers[REGISTER_A] = 0;
1539 Flags = Flags | FLAG_Z;
1540 Flags = Flags & (0xFF - FLAG_N);
1541 Flags = Flags & (0xFF - FLAG_C);
1542 break;
1543
1544 case 0x55: // INC abs
1545 LB = fetch();
1546 HB = fetch();
1547 address += (WORD)((WORD)HB << 8) + LB;
1548 ++Memory[address];
1549 set_flag_n(Memory[address]);
1550 set_flag_z(Memory[address]);
1551 break;
1552
1553 case 0x65: // INC abs X
1554 address += Index_Registers[REGISTER_X];
1555 LB = fetch();
1556 HB = fetch();
1557 address += (WORD)((WORD)HB << 8) + LB;
1558 if (address >= 0 && address < MEMORY_SIZE)
1559 {
1560 ++Memory[address];
1561 }
1562 set_flag_n(Memory[address]);
1563 set_flag_z(Memory[address]);
1564 break;
1565
1566 case 0x75: // INC abs Y
1567 address += Index_Registers[REGISTER_Y];
1568 LB = fetch();
1569 HB = fetch();
1570 address += (WORD)((WORD)HB << 8) + LB;
1571 if (address >= 0 && address < MEMORY_SIZE)
1572 {
1573 ++Memory[address];
1574 }
1575 set_flag_n(Memory[address]);
1576 set_flag_z(Memory[address]);
1577 break;
1578
1579 case 0x85: // INC abs XY
1580 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1581 LB = fetch();
1582 HB = fetch();
1583 address += (WORD)((WORD)HB << 8) + LB;
1584 if (address >= 0 && address < MEMORY_SIZE)
1585 {
1586 ++Memory[address];
1587 }
1588 set_flag_n(Memory[address]);
1589 set_flag_z(Memory[address]);
1590 break;
1591
1592 case 0x5F: // CLR abs
1593 LB = fetch();
1594 HB = fetch();
1595 address += (WORD)((WORD)HB << 8) + LB;
1596 Memory[address] = 0;
1597 Flags = Flags | FLAG_Z;
1598 Flags = Flags & (0xFF - FLAG_N);
1599 Flags = Flags & (0xFF - FLAG_C);
1600 break;
1601
1602 case 0x6F: // CLR abs X
1603 address += Index_Registers[REGISTER_X];
1604 LB = fetch();
1605 HB = fetch();
1606 address += (WORD)((WORD)HB << 8) + LB;
1607 Memory[address] = 0;
1608 Flags = Flags | FLAG_Z;
1609 Flags = Flags & (0xFF - FLAG_N);
1610 Flags = Flags & (0xFF - FLAG_C);
1611 break;
1612
1613 case 0x7F: // CLR abs Y
1614 address += Index_Registers[REGISTER_Y];
1615 LB = fetch();
1616 HB = fetch();
1617 address += (WORD)((WORD)HB << 8) + LB;
1618 Memory[address] = 0;
1619 Flags = Flags | FLAG_Z;
1620 Flags = Flags & (0xFF - FLAG_N);
1621 Flags = Flags & (0xFF - FLAG_C);
1622 break;
1623
1624 case 0x8F: // CLR abs XY
1625 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1626 LB = fetch();
1627 HB = fetch();
1628 address += (WORD)((WORD)HB << 8) + LB;
1629 Memory[address] = 0;
1630 Flags = Flags | FLAG_Z;
1631 Flags = Flags & (0xFF - FLAG_N);
1632 Flags = Flags & (0xFF - FLAG_C);
1633 break;
1634
1635 case 0x4A: // DEX imply
1636 Index_Registers[REGISTER_X]--;
1637 set_flag_z(Index_Registers[REGISTER_X]);
1638 break;
1639
1640 case 0x4B: //INX impl
1641 ++Index_Registers[REGISTER_X];
1642 set_flag_z(Index_Registers[REGISTER_X]);
1643 break;
1644
1645 case 0x4C: //DEY impl
1646 Index_Registers[REGISTER_Y]--;
1647 set_flag_z(Index_Registers[REGISTER_Y]);
1648 break;
1649
1650 case 0x4D: //INY impl
1651 ++Index_Registers[REGISTER_Y];
1652 set_flag_z(Index_Registers[REGISTER_Y]);
1653 break;
1654
1655 case 0xB7: //SBC A,B
1656 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
1657 if ((Flags & FLAG_C) != 0)
1658 {
1659 temp_word--;
1660 }
1661 if (temp_word >= 0x100)
1662 {
1663 Flags = Flags | FLAG_C;
1664 }
1665 else
1666 {
1667 Flags = Flags & (0xFF - FLAG_C);
1668 }
1669 set_flag_n((BYTE)temp_word);
1670 set_flag_z((BYTE)temp_word);
1671 Registers[REGISTER_A] = (BYTE)temp_word;
1672 break;
1673
1674 case 0xC7: //SBC A,C
1675 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
1676 if ((Flags & FLAG_C) != 0)
1677 {
1678 temp_word--;
1679 }
1680 if (temp_word >= 0x100)
1681 {
1682 Flags = Flags | FLAG_C;
1683 }
1684 else
1685 {
1686 Flags = Flags & (0xFF - FLAG_C);
1687 }
1688 set_flag_n((BYTE)temp_word);
1689 set_flag_z((BYTE)temp_word);
1690 Registers[REGISTER_A] = (BYTE)temp_word;
1691 break;
1692
1693 case 0xD7: //SBC A,L
1694 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1695 if ((Flags & FLAG_C) != 0)
1696 {
1697 temp_word--;
1698 }
1699 if (temp_word >= 0x100)
1700 {
1701 Flags = Flags | FLAG_C;
1702 }
1703 else
1704 {
1705 Flags = Flags & (0xFF - FLAG_C);
1706 }
1707 set_flag_n((BYTE)temp_word);
1708 set_flag_z((BYTE)temp_word);
1709 Registers[REGISTER_A] = (BYTE)temp_word;
1710 break;
1711
1712 case 0xE7: //SBC A,H
1713 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1714 if ((Flags & FLAG_C) != 0)
1715 {
1716 temp_word--;
1717 }
1718 if (temp_word >= 0x100)
1719 {
1720 Flags = Flags | FLAG_C;
1721 }
1722 else
1723 {
1724 Flags = Flags & (0xFF - FLAG_C);
1725 }
1726 set_flag_n((BYTE)temp_word);
1727 set_flag_z((BYTE)temp_word);
1728 Registers[REGISTER_A] = (BYTE)temp_word;
1729 break;
1730
1731 case 0xF7: //SBC A,M
1732 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
1733 if ((Flags & FLAG_C) != 0)
1734 {
1735 temp_word--;
1736 }
1737 if (temp_word >= 0x100)
1738 {
1739 Flags = Flags | FLAG_C;
1740 }
1741 else
1742 {
1743 Flags = Flags & (0xFF - FLAG_C);
1744 }
1745 set_flag_n((BYTE)temp_word);
1746 set_flag_z((BYTE)temp_word);
1747 Registers[REGISTER_A] = (BYTE)temp_word;
1748 break;
1749
1750 case 0xBB: //OR A,B
1751 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_B];
1752 set_flag_n((BYTE)temp_word);
1753 set_flag_z((BYTE)temp_word);
1754 Registers[REGISTER_A] = (BYTE)temp_word;
1755 break;
1756
1757 case 0xCB: //OR A,C
1758 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_C];
1759 set_flag_n((BYTE)temp_word);
1760 set_flag_z((BYTE)temp_word);
1761 Registers[REGISTER_A] = (BYTE)temp_word;
1762 break;
1763
1764 case 0xDB: //OR A,L
1765 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_L];
1766 set_flag_n((BYTE)temp_word);
1767 set_flag_z((BYTE)temp_word);
1768 Registers[REGISTER_A] = (BYTE)temp_word;
1769 break;
1770
1771 case 0xEB: //OR A,H
1772 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_H];
1773 set_flag_n((BYTE)temp_word);
1774 set_flag_z((BYTE)temp_word);
1775 Registers[REGISTER_A] = (BYTE)temp_word;
1776 break;
1777
1778 case 0xFB: //OR A,M
1779 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_M];
1780 set_flag_n((BYTE)temp_word);
1781 set_flag_z((BYTE)temp_word);
1782 Registers[REGISTER_A] = (BYTE)temp_word;
1783 break;
1784
1785 case 0x9B: //COMA
1786 break;
1787
1788 case 0xB9: //SUB A,B
1789 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
1790 if (temp_word >= 0x100)
1791 {
1792 Flags = Flags | FLAG_C;
1793 }
1794 else
1795 {
1796 Flags = Flags & (0xFF - FLAG_C);
1797 }
1798 set_flag_n((BYTE)temp_word);
1799 set_flag_z((BYTE)temp_word);
1800 Registers[REGISTER_A] = (BYTE)temp_word;
1801 break;
1802
1803 case 0xC9: //SUB A,C
1804 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
1805 if (temp_word >= 0x100)
1806 {
1807 Flags = Flags | FLAG_C;
1808 }
1809 else
1810 {
1811 Flags = Flags & (0xFF - FLAG_C);
1812 }
1813 set_flag_n((BYTE)temp_word);
1814 set_flag_z((BYTE)temp_word);
1815 Registers[REGISTER_A] = (BYTE)temp_word;
1816 break;
1817
1818 case 0xD9: //SUB A,L
1819 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1820 if (temp_word >= 0x100)
1821 {
1822 Flags = Flags | FLAG_C;
1823 }
1824 else
1825 {
1826 Flags = Flags & (0xFF - FLAG_C);
1827 }
1828 set_flag_n((BYTE)temp_word);
1829 set_flag_z((BYTE)temp_word);
1830 Registers[REGISTER_A] = (BYTE)temp_word;
1831 break;
1832
1833 case 0xE9: //SUB A,H
1834 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1835 if (temp_word >= 0x100)
1836 {
1837 Flags = Flags | FLAG_C;
1838 }
1839 else
1840 {
1841 Flags = Flags & (0xFF - FLAG_C);
1842 }
1843 set_flag_n((BYTE)temp_word);
1844 set_flag_z((BYTE)temp_word);
1845 Registers[REGISTER_A] = (BYTE)temp_word;
1846 break;
1847
1848 case 0xF9: //SUB A,C
1849 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
1850 if (temp_word >= 0x100)
1851 {
1852 Flags = Flags | FLAG_C;
1853 }
1854 else
1855 {
1856 Flags = Flags & (0xFF - FLAG_C);
1857 }
1858 set_flag_n((BYTE)temp_word);
1859 set_flag_z((BYTE)temp_word);
1860 Registers[REGISTER_A] = (BYTE)temp_word;
1861 break;
1862
1863 case 0xBD: //XOR A,B
1864 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_B];
1865 set_flag_n((BYTE)temp_word);
1866 set_flag_z((BYTE)temp_word);
1867 Registers[REGISTER_A] = (BYTE)temp_word;
1868 break;
1869
1870 case 0xCD: //XOR A,C
1871 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_C];
1872 set_flag_n((BYTE)temp_word);
1873 set_flag_z((BYTE)temp_word);
1874 Registers[REGISTER_A] = (BYTE)temp_word;
1875 break;
1876
1877 case 0xDD: //XOR A,L
1878 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_L];
1879 set_flag_n((BYTE)temp_word);
1880 set_flag_z((BYTE)temp_word);
1881 Registers[REGISTER_A] = (BYTE)temp_word;
1882 break;
1883
1884 case 0xED: //XOR A,H
1885 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_H];
1886 set_flag_n((BYTE)temp_word);
1887 set_flag_z((BYTE)temp_word);
1888 Registers[REGISTER_A] = (BYTE)temp_word;
1889 break;
1890
1891 case 0xFD: //XOR A,M
1892 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_M];
1893 set_flag_n((BYTE)temp_word);
1894 set_flag_z((BYTE)temp_word);
1895 Registers[REGISTER_A] = (BYTE)temp_word;
1896 break;
1897
1898 case 0x54: //TEST Absolute
1899 break;
1900
1901 case 0x64: //TEST Absolute X
1902 break;
1903
1904 case 0x74: //TEST Absolute Y
1905 break;
1906
1907 case 0x84: //TEST Absolute X,Y
1908 break;
1909
1910 case 0x56: //DEC Absolute
1911 LB = fetch();
1912 HB = fetch();
1913 address += (WORD)((WORD)HB << 8) + LB;
1914 Memory[address]--;
1915 set_flag_n(Memory[address]);
1916 set_flag_z(Memory[address]);
1917 break;
1918
1919 case 0x66: //DEC Absolute X
1920 address += Index_Registers[REGISTER_X];
1921 LB = fetch();
1922 HB = fetch();
1923 address += (WORD)((WORD)HB << 8) + LB;
1924 if (address >= 0 && address < MEMORY_SIZE)
1925 {
1926 Memory[address]--;
1927 }
1928 set_flag_n(Memory[address]);
1929 set_flag_z(Memory[address]);
1930 break;
1931
1932 case 0x76: //DEC Absolute Y
1933 address += Index_Registers[REGISTER_Y];
1934 LB = fetch();
1935 HB = fetch();
1936 address += (WORD)((WORD)HB << 8) + LB;
1937 if (address >= 0 && address < MEMORY_SIZE)
1938 {
1939 Memory[address]--;
1940 }
1941 set_flag_n(Memory[address]);
1942 set_flag_z(Memory[address]);
1943 break;
1944
1945 case 0x86: //DEC Absolute X,Y
1946 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1947 LB = fetch();
1948 HB = fetch();
1949 address += (WORD)((WORD)HB << 8) + LB;
1950 if (address >= 0 && address < MEMORY_SIZE)
1951 {
1952 Memory[address]--;
1953 }
1954 set_flag_n(Memory[address]);
1955 set_flag_z(Memory[address]);
1956 break;
1957
1958 case 0x59: //SAL Absolute
1959
1960 break;
1961
1962 case 0x69: //SAL Absolute X
1963
1964 break;
1965
1966 case 0x79: //SAL Absolute Y
1967
1968 break;
1969
1970 case 0x89: //SAL Absolute X,Y
1971
1972 break;
1973
1974 case 0x5A: //SHR Absolute
1975
1976 break;
1977
1978 case 0x6A: //SHR Absolute X
1979
1980 break;
1981
1982 case 0x7A: //SHR Absolute Y
1983
1984 break;
1985
1986 case 0x8A: //SHR Absolute X,Y
1987
1988 break;
1989
1990 case 0x5C: //NEG Absolute
1991
1992 break;
1993
1994 case 0x6C: //NEG Absolute X
1995
1996 break;
1997
1998 case 0x7C: //NEG Absolute Y
1999
2000 break;
2001
2002 case 0x8C: //NEG Absolute X,Y
2003
2004 break;
2005
2006 case 0x02: //SWI
2007
2008 break;
2009
2010 case 0x03: //RTI
2011
2012 break;
2013
2014 case 0x98: //RCLA
2015
2016 break;
2017
2018 case 0x99: //SALA
2019
2020 break;
2021
2022 case 0x9A: //SHRA
2023
2024 break;
2025 case 0x17: //NOP
2026 break;
2027
2028 case 0x18: //WAI
2029 halt = true;
2030 break;
2031 case 0x1C: //ADI Immediate
2032
2033 break;
2034 case 0x1D: //CPI Immediate
2035
2036 break;
2037 case 0x1E: //ANI Immediate
2038
2039 break;
2040 case 0x94: //TESTA Register A
2041
2042 break;
2043 case 0x96: //DECA Register A
2044
2045 break;
2046 case 0x57: //RR Absolute
2047
2048 break;
2049 case 0x67: //RR Absolute X
2050
2051 break;
2052 case 0x77: //RR Absolute Y
2053
2054 break;
2055 case 0x87: //RR Absolute X,Y
2056
2057 break;
2058 case 0x97: //RRA Register A
2059
2060 break;
2061 case 0x58: //RCL Absolute
2062
2063 break;
2064 case 0x68: //RCL Absolute X
2065
2066 break;
2067 case 0x78: //RCL Absolute Y
2068
2069 break;
2070 case 0x88: //RCL Absolute X,Y
2071
2072 break;
2073 case 0x5B: //COM Absolute
2074
2075 break;
2076 case 0x6B: //COM Absolute X
2077
2078 break;
2079 case 0x7B: //COM Absolute Y
2080
2081 break;
2082 case 0x8B: //COM Absolute X,Y
2083
2084 break;
2085 case 0x9C: //NEGA Register A
2086
2087 break;
2088 case 0x5D: //RAL Absolute
2089
2090 break;
2091 case 0x6D: //RAL Absolute X
2092
2093 break;
2094 case 0x7D: //RAL Absolute Y
2095
2096 break;
2097 case 0x8D: //RAL Absolute X,Y
2098
2099 break;
2100 case 0x9D: //RALA Register A
2101
2102 break;
2103 case 0x5E: //ROR Absolute
2104
2105 break;
2106 case 0x6E: //ROR Absolute X
2107
2108 break;
2109 case 0x7E: //ROR Absolute Y
2110
2111 break;
2112 case 0x8E: //ROR Absolute X,Y
2113
2114 break;
2115 case 0x9E: //RORA Register A
2116
2117 break;
2118 }
2119}
2120
2121void Group_2_Move(BYTE opcode) {
2122
2123 BYTE source = opcode >> 4;
2124 BYTE destination = opcode & 0x0F;
2125 WORD address = 0;
2126
2127 int destReg = 0;
2128 int sourceReg = 0;
2129
2130 switch (destination)
2131 {
2132 case 0x00:
2133 destReg = REGISTER_A;
2134 break;
2135
2136 case 0x01:
2137 destReg = REGISTER_B;
2138 break;
2139
2140 case 0x02:
2141 destReg = REGISTER_C;
2142 break;
2143
2144 case 0x03:
2145 destReg = REGISTER_L;
2146 break;
2147
2148 case 0x04:
2149 destReg = REGISTER_H;
2150 break;
2151
2152 case 0x05:
2153 destReg = REGISTER_M;
2154 break;
2155
2156 case 0xA0:
2157 destReg = REGISTER_A;
2158 break;
2159
2160 case 0xB0:
2161 destReg = REGISTER_A;
2162 break;
2163
2164 case 0xC0:
2165 destReg = REGISTER_A;
2166 break;
2167
2168 case 0xD0:
2169 destReg = REGISTER_A;
2170 break;
2171
2172 case 0xE0:
2173 destReg = REGISTER_A;
2174 break;
2175
2176 case 0xF0:
2177 destReg = REGISTER_A;
2178 break;
2179
2180 case 0xA1:
2181 destReg = REGISTER_B;
2182 break;
2183
2184 case 0xB1:
2185 destReg = REGISTER_B;
2186 break;
2187
2188 case 0xC1:
2189 destReg = REGISTER_B;
2190 break;
2191
2192 case 0xD1:
2193 destReg = REGISTER_B;
2194 break;
2195
2196 case 0xE1:
2197 destReg = REGISTER_B;
2198 break;
2199
2200 case 0xF1:
2201 destReg = REGISTER_B;
2202 break;
2203
2204 case 0xA2:
2205 destReg = REGISTER_C;
2206 break;
2207
2208 case 0xB2:
2209 destReg = REGISTER_C;
2210 break;
2211
2212 case 0xC2:
2213 destReg = REGISTER_C;
2214 break;
2215
2216 case 0xD2:
2217 destReg = REGISTER_C;
2218 break;
2219
2220 case 0xE2:
2221 destReg = REGISTER_C;
2222 break;
2223
2224 case 0xF2:
2225 destReg = REGISTER_C;
2226 break;
2227
2228 case 0xA3:
2229 destReg = REGISTER_L;
2230 break;
2231
2232 case 0xB3:
2233 destReg = REGISTER_L;
2234 break;
2235
2236 case 0xC3:
2237 destReg = REGISTER_L;
2238 break;
2239
2240 case 0xD3:
2241 destReg = REGISTER_L;
2242 break;
2243
2244 case 0xE3:
2245 destReg = REGISTER_L;
2246 break;
2247
2248 case 0xF3:
2249 destReg = REGISTER_L;
2250 break;
2251
2252 case 0xA4:
2253 destReg = REGISTER_H;
2254 break;
2255
2256 case 0xB4:
2257 destReg = REGISTER_H;
2258 break;
2259
2260 case 0xC4:
2261 destReg = REGISTER_H;
2262 break;
2263
2264 case 0xD4:
2265 destReg = REGISTER_H;
2266 break;
2267
2268 case 0xE4:
2269 destReg = REGISTER_H;
2270 break;
2271
2272 case 0xF4:
2273 destReg = REGISTER_H;
2274 break;
2275
2276 case 0xA5:
2277 destReg = REGISTER_M;
2278 break;
2279
2280 case 0xB5:
2281 destReg = REGISTER_M;
2282 break;
2283
2284 case 0xC5:
2285 destReg = REGISTER_M;
2286 break;
2287
2288 case 0xD5:
2289 destReg = REGISTER_M;
2290 break;
2291
2292 case 0xE5:
2293 destReg = REGISTER_M;
2294 break;
2295 }
2296
2297 switch (source)
2298 {
2299 case 0xA0:
2300 sourceReg = REGISTER_A;
2301 break;
2302
2303 case 0xA1:
2304 sourceReg = REGISTER_A;
2305 break;
2306
2307 case 0xA2:
2308 sourceReg = REGISTER_A;
2309 break;
2310
2311 case 0xA3:
2312 sourceReg = REGISTER_A;
2313 break;
2314
2315 case 0xA4:
2316 sourceReg = REGISTER_A;
2317 break;
2318
2319 case 0xA5:
2320 sourceReg = REGISTER_A;
2321 break;
2322
2323 case 0xB0:
2324 sourceReg = REGISTER_B;
2325 break;
2326
2327 case 0xB1:
2328 sourceReg = REGISTER_B;
2329 break;
2330
2331 case 0xB2:
2332 sourceReg = REGISTER_B;
2333 break;
2334
2335 case 0xB3:
2336 sourceReg = REGISTER_B;
2337 break;
2338
2339 case 0xB4:
2340 sourceReg = REGISTER_B;
2341 break;
2342
2343 case 0xB5:
2344 sourceReg = REGISTER_B;
2345 break;
2346
2347 case 0xC0:
2348 sourceReg = REGISTER_C;
2349 break;
2350
2351 case 0xC1:
2352 sourceReg = REGISTER_C;
2353 break;
2354
2355 case 0xC2:
2356 sourceReg = REGISTER_C;
2357 break;
2358
2359 case 0xC3:
2360 sourceReg = REGISTER_C;
2361 break;
2362
2363 case 0xC4:
2364 sourceReg = REGISTER_C;
2365 break;
2366
2367 case 0xC5:
2368 sourceReg = REGISTER_C;
2369 break;
2370
2371 case 0xD0:
2372 sourceReg = REGISTER_L;
2373 break;
2374
2375 case 0xD1:
2376 sourceReg = REGISTER_L;
2377 break;
2378
2379 case 0xD2:
2380 sourceReg = REGISTER_L;
2381 break;
2382
2383 case 0xD3:
2384 sourceReg = REGISTER_L;
2385 break;
2386
2387 case 0xD4:
2388 sourceReg = REGISTER_L;
2389 break;
2390
2391 case 0xD5:
2392 sourceReg = REGISTER_L;
2393 break;
2394
2395 case 0xE0:
2396 sourceReg = REGISTER_H;
2397 break;
2398
2399 case 0xE1:
2400 sourceReg = REGISTER_H;
2401 break;
2402
2403 case 0xE2:
2404 sourceReg = REGISTER_H;
2405 break;
2406
2407 case 0xE3:
2408 sourceReg = REGISTER_H;
2409 break;
2410
2411 case 0xE4:
2412 sourceReg = REGISTER_H;
2413 break;
2414
2415 case 0xE5:
2416 sourceReg = REGISTER_H;
2417 break;
2418
2419 case 0xF0:
2420 sourceReg = REGISTER_M;
2421 break;
2422
2423 case 0xF1:
2424 sourceReg = REGISTER_M;
2425 break;
2426
2427 case 0xF2:
2428 sourceReg = REGISTER_M;
2429 break;
2430
2431 case 0xF3:
2432 sourceReg = REGISTER_M;
2433 break;
2434
2435 case 0xF4:
2436 sourceReg = REGISTER_M;
2437 break;
2438
2439 case 0x0A:
2440 sourceReg = REGISTER_A;
2441 break;
2442
2443 case 0x0B:
2444 sourceReg = REGISTER_B;
2445 break;
2446
2447 case 0x0C:
2448 sourceReg = REGISTER_C;
2449 break;
2450
2451 case 0x0D:
2452 sourceReg = REGISTER_L;
2453 break;
2454
2455 case 0x0E:
2456 sourceReg = REGISTER_H;
2457 break;
2458
2459 case 0x0F:
2460 sourceReg = REGISTER_M;
2461 break;
2462 }
2463
2464 if (sourceReg == REGISTER_M) {
2465
2466 address = Registers[REGISTER_L];
2467 address += (WORD)Registers[REGISTER_H] << 8;
2468
2469 if (address >= 0 && address <= MEMORY_SIZE) {
2470
2471 Registers[REGISTER_M] = Memory[address];
2472
2473 }
2474 }
2475
2476 if (destReg == REGISTER_M) {
2477
2478 address = Registers[REGISTER_L];
2479 address += (WORD)Registers[REGISTER_H] << 8;
2480
2481 if (address >= 0 && address <= MEMORY_SIZE) {
2482
2483 Memory[address] = Registers[sourceReg];
2484
2485 }
2486 }
2487 else {
2488 Registers[destReg] = Registers[sourceReg];
2489 }
2490}
2491
2492void execute(BYTE opcode)
2493{
2494
2495 BYTE source = opcode >> 4;
2496 BYTE destination = opcode & 0x0F;
2497
2498 if (((source >= 0x0A) && (source <= 0xF5)) && ((destination >= 0x00) && (destination <= 0x05))) {
2499 Group_2_Move(opcode);
2500 }
2501 else
2502 {
2503 Group_1(opcode);
2504 }
2505}
2506
2507void emulate()
2508{
2509 BYTE opcode;
2510 int sanity;
2511
2512 ProgramCounter = 0;
2513 halt = false;
2514 memory_in_range = true;
2515 sanity = 0;
2516
2517 printf(" A B C L H X Y SP\n");
2518
2519 while ((!halt) && (memory_in_range)) {
2520 printf("%04X ", ProgramCounter); // Print current address
2521 opcode = fetch();
2522 execute(opcode);
2523
2524 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
2525
2526 printf("%02X ", Registers[REGISTER_A]);
2527 printf("%02X ", Registers[REGISTER_B]);
2528 printf("%02X ", Registers[REGISTER_C]);
2529 printf("%02X ", Registers[REGISTER_L]);
2530 printf("%02X ", Registers[REGISTER_H]);
2531 printf("%02X ", Index_Registers[REGISTER_X]);
2532 printf("%02X ", Index_Registers[REGISTER_Y]);
2533 printf("%04X ", StackPointer); // Print Stack Pointer
2534
2535 if ((Flags & FLAG_Z) == FLAG_Z)
2536 {
2537 printf("Z=1 ");
2538 }
2539 else
2540 {
2541 printf("Z=0 ");
2542 }
2543 if ((Flags & FLAG_I) == FLAG_I)
2544 {
2545 printf("I=1 ");
2546 }
2547 else
2548 {
2549 printf("I=0 ");
2550 }
2551 if ((Flags & FLAG_N) == FLAG_N)
2552 {
2553 printf("N=1 ");
2554 }
2555 else
2556 {
2557 printf("N=0 ");
2558 }
2559 if ((Flags & FLAG_C) == FLAG_C)
2560 {
2561 printf("C=1 ");
2562 }
2563 else
2564 {
2565 printf("C=0 ");
2566 }
2567
2568 printf("\n"); // New line
2569 sanity++;
2570 if (sanity > 200) halt = true;
2571
2572 }
2573
2574 printf("\n"); // New line
2575}
2576
2577
2578////////////////////////////////////////////////////////////////////////////////
2579// Simulator/Emulator (End) //
2580////////////////////////////////////////////////////////////////////////////////
2581
2582
2583void initialise_filenames() {
2584 int i;
2585
2586 for (i = 0; i < MAX_FILENAME_SIZE; i++) {
2587 hex_file[i] = '\0';
2588 trc_file[i] = '\0';
2589 }
2590}
2591
2592
2593
2594
2595int find_dot_position(char *filename) {
2596 int dot_position;
2597 int i;
2598 char chr;
2599
2600 dot_position = 0;
2601 i = 0;
2602 chr = filename[i];
2603
2604 while (chr != '\0') {
2605 if (chr == '.') {
2606 dot_position = i;
2607 }
2608 i++;
2609 chr = filename[i];
2610 }
2611
2612 return (dot_position);
2613}
2614
2615
2616int find_end_position(char *filename) {
2617 int end_position;
2618 int i;
2619 char chr;
2620
2621 end_position = 0;
2622 i = 0;
2623 chr = filename[i];
2624
2625 while (chr != '\0') {
2626 end_position = i;
2627 i++;
2628 chr = filename[i];
2629 }
2630
2631 return (end_position);
2632}
2633
2634
2635bool file_exists(char *filename) {
2636 bool exists;
2637 FILE *ifp;
2638
2639 exists = false;
2640
2641 if ((ifp = fopen(filename, "r")) != NULL) {
2642 exists = true;
2643
2644 fclose(ifp);
2645 }
2646
2647 return (exists);
2648}
2649
2650
2651
2652void create_file(char *filename) {
2653 FILE *ofp;
2654
2655 if ((ofp = fopen(filename, "w")) != NULL) {
2656 fclose(ofp);
2657 }
2658}
2659
2660
2661
2662bool getline(FILE *fp, char *buffer) {
2663 bool rc;
2664 bool collect;
2665 char c;
2666 int i;
2667
2668 rc = false;
2669 collect = true;
2670
2671 i = 0;
2672 while (collect) {
2673 c = getc(fp);
2674
2675 switch (c) {
2676 case EOF:
2677 if (i > 0) {
2678 rc = true;
2679 }
2680 collect = false;
2681 break;
2682
2683 case '\n':
2684 if (i > 0) {
2685 rc = true;
2686 collect = false;
2687 buffer[i] = '\0';
2688 }
2689 break;
2690
2691 default:
2692 buffer[i] = c;
2693 i++;
2694 break;
2695 }
2696 }
2697
2698 return (rc);
2699}
2700
2701
2702
2703
2704
2705
2706void load_and_run(int args, _TCHAR** argv) {
2707 char chr;
2708 int ln;
2709 int dot_position;
2710 int end_position;
2711 long i;
2712 FILE *ifp;
2713 long address;
2714 long load_at;
2715 int code;
2716
2717 // Prompt for the .hex file
2718
2719 printf("\n");
2720 printf("Enter the hex filename (.hex): ");
2721
2722 if (args == 2) {
2723 ln = 0;
2724 chr = argv[1][ln];
2725 while (chr != '\0')
2726 {
2727 if (ln < MAX_FILENAME_SIZE)
2728 {
2729 hex_file[ln] = chr;
2730 trc_file[ln] = chr;
2731 ln++;
2732 }
2733 chr = argv[1][ln];
2734 }
2735 }
2736 else {
2737 ln = 0;
2738 chr = '\0';
2739 while (chr != '\n') {
2740 chr = getchar();
2741
2742 switch (chr) {
2743 case '\n':
2744 break;
2745 default:
2746 if (ln < MAX_FILENAME_SIZE) {
2747 hex_file[ln] = chr;
2748 trc_file[ln] = chr;
2749 ln++;
2750 }
2751 break;
2752 }
2753 }
2754
2755 }
2756 // Tidy up the file names
2757
2758 dot_position = find_dot_position(hex_file);
2759 if (dot_position == 0) {
2760 end_position = find_end_position(hex_file);
2761
2762 hex_file[end_position + 1] = '.';
2763 hex_file[end_position + 2] = 'h';
2764 hex_file[end_position + 3] = 'e';
2765 hex_file[end_position + 4] = 'x';
2766 hex_file[end_position + 5] = '\0';
2767 }
2768 else {
2769 hex_file[dot_position + 0] = '.';
2770 hex_file[dot_position + 1] = 'h';
2771 hex_file[dot_position + 2] = 'e';
2772 hex_file[dot_position + 3] = 'x';
2773 hex_file[dot_position + 4] = '\0';
2774 }
2775
2776 dot_position = find_dot_position(trc_file);
2777 if (dot_position == 0) {
2778 end_position = find_end_position(trc_file);
2779
2780 trc_file[end_position + 1] = '.';
2781 trc_file[end_position + 2] = 't';
2782 trc_file[end_position + 3] = 'r';
2783 trc_file[end_position + 4] = 'c';
2784 trc_file[end_position + 5] = '\0';
2785 }
2786 else {
2787 trc_file[dot_position + 0] = '.';
2788 trc_file[dot_position + 1] = 't';
2789 trc_file[dot_position + 2] = 'r';
2790 trc_file[dot_position + 3] = 'c';
2791 trc_file[dot_position + 4] = '\0';
2792 }
2793
2794 if (file_exists(hex_file)) {
2795 // Clear Registers and Memory
2796
2797 Registers[REGISTER_A] = 0;
2798 Registers[REGISTER_B] = 0;
2799 Registers[REGISTER_C] = 0;
2800 Registers[REGISTER_L] = 0;
2801 Registers[REGISTER_H] = 0;
2802 Index_Registers[REGISTER_X] = 0;
2803 Index_Registers[REGISTER_Y] = 0;
2804 Flags = 0;
2805 ProgramCounter = 0;
2806 StackPointer = 0;
2807
2808 for (i = 0; i < MEMORY_SIZE; i++) {
2809 Memory[i] = 0x00;
2810 }
2811
2812 // Load hex file
2813
2814 if ((ifp = fopen(hex_file, "r")) != NULL) {
2815 printf("Loading file...\n\n");
2816
2817 load_at = 0;
2818
2819 while (getline(ifp, InputBuffer)) {
2820 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
2821 load_at = address;
2822 }
2823 else if (sscanf(InputBuffer, "%x", &code) == 1) {
2824 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
2825 Memory[load_at] = (BYTE)code;
2826 }
2827 load_at++;
2828 }
2829 else {
2830 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
2831 }
2832 }
2833
2834 fclose(ifp);
2835 }
2836
2837 // Emulate
2838
2839 emulate();
2840 }
2841 else {
2842 printf("\n");
2843 printf("ERROR> Input file %s does not exist!\n", hex_file);
2844 printf("\n");
2845 }
2846}
2847
2848void building(int args, _TCHAR** argv) {
2849 char buffer[1024];
2850 load_and_run(args, argv);
2851 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",
2852 Memory[TEST_ADDRESS_1],
2853 Memory[TEST_ADDRESS_2],
2854 Memory[TEST_ADDRESS_3],
2855 Memory[TEST_ADDRESS_4],
2856 Memory[TEST_ADDRESS_5],
2857 Memory[TEST_ADDRESS_6],
2858 Memory[TEST_ADDRESS_7],
2859 Memory[TEST_ADDRESS_8],
2860 Memory[TEST_ADDRESS_9],
2861 Memory[TEST_ADDRESS_10],
2862 Memory[TEST_ADDRESS_11],
2863 Memory[TEST_ADDRESS_12]
2864 );
2865 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2866}
2867
2868
2869
2870void test_and_mark() {
2871 char buffer[1024];
2872 bool testing_complete;
2873 int len = sizeof(SOCKADDR);
2874 char chr;
2875 int i;
2876 int j;
2877 bool end_of_program;
2878 long address;
2879 long load_at;
2880 int code;
2881 int mark;
2882 int passed;
2883
2884 printf("\n");
2885 printf("Automatic Testing and Marking\n");
2886 printf("\n");
2887
2888 testing_complete = false;
2889
2890 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
2891 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2892
2893 while (!testing_complete) {
2894 memset(buffer, '\0', sizeof(buffer));
2895
2896 if (recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
2897 printf("Incoming Data: %s \n", buffer);
2898
2899 //if (strcmp(buffer, "Testing complete") == 1)
2900 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
2901 testing_complete = true;
2902 printf("Current mark = %d\n", mark);
2903
2904 }
2905 else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
2906 //testing_complete = true;
2907 printf("Passed = %d\n", passed);
2908
2909 }
2910 else if (strcmp(buffer, "Error") == 0) {
2911 printf("ERROR> Testing abnormally terminated\n");
2912 testing_complete = true;
2913 }
2914 else {
2915 // Clear Registers and Memory
2916
2917 Registers[REGISTER_A] = 0;
2918 Registers[REGISTER_B] = 0;
2919 Registers[REGISTER_C] = 0;
2920 Registers[REGISTER_L] = 0;
2921 Registers[REGISTER_H] = 0;
2922 Index_Registers[REGISTER_X] = 0;
2923 Index_Registers[REGISTER_Y] = 0;
2924 Flags = 0;
2925 ProgramCounter = 0;
2926 StackPointer = 0;
2927 for (i = 0; i < MEMORY_SIZE; i++) {
2928 Memory[i] = 0;
2929 }
2930
2931 // Load hex file
2932
2933 i = 0;
2934 j = 0;
2935 load_at = 0;
2936 end_of_program = false;
2937 FILE *ofp;
2938 fopen_s(&ofp, "branch.txt", "a");
2939
2940 while (!end_of_program) {
2941 chr = buffer[i];
2942 switch (chr) {
2943 case '\0':
2944 end_of_program = true;
2945
2946 case ',':
2947 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
2948 load_at = address;
2949 }
2950 else if (sscanf(InputBuffer, "%x", &code) == 1) {
2951 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
2952 Memory[load_at] = (BYTE)code;
2953 fprintf(ofp, "%02X\n", (BYTE)code);
2954 }
2955 load_at++;
2956 }
2957 else {
2958 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
2959 }
2960 j = 0;
2961 break;
2962
2963 default:
2964 InputBuffer[j] = chr;
2965 j++;
2966 break;
2967 }
2968 i++;
2969 }
2970 fclose(ofp);
2971 // Emulate
2972
2973 if (load_at > 1) {
2974 emulate();
2975 // Send and store results
2976 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
2977 Memory[TEST_ADDRESS_1],
2978 Memory[TEST_ADDRESS_2],
2979 Memory[TEST_ADDRESS_3],
2980 Memory[TEST_ADDRESS_4],
2981 Memory[TEST_ADDRESS_5],
2982 Memory[TEST_ADDRESS_6],
2983 Memory[TEST_ADDRESS_7],
2984 Memory[TEST_ADDRESS_8],
2985 Memory[TEST_ADDRESS_9],
2986 Memory[TEST_ADDRESS_10],
2987 Memory[TEST_ADDRESS_11],
2988 Memory[TEST_ADDRESS_12]
2989 );
2990 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2991 }
2992 }
2993 }
2994 }
2995}
2996
2997
2998
2999int _tmain(int argc, _TCHAR* argv[])
3000{
3001 char chr;
3002 char dummy;
3003
3004 printf("\n");
3005 printf("Microprocessor Emulator\n");
3006 printf("UWE Computer and Network Systems Assignment 1\n");
3007 printf("\n");
3008
3009 initialise_filenames();
3010
3011 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
3012
3013 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
3014 if (!sock) {
3015 // Creation failed!
3016 }
3017
3018 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
3019 server_addr.sin_family = AF_INET;
3020 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
3021 server_addr.sin_port = htons(PORT_SERVER);
3022
3023 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
3024 client_addr.sin_family = AF_INET;
3025 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
3026 client_addr.sin_port = htons(PORT_CLIENT);
3027
3028 chr = '\0';
3029 while ((chr != 'e') && (chr != 'E'))
3030 {
3031 printf("\n");
3032 printf("Please select option\n");
3033 printf("L - Load and run a hex file\n");
3034 printf("T - Have the server test and mark your emulator\n");
3035 printf("E - Exit\n");
3036 if (argc == 2) { building(argc, argv); exit(0); }
3037 printf("Enter option: ");
3038 chr = getchar();
3039 if (chr != 0x0A)
3040 {
3041 dummy = getchar(); // read in the <CR>
3042 }
3043 printf("\n");
3044
3045 switch (chr)
3046 {
3047 case 'L':
3048 case 'l':
3049 load_and_run(argc, argv);
3050 break;
3051
3052 case 'T':
3053 case 't':
3054 test_and_mark();
3055 break;
3056
3057 default:
3058 break;
3059 }
3060 }
3061
3062 closesocket(sock);
3063 WSACleanup();
3064
3065
3066 return 0;
3067}