· 7 years ago · Feb 20, 2019, 07:42 PM
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 BYTE saved_flags = 0;
428 WORD address = 0;
429 WORD data = 0;
430 WORD temp_word = 0;
431 WORD param1 = 0;
432 WORD param2 = 0;
433
434 switch (opcode) {
435 case 0x43: //LD Immediate
436 data = fetch();
437 Registers[REGISTER_A] = data;
438 set_flag_n((BYTE)Registers[REGISTER_A]);
439 set_flag_z((BYTE)Registers[REGISTER_A]);
440 break;
441
442 case 0x53: //LD Absoulute
443 LB = fetch();
444 HB = fetch();
445 address += (WORD)((WORD)HB << 8) + LB;
446 if (address >= 0 && address < MEMORY_SIZE) {
447 Registers[REGISTER_A] = Memory[address];
448 }
449 set_flag_n((BYTE)Registers[REGISTER_A]);
450 set_flag_z((BYTE)Registers[REGISTER_A]);
451 break;
452
453 case 0x63://LD Absoulte X
454 address += Index_Registers[REGISTER_X];
455 LB = fetch();
456 HB = fetch();
457 address += (WORD)((WORD)HB << 8) + LB;
458 if (address >= 0 && address < MEMORY_SIZE) {
459 Registers[REGISTER_A] = Memory[address];
460 }
461 set_flag_n((BYTE)Registers[REGISTER_A]);
462 set_flag_z((BYTE)Registers[REGISTER_A]);
463 break;
464
465 case 0x73://LD Absoulte Y
466 address += Index_Registers[REGISTER_Y];
467 LB = fetch();
468 HB = fetch();
469 address += (WORD)((WORD)HB << 8) + LB;
470 if (address >= 0 && address < MEMORY_SIZE) {
471 Registers[REGISTER_A] = Memory[address];
472 }
473 set_flag_n((BYTE)Registers[REGISTER_A]);
474 set_flag_z((BYTE)Registers[REGISTER_A]);
475 break;
476
477 case 0x83://LD Absoulte XY
478 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
479 LB = fetch();
480 HB = fetch();
481 address += (WORD)((WORD)HB << 8) + LB;
482 if (address >= 0 && address < MEMORY_SIZE) {
483 Registers[REGISTER_A] = Memory[address];
484 }
485 set_flag_n((BYTE)Registers[REGISTER_A]);
486 set_flag_z((BYTE)Registers[REGISTER_A]);
487 break;
488
489 case 0x93://LD zpg
490 address += 0x0000 | (WORD)fetch();
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 0x04://STO Absolute
499 LB = fetch();
500 HB = fetch();
501 address += (WORD)((WORD)HB << 8) + LB;
502 if (address >= 0 && address < MEMORY_SIZE) {
503 Memory[address] = Registers[REGISTER_A];
504 }
505 set_flag_n((BYTE)Memory[address]);
506 set_flag_z((BYTE)Memory[address]);
507 break;
508
509 case 0x14://STO Absolute X
510 address += Index_Registers[REGISTER_X];
511 LB = fetch();
512 HB = fetch();
513 address += (WORD)((WORD)HB << 8) + LB;
514 if (address >= 0 && address < MEMORY_SIZE) {
515 Memory[address] = Registers[REGISTER_A];
516 }
517 set_flag_n((BYTE)Memory[address]);
518 set_flag_z((BYTE)Memory[address]);
519 break;
520
521 case 0x24: //STO Absolute Y
522 address += Index_Registers[REGISTER_Y];
523 LB = fetch();
524 HB = fetch();
525 address += (WORD)((WORD)HB << 8) + LB;
526 if (address >= 0 && address < MEMORY_SIZE) {
527 Memory[address] = Registers[REGISTER_A];
528 }
529 set_flag_n((BYTE)Memory[address]);
530 set_flag_z((BYTE)Memory[address]);
531 break;
532
533 case 0x34://STO Absolute XY
534 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
535 LB = fetch();
536 HB = fetch();
537 address += (WORD)((WORD)HB << 8) + LB;
538 if (address >= 0 && address < MEMORY_SIZE) {
539 Memory[address] = Registers[REGISTER_A];
540 }
541 set_flag_n((BYTE)Memory[address]);
542 set_flag_z((BYTE)Memory[address]);
543 break;
544
545 case 0x44://STO zpg
546 address += 0x0000 | (WORD)fetch();
547 if (address >= 0 && address < MEMORY_SIZE) {
548 Memory[address] = Registers[REGISTER_A];
549 }
550 set_flag_n((BYTE)Memory[address]);
551 set_flag_z((BYTE)Memory[address]);
552 break;
553
554 case 0x21://LDX Immediate
555 data = fetch();
556 Index_Registers[REGISTER_X] = data;
557 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
558 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
559 break;
560
561 case 0x31: //LDX Absoulute
562 LB = fetch();
563 HB = fetch();
564 address += (WORD)((WORD)HB << 8) + LB;
565 if (address >= 0 && address < MEMORY_SIZE) {
566 Index_Registers[REGISTER_X] = Memory[address];
567 }
568 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
569 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
570 break;
571
572 case 0x41://LDX Absoulte X
573 address += Index_Registers[REGISTER_X];
574 LB = fetch();
575 HB = fetch();
576 address += (WORD)((WORD)HB << 8) + LB;
577 if (address >= 0 && address < MEMORY_SIZE) {
578 Index_Registers[REGISTER_X] = Memory[address];
579 }
580 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
581 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
582 break;
583
584 case 0x51://LDX Absoulte Y
585 address += Index_Registers[REGISTER_Y];
586 LB = fetch();
587 HB = fetch();
588 address += (WORD)((WORD)HB << 8) + LB;
589 if (address >= 0 && address < MEMORY_SIZE) {
590 Index_Registers[REGISTER_X] = Memory[address];
591 }
592 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
593 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
594 break;
595
596 case 0x61://LDX Absoulte XY
597 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
598 LB = fetch();
599 HB = fetch();
600 address += (WORD)((WORD)HB << 8) + LB;
601 if (address >= 0 && address < MEMORY_SIZE) {
602 Index_Registers[REGISTER_X] = Memory[address];
603 }
604 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
605 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
606 break;
607
608 case 0x71://LDX zpg
609 address += 0x0000 | (WORD)fetch();
610 if (address >= 0 && address < MEMORY_SIZE) {
611 Index_Registers[REGISTER_X] = Memory[address];
612 }
613 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
614 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
615 break;
616
617 case 0x22://LODY Immediate
618 data = fetch();
619 Index_Registers[REGISTER_Y] = data;
620 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
621 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
622 break;
623
624 case 0x32: //LODY Absoulute
625 LB = fetch();
626 HB = fetch();
627 address += (WORD)((WORD)HB << 8) + LB;
628 if (address >= 0 && address < MEMORY_SIZE) {
629 Index_Registers[REGISTER_Y] = Memory[address];
630 }
631 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
632 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
633 break;
634
635 case 0x42://LODY Absoulte X
636 address += Index_Registers[REGISTER_X];
637 LB = fetch();
638 HB = fetch();
639 address += (WORD)((WORD)HB << 8) + LB;
640 if (address >= 0 && address < MEMORY_SIZE) {
641 Index_Registers[REGISTER_Y] = Memory[address];
642 }
643 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
644 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
645 break;
646
647 case 0x52://LODY Absoulte Y
648 address += Index_Registers[REGISTER_Y];
649 LB = fetch();
650 HB = fetch();
651 address += (WORD)((WORD)HB << 8) + LB;
652 if (address >= 0 && address < MEMORY_SIZE) {
653 Index_Registers[REGISTER_Y] = Memory[address];
654 }
655 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
656 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
657 break;
658
659 case 0x62://LODY Absoulte XY
660 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
661 LB = fetch();
662 HB = fetch();
663 address += (WORD)((WORD)HB << 8) + LB;
664 if (address >= 0 && address < MEMORY_SIZE) {
665 Index_Registers[REGISTER_Y] = Memory[address];
666 }
667 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
668 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
669 break;
670
671 case 0x72://LODY zpg
672 address += 0x0000 | (WORD)fetch();
673 if (address >= 0 && address < MEMORY_SIZE) {
674 Index_Registers[REGISTER_Y] = Memory[address];
675 }
676 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
677 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
678 break;
679
680 case 0x27://Register B MVR Intermediate
681 data = fetch();
682 Registers[REGISTER_B] = data;
683 set_flag_n((BYTE)Registers[REGISTER_B]);
684 set_flag_z((BYTE)Registers[REGISTER_B]);
685 break;
686
687 case 0x28://Register C MVR Intermediate
688 data = fetch();
689 Registers[REGISTER_C] = data;
690 set_flag_n((BYTE)Registers[REGISTER_C]);
691 set_flag_z((BYTE)Registers[REGISTER_C]);
692 break;
693
694 case 0x29://Register L MVR Intermediate
695 data = fetch();
696 Registers[REGISTER_L] = data;
697 set_flag_n((BYTE)Registers[REGISTER_L]);
698 set_flag_z((BYTE)Registers[REGISTER_L]);
699 break;
700
701 case 0x2A://Register H MVR Intermediate
702 data = fetch();
703 Registers[REGISTER_H] = data;
704 set_flag_n((BYTE)Registers[REGISTER_H]);
705 set_flag_z((BYTE)Registers[REGISTER_H]);
706 break;
707
708 case 0x20://LODS Immediate
709 data = fetch();
710 StackPointer = data;
711 StackPointer += (WORD)fetch() << 8;
712 set_flag_n((BYTE)StackPointer);
713 set_flag_z((BYTE)StackPointer);
714 break;
715
716 case 0x30://LODS Absoulte
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_n((BYTE)StackPointer);
725 set_flag_z((BYTE)StackPointer);
726 break;
727
728 case 0x40://LODS Absoulte X
729 address += Index_Registers[REGISTER_X];
730 LB = fetch();
731 HB = fetch();
732 address += (WORD)((WORD)HB << 8) + LB;
733 if (address >= 0 && address < MEMORY_SIZE - 1) {
734 StackPointer = Memory[address];
735 StackPointer += (WORD)Memory[address + 1] << 8;
736 }
737 set_flag_n((BYTE)StackPointer);
738 set_flag_z((BYTE)StackPointer);
739 break;
740
741 case 0x50://LODS Absoulte Y
742 address += Index_Registers[REGISTER_Y];
743 LB = fetch();
744 HB = fetch();
745 address += (WORD)((WORD)HB << 8) + LB;
746 if (address >= 0 && address < MEMORY_SIZE - 1) {
747 StackPointer = Memory[address];
748 StackPointer += (WORD)Memory[address + 1] << 8;
749 }
750 set_flag_n((BYTE)StackPointer);
751 set_flag_z((BYTE)StackPointer);
752 break;
753
754 case 0x60://LODS Absolute XY
755 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
756 LB = fetch();
757 HB = fetch();
758 address += (WORD)((WORD)HB << 8) + LB;
759 if (address >= 0 && address < MEMORY_SIZE - 1) {
760 StackPointer = Memory[address];
761 StackPointer += (WORD)Memory[address + 1] << 8;
762 }
763 set_flag_n((BYTE)StackPointer);
764 set_flag_z((BYTE)StackPointer);
765 break;
766
767 case 0x70://LODS zpg
768 address += 0x0000 | (WORD)fetch();
769 if (address >= 0 && address < MEMORY_SIZE - 1) {
770 StackPointer = Memory[address];
771 StackPointer += (WORD)Memory[address + 1] << 8;
772 }
773 set_flag_n((BYTE)StackPointer);
774 set_flag_z((BYTE)StackPointer);
775 break;
776
777 case 0x0F://STOS Absoulte
778 LB = fetch();
779 HB = fetch();
780 address += (WORD)((WORD)HB << 8) + LB;
781 if (address >= 0 && address < MEMORY_SIZE - 1) {
782 HB = (BYTE)(StackPointer >> 8);
783 LB = (BYTE)StackPointer;
784 Memory[address] = LB;
785 Memory[address + 1] = HB;
786 }
787 set_flag_n((BYTE)StackPointer);
788 set_flag_z((BYTE)StackPointer);
789 break;
790
791 case 0x1F://STOS Absoulte X
792 address += Index_Registers[REGISTER_X];
793 LB = fetch();
794 HB = fetch();
795 address += (WORD)((WORD)HB << 8) + LB;
796 if (address >= 0 && address < MEMORY_SIZE - 1) {
797 HB = (BYTE)(StackPointer >> 8);
798 LB = (BYTE)StackPointer;
799 Memory[address] = LB;
800 Memory[address + 1] = HB;
801
802 }
803 set_flag_n((BYTE)StackPointer);
804 set_flag_z((BYTE)StackPointer);
805 break;
806
807 case 0x2F://STOS Absoulte Y
808 address += Index_Registers[REGISTER_Y];
809 LB = fetch();
810 HB = fetch();
811 address += (WORD)((WORD)HB << 8) + LB;
812 if (address >= 0 && address < MEMORY_SIZE - 1) {
813 HB = (BYTE)(StackPointer >> 8);
814 LB = (BYTE)StackPointer;
815 Memory[address] = LB;
816 Memory[address + 1] = HB;
817 }
818 set_flag_n((BYTE)StackPointer);
819 set_flag_z((BYTE)StackPointer);
820 break;
821
822 case 0x3F://STOS Absolute XY
823 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
824 LB = fetch();
825 HB = fetch();
826 address += (WORD)((WORD)HB << 8) + LB;
827 if (address >= 0 && address < MEMORY_SIZE - 1) {
828 HB = (BYTE)(StackPointer >> 8);
829 LB = (BYTE)StackPointer;
830 Memory[address] = LB;
831 Memory[address + 1] = HB;
832 }
833 set_flag_n((BYTE)StackPointer);
834 set_flag_z((BYTE)StackPointer);
835 break;
836
837 case 0x4F://STOS zpg
838 address += 0x0000 | (WORD)fetch();
839 if (address >= 0 && address < MEMORY_SIZE - 1) {
840 HB = (BYTE)(StackPointer >> 8);
841 LB = (BYTE)StackPointer;
842 Memory[address] = LB;
843 Memory[address + 1] = HB;
844 }
845 set_flag_n((BYTE)StackPointer);
846 set_flag_z((BYTE)StackPointer);
847 break;
848
849 case 0x05://STOX Absolute
850 LB = fetch();
851 HB = fetch();
852 address += (WORD)((WORD)HB << 8) + LB;
853 if (address >= 0 && address < MEMORY_SIZE) {
854 Memory[address] = Index_Registers[REGISTER_X];
855 }
856 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
857 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
858 break;
859
860 case 0x15://STOX Absolute X
861 address += Index_Registers[REGISTER_X];
862 LB = fetch();
863 HB = fetch();
864 address += (WORD)((WORD)HB << 8) + LB;
865 if (address >= 0 && address < MEMORY_SIZE) {
866 Memory[address] = Index_Registers[REGISTER_X];
867 }
868 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
869 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
870 break;
871
872 case 0x25: //STOX Absolute Y
873 address += Index_Registers[REGISTER_Y];
874 LB = fetch();
875 HB = fetch();
876 address += (WORD)((WORD)HB << 8) + LB;
877 if (address >= 0 && address < MEMORY_SIZE) {
878 Memory[address] = Index_Registers[REGISTER_X];
879 }
880 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
881 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
882 break;
883
884 case 0x35://STOX Absolute XY
885 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
886 LB = fetch();
887 HB = fetch();
888 address += (WORD)((WORD)HB << 8) + LB;
889 if (address >= 0 && address < MEMORY_SIZE) {
890 Memory[address] = Index_Registers[REGISTER_X];
891 }
892 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
893 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
894 break;
895
896 case 0x45://STOX zpg
897 address += 0x0000 | (WORD)fetch();
898 if (address >= 0 && address < MEMORY_SIZE) {
899 Memory[address] = Index_Registers[REGISTER_X];
900 }
901 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
902 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
903 break;
904
905 case 0x06://STOY Absolute
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_Y];
911 }
912 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
913 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
914 break;
915
916 case 0x16://STOY Absolute X
917 address += Index_Registers[REGISTER_X];
918 LB = fetch();
919 HB = fetch();
920 address += (WORD)((WORD)HB << 8) + LB;
921 if (address >= 0 && address < MEMORY_SIZE) {
922 Memory[address] = Index_Registers[REGISTER_Y];
923 }
924 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
925 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
926 break;
927
928 case 0x26: //STOY Absolute Y
929 address += Index_Registers[REGISTER_Y];
930 LB = fetch();
931 HB = fetch();
932 address += (WORD)((WORD)HB << 8) + LB;
933 if (address >= 0 && address < MEMORY_SIZE) {
934 Memory[address] = Index_Registers[REGISTER_Y];
935 }
936 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
937 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
938 break;
939
940 case 0x36://STOY Absolute XY
941 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
942 LB = fetch();
943 HB = fetch();
944 address += (WORD)((WORD)HB << 8) + LB;
945 if (address >= 0 && address < MEMORY_SIZE) {
946 Memory[address] = Index_Registers[REGISTER_Y];
947 }
948 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
949 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
950 break;
951
952 case 0x46://STOY zpg
953 address += 0x0000 | (WORD)fetch();
954 if (address >= 0 && address < MEMORY_SIZE) {
955 Memory[address] = Index_Registers[REGISTER_Y];
956 }
957 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
958 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
959 break;
960
961 case 0xB6://ADC A,B
962 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
963 if ((Flags & FLAG_C) != 0)
964 {
965 temp_word++;
966 }
967 if (temp_word >= 0x100)
968 {
969 Flags = Flags | FLAG_C;
970 }
971 else
972 {
973 Flags = Flags & (0xFF - FLAG_C);
974 }
975 set_flag_n((BYTE)temp_word);
976 set_flag_z((BYTE)temp_word);
977 Registers[REGISTER_A] = (BYTE)temp_word;
978 break;
979
980 case 0xC6://ADC A,C
981 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
982 if ((Flags & FLAG_C) != 0)
983 {
984 temp_word++;
985 }
986 if (temp_word >= 0x100)
987 {
988 Flags = Flags | FLAG_C;
989 }
990 else
991 {
992 Flags = Flags & (0xFF - FLAG_C);
993 }
994 set_flag_n((BYTE)temp_word);
995 set_flag_z((BYTE)temp_word);
996 Registers[REGISTER_A] = (BYTE)temp_word;
997 break;
998
999 case 0xD6://ADC A,L
1000 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
1001 if ((Flags & FLAG_C) != 0)
1002 {
1003 temp_word++;
1004 }
1005 if (temp_word >= 0x100)
1006 {
1007 Flags = Flags | FLAG_C;
1008 }
1009 else
1010 {
1011 Flags = Flags & (0xFF - FLAG_C);
1012 }
1013 set_flag_n((BYTE)temp_word);
1014 set_flag_z((BYTE)temp_word);
1015 Registers[REGISTER_A] = (BYTE)temp_word;
1016 break;
1017
1018 case 0xE6://ADC A,H
1019 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
1020 if ((Flags & FLAG_C) != 0)
1021 {
1022 temp_word++;
1023 }
1024 if (temp_word >= 0x100)
1025 {
1026 Flags = Flags | FLAG_C;
1027 }
1028 else
1029 {
1030 Flags = Flags & (0xFF - FLAG_C);
1031 }
1032 set_flag_n((BYTE)temp_word);
1033 set_flag_z((BYTE)temp_word);
1034 Registers[REGISTER_A] = (BYTE)temp_word;
1035 break;
1036
1037 case 0xF6://ADC A,M
1038 HB = Registers[REGISTER_H];
1039 LB = Registers[REGISTER_L];
1040 address = ((WORD)HB << 8) + LB;
1041 param1 = Registers[REGISTER_A];
1042 param2 = Memory[address];
1043 temp_word = (WORD)param1 + (WORD)param2;
1044 if ((Flags & FLAG_C) != 0)
1045 {
1046 temp_word++;
1047 }
1048 if (temp_word >= 0x100)
1049 {
1050 Flags = Flags | FLAG_C;
1051 }
1052 else
1053 {
1054 Flags = Flags & (0xFF - FLAG_C);
1055 }
1056 set_flag_n((BYTE)temp_word);
1057 set_flag_z((BYTE)temp_word);
1058 Registers[REGISTER_A] = (BYTE)temp_word;
1059 break;
1060
1061 case 0xB8://ADD A,B
1062 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
1063 if (temp_word >= 0x100)
1064 {
1065 Flags = Flags | FLAG_C;
1066 }
1067 else
1068 {
1069 Flags = Flags & (0xFF - FLAG_C);
1070 }
1071 set_flag_n((BYTE)temp_word);
1072 set_flag_z((BYTE)temp_word);
1073 Registers[REGISTER_A] = (BYTE)temp_word;
1074 break;
1075
1076 case 0xC8://ADD A,C
1077 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
1078 if (temp_word >= 0x100)
1079 {
1080 Flags = Flags | FLAG_C;
1081 }
1082 else
1083 {
1084 Flags = Flags & (0xFF - FLAG_C);
1085 }
1086 set_flag_n((BYTE)temp_word);
1087 set_flag_z((BYTE)temp_word);
1088 Registers[REGISTER_A] = (BYTE)temp_word;
1089 break;
1090
1091 case 0xD8://ADD A,L
1092 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
1093 if (temp_word >= 0x100)
1094 {
1095 Flags = Flags | FLAG_C;
1096 }
1097 else
1098 {
1099 Flags = Flags & (0xFF - FLAG_C);
1100 }
1101 set_flag_n((BYTE)temp_word);
1102 set_flag_z((BYTE)temp_word);
1103 Registers[REGISTER_A] = (BYTE)temp_word;
1104 break;
1105
1106 case 0xE8://ADD A,H
1107 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
1108 if (temp_word >= 0x100)
1109 {
1110 Flags = Flags | FLAG_C;
1111 }
1112 else
1113 {
1114 Flags = Flags & (0xFF - FLAG_C);
1115 }
1116 set_flag_n((BYTE)temp_word);
1117 set_flag_z((BYTE)temp_word);
1118 Registers[REGISTER_A] = (BYTE)temp_word;
1119 break;
1120
1121 case 0xF8://ADD A,M
1122 HB = Registers[REGISTER_H];
1123 LB = Registers[REGISTER_L];
1124 address = ((WORD)HB << 8) + LB;
1125 param1 = Registers[REGISTER_A];
1126 param2 = Memory[address];
1127 temp_word = (WORD)param1 + (WORD)param2;
1128 if (temp_word >= 0x100)
1129 {
1130 Flags = Flags | FLAG_C;
1131 }
1132 else
1133 {
1134 Flags = Flags & (0xFF - FLAG_C);
1135 }
1136 set_flag_n((BYTE)temp_word);
1137 set_flag_z((BYTE)temp_word);
1138 Registers[REGISTER_A] = (BYTE)temp_word;
1139 break;
1140
1141 case 0xBA://CMP A,B
1142 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
1143 if (temp_word >= 0x100) {
1144 Flags = Flags | FLAG_C; // Set carry flag
1145 }
1146 else {
1147 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1148 }
1149 set_flag_n((BYTE)temp_word);
1150 set_flag_z((BYTE)temp_word);
1151 break;
1152
1153 case 0xCA://CMP A,C
1154 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
1155 if (temp_word >= 0x100) {
1156 Flags = Flags | FLAG_C; // Set carry flag
1157 }
1158 else {
1159 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1160 }
1161 set_flag_n((BYTE)temp_word);
1162 set_flag_z((BYTE)temp_word);
1163 break;
1164
1165 case 0xDA://CMP A,L
1166 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1167 if (temp_word >= 0x100) {
1168 Flags = Flags | FLAG_C; // Set carry flag
1169 }
1170 else {
1171 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1172 }
1173 set_flag_n((BYTE)temp_word);
1174 set_flag_z((BYTE)temp_word);
1175 break;
1176
1177 case 0xEA://CMP A,H
1178 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1179 if (temp_word >= 0x100)
1180 {
1181 Flags = Flags | FLAG_C; // Set carry flag
1182 }
1183 else
1184 {
1185 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1186 }
1187 set_flag_n((BYTE)temp_word);
1188 set_flag_z((BYTE)temp_word);
1189 break;
1190
1191 case 0xFA://CMP A,M
1192 HB = Registers[REGISTER_H];
1193 LB = Registers[REGISTER_L];
1194 address = ((WORD)HB << 8) + LB;
1195 param1 = Registers[REGISTER_A];
1196 param2 = Memory[address];
1197 temp_word = (WORD)param1 + (WORD)param2;
1198 if (temp_word >= 0x100)
1199 {
1200 Flags = Flags | FLAG_C; // Set carry flag
1201 }
1202 else
1203 {
1204 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1205 }
1206 set_flag_n((BYTE)temp_word);
1207 set_flag_z((BYTE)temp_word);
1208 break;
1209
1210 case 0x2D://MSA
1211 Registers[REGISTER_A] = Flags;
1212 break;
1213
1214 case 0x2B://TAY
1215 Index_Registers[REGISTER_Y] = Registers[REGISTER_A];
1216 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
1217 break;
1218
1219 case 0x2C://TYA
1220 Registers[REGISTER_A] = Index_Registers[REGISTER_Y];
1221 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
1222 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
1223 break;
1224
1225 case 0xA6://CLC
1226 Flags = Flags & (0xFF - FLAG_C);
1227 break;
1228
1229 case 0xA7://SEC
1230 Flags = Flags | FLAG_C;
1231 break;
1232
1233 case 0xA8://CLI
1234 Flags = Flags & (0xFF - FLAG_I);
1235 break;
1236
1237 case 0xA9://SEI
1238 Flags = Flags | FLAG_I;
1239 break;
1240
1241 case 0xAA://CMC
1242 Flags = Flags ^ FLAG_C;
1243 break;
1244
1245 case 0xAE://PUSH REGISTER A
1246 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1247 StackPointer--;
1248 Memory[StackPointer] = Registers[REGISTER_A];
1249 }
1250 break;
1251
1252 case 0xBE://PUSH FLAGS
1253 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1254 StackPointer--;
1255 Memory[StackPointer] = Flags;
1256 }
1257 break;
1258
1259 case 0xCE://PUSH REGISTER B
1260 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1261 StackPointer--;
1262 Memory[StackPointer] = Registers[REGISTER_B];
1263 }
1264 break;
1265
1266 case 0xDE://PUSH REGISTER C
1267 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1268 StackPointer--;
1269 Memory[StackPointer] = Registers[REGISTER_C];
1270 }
1271 break;
1272
1273 case 0xEE://PUSH REGISTER L
1274 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1275 StackPointer--;
1276 Memory[StackPointer] = Registers[REGISTER_L];
1277 }
1278 break;
1279
1280 case 0xFE://PUSH REGISTER H
1281 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1282 StackPointer--;
1283 Memory[StackPointer] = Registers[REGISTER_H];
1284 }
1285 break;
1286
1287 case 0xAF://POP REGISTER A
1288 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1289 Registers[REGISTER_A] = Memory[StackPointer];
1290 StackPointer++;
1291 }
1292 break;
1293
1294 case 0xBF://POP FLAGS
1295 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1296 Flags = Memory[StackPointer];
1297 StackPointer++;
1298 }
1299 break;
1300
1301 case 0xCF://POP REGISTER B
1302 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1303 Registers[REGISTER_B] = Memory[StackPointer];
1304 StackPointer++;
1305 }
1306 break;
1307
1308 case 0xDF://POP REGISTER C
1309 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1310 Registers[REGISTER_C] = Memory[StackPointer];
1311 StackPointer++;
1312 }
1313 break;
1314
1315 case 0xEF://POP REGISTER L
1316 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1317 Registers[REGISTER_L] = Memory[StackPointer];
1318 StackPointer++;
1319 }
1320 break;
1321
1322 case 0xFF://POP REGISTER H
1323 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1324 Registers[REGISTER_H] = Memory[StackPointer];
1325 StackPointer++;
1326 }
1327 break;
1328
1329 case 0x38: //JUMP abs
1330 LB = fetch();
1331 HB = fetch();
1332 address = ((WORD)HB << 8) + (WORD)LB;
1333 ProgramCounter = address;
1334 break;
1335
1336 case 0x07://JMPR abs
1337 HB = fetch();
1338 LB = fetch();
1339 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1340 StackPointer--;
1341 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1342 StackPointer--;
1343 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1344 ProgramCounter = address;
1345 }
1346 break;
1347
1348 case 0x23: //RT impl
1349 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
1350 LB = Memory[StackPointer];
1351 StackPointer++;
1352 HB = Memory[StackPointer];
1353 StackPointer++;
1354 ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
1355 }
1356 break;
1357
1358 case 0x39://JCC
1359 LB = fetch();
1360 HB = fetch();
1361 address = ((WORD)HB << 8) + (WORD)LB;
1362 if ((Flags & FLAG_C) == 0)
1363 {
1364 ProgramCounter = address;
1365 }
1366 break;
1367
1368 case 0x3A://JCS
1369 LB = fetch();
1370 HB = fetch();
1371 address = ((WORD)HB << 8) + (WORD)LB;
1372 if ((Flags & FLAG_C) == FLAG_C)
1373 {
1374 ProgramCounter = address;
1375 }
1376 break;
1377
1378 case 0x3B://JNE abs
1379 LB = fetch();
1380 HB = fetch();
1381 address = ((WORD)HB << 8) + (WORD)LB;
1382 if ((Flags & FLAG_Z) == 0)
1383 {
1384 ProgramCounter = address;
1385 }
1386 break;
1387
1388 case 0x3C://JEQ
1389 LB = fetch();
1390 HB = fetch();
1391 address = ((WORD)HB << 8) + (WORD)LB;
1392 if ((Flags & FLAG_Z) == FLAG_Z)
1393 {
1394 ProgramCounter = address;
1395 }
1396 break;
1397
1398 case 0x3D://JMI abs
1399 LB = fetch();
1400 HB = fetch();
1401 address = ((WORD)HB << 8) + (WORD)LB;
1402 if ((Flags & FLAG_N) == FLAG_N)
1403 {
1404 ProgramCounter = address;
1405 }
1406 break;
1407
1408 case 0x3E://JPL abs
1409 LB = fetch();
1410 HB = fetch();
1411 address = ((WORD)HB << 8) + (WORD)LB;
1412 if ((Flags & FLAG_N) == 0)
1413 {
1414 ProgramCounter = address;
1415 }
1416 break;
1417
1418 //////////////// CCC
1419 case 0x08: // CCC
1420 LB = fetch();
1421 HB = fetch();
1422 address = ((WORD)HB << 8) + (WORD)LB;
1423 if ((Flags & FLAG_C) == 0) {
1424 Memory[StackPointer] = ProgramCounter;
1425 StackPointer--;
1426 ProgramCounter = address;
1427 }
1428 break;
1429
1430
1431 /////////////// CCS
1432 case 0x09: // CCS
1433 LB = fetch();
1434 HB = fetch();
1435 address = ((WORD)HB << 8) + (WORD)LB;
1436
1437 if ((Flags & FLAG_C) != 0) {
1438 Memory[StackPointer] = ProgramCounter;
1439 StackPointer--;
1440 ProgramCounter = address;
1441 }
1442 break;
1443
1444 ////////////// CNE
1445 case 0x0A: // CNE
1446 LB = fetch();
1447 HB = fetch();
1448 address = ((WORD)HB << 8) + (WORD)LB;
1449
1450 if ((Flags & FLAG_Z) == 0) {
1451 Memory[StackPointer] = ProgramCounter;
1452 StackPointer--;
1453 ProgramCounter = address;
1454 }
1455 break;
1456
1457 /////////////// CEQ
1458 case 0x0B: // CEQ
1459 LB = fetch();
1460 HB = fetch();
1461 address = ((WORD)HB << 8) + (WORD)LB;
1462
1463 if ((Flags & FLAG_Z) != 0) {
1464 Memory[StackPointer] = ProgramCounter;
1465 StackPointer--;
1466 ProgramCounter = address;
1467 }
1468 break;
1469
1470 ///////////////// CMI
1471 case 0x0C: // CMI
1472 LB = fetch();
1473 HB = fetch();
1474 address = ((WORD)HB << 8) + (WORD)LB;
1475
1476 if ((Flags & FLAG_N) != 0) {
1477 Memory[StackPointer] = ProgramCounter;
1478 StackPointer--;
1479 ProgramCounter = address;
1480 }
1481 break;
1482
1483 ///////////////// CPL
1484 case 0x0D: // CPL
1485 LB = fetch();
1486 HB = fetch();
1487 address = ((WORD)HB << 8) + (WORD)LB;
1488
1489 if ((Flags & FLAG_N) == 0) {
1490 Memory[StackPointer] = ProgramCounter;
1491 StackPointer--;
1492 ProgramCounter = address;
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 HB = Registers[REGISTER_H];
1532 LB = Registers[REGISTER_L];
1533 address = ((WORD)HB << 8) + LB;
1534 param1 = Registers[REGISTER_A];
1535 param2 = Memory[address];
1536 temp_word = (WORD)param1 & (WORD)param2;
1537 set_flag_n((BYTE)temp_word);
1538 set_flag_z((BYTE)temp_word);
1539 Registers[REGISTER_A] = (BYTE)temp_word;
1540 break;
1541
1542 case 0x9F: //CLRA
1543 Registers[REGISTER_A] = 0;
1544 Flags = Flags | FLAG_Z;
1545 Flags = Flags & (0xFF - FLAG_N);
1546 Flags = Flags & (0xFF - FLAG_C);
1547 break;
1548
1549 case 0x55: // INC abs
1550 LB = fetch();
1551 HB = fetch();
1552 address += (WORD)((WORD)HB << 8) + LB;
1553 ++Memory[address];
1554 set_flag_n(Memory[address]);
1555 set_flag_z(Memory[address]);
1556 break;
1557
1558 case 0x65: // INC abs X
1559 address += Index_Registers[REGISTER_X];
1560 LB = fetch();
1561 HB = fetch();
1562 address += (WORD)((WORD)HB << 8) + LB;
1563 if (address >= 0 && address < MEMORY_SIZE)
1564 {
1565 ++Memory[address];
1566 }
1567 set_flag_n(Memory[address]);
1568 set_flag_z(Memory[address]);
1569 break;
1570
1571 case 0x75: // INC abs Y
1572 address += Index_Registers[REGISTER_Y];
1573 LB = fetch();
1574 HB = fetch();
1575 address += (WORD)((WORD)HB << 8) + LB;
1576 if (address >= 0 && address < MEMORY_SIZE)
1577 {
1578 ++Memory[address];
1579 }
1580 set_flag_n(Memory[address]);
1581 set_flag_z(Memory[address]);
1582 break;
1583
1584 case 0x85: // INC abs XY
1585 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1586 LB = fetch();
1587 HB = fetch();
1588 address += (WORD)((WORD)HB << 8) + LB;
1589 if (address >= 0 && address < MEMORY_SIZE)
1590 {
1591 ++Memory[address];
1592 }
1593 set_flag_n(Memory[address]);
1594 set_flag_z(Memory[address]);
1595 break;
1596
1597 case 0x5F: // CLR abs
1598 LB = fetch();
1599 HB = fetch();
1600 address += (WORD)((WORD)HB << 8) + LB;
1601 Memory[address] = 0;
1602 Flags = Flags | FLAG_Z;
1603 Flags = Flags & (0xFF - FLAG_N);
1604 Flags = Flags & (0xFF - FLAG_C);
1605 break;
1606
1607 case 0x6F: // CLR abs X
1608 address += Index_Registers[REGISTER_X];
1609 LB = fetch();
1610 HB = fetch();
1611 address += (WORD)((WORD)HB << 8) + LB;
1612 Memory[address] = 0;
1613 Flags = Flags | FLAG_Z;
1614 Flags = Flags & (0xFF - FLAG_N);
1615 Flags = Flags & (0xFF - FLAG_C);
1616 break;
1617
1618 case 0x7F: // CLR abs Y
1619 address += Index_Registers[REGISTER_Y];
1620 LB = fetch();
1621 HB = fetch();
1622 address += (WORD)((WORD)HB << 8) + LB;
1623 Memory[address] = 0;
1624 Flags = Flags | FLAG_Z;
1625 Flags = Flags & (0xFF - FLAG_N);
1626 Flags = Flags & (0xFF - FLAG_C);
1627 break;
1628
1629 case 0x8F: // CLR abs XY
1630 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1631 LB = fetch();
1632 HB = fetch();
1633 address += (WORD)((WORD)HB << 8) + LB;
1634 Memory[address] = 0;
1635 Flags = Flags | FLAG_Z;
1636 Flags = Flags & (0xFF - FLAG_N);
1637 Flags = Flags & (0xFF - FLAG_C);
1638 break;
1639
1640 case 0x4A: // DEX imply
1641 Index_Registers[REGISTER_X]--;
1642 set_flag_z(Index_Registers[REGISTER_X]);
1643 break;
1644
1645 case 0x4B: //INX impl
1646 ++Index_Registers[REGISTER_X];
1647 set_flag_z(Index_Registers[REGISTER_X]);
1648 break;
1649
1650 case 0x4C: //DEY impl
1651 Index_Registers[REGISTER_Y]--;
1652 set_flag_z(Index_Registers[REGISTER_Y]);
1653 break;
1654
1655 case 0x4D: //INY impl
1656 ++Index_Registers[REGISTER_Y];
1657 set_flag_z(Index_Registers[REGISTER_Y]);
1658 break;
1659
1660 case 0xB7: // SBC A,B
1661 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
1662 if ((Flags & FLAG_C) != 0)
1663 {
1664 temp_word--;
1665 }
1666 if (temp_word >= 0x100)
1667 {
1668 Flags = Flags | FLAG_C; //Set carry flag
1669 }
1670 else
1671 {
1672 Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
1673 }
1674 set_flag_n((BYTE)temp_word);
1675 set_flag_z((BYTE)temp_word);
1676 Registers[REGISTER_A] = (BYTE)temp_word;
1677 break;
1678 case 0xC7: // SBC A,C
1679 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
1680 if ((Flags & FLAG_C) != 0)
1681 {
1682 temp_word--;
1683 }
1684 if (temp_word >= 0x100)
1685 {
1686 Flags = Flags | FLAG_C; //Set carry flag
1687 }
1688 else
1689 {
1690 Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
1691 }
1692 set_flag_n((BYTE)temp_word);
1693 set_flag_z((BYTE)temp_word);
1694 Registers[REGISTER_A] = (BYTE)temp_word;
1695 break;
1696 case 0xD7: // SBC A,L
1697 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1698 if ((Flags & FLAG_C) != 0)
1699 {
1700 temp_word--;
1701 }
1702 if (temp_word >= 0x100)
1703 {
1704 Flags = Flags | FLAG_C; //Set carry flag
1705 }
1706 else
1707 {
1708 Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
1709 }
1710 set_flag_n((BYTE)temp_word);
1711 set_flag_z((BYTE)temp_word);
1712 Registers[REGISTER_A] = (BYTE)temp_word;
1713 break;
1714 case 0xE7: // SBC A,H
1715 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1716 if ((Flags & FLAG_C) != 0)
1717 {
1718 temp_word--;
1719 }
1720 if (temp_word >= 0x100)
1721 {
1722 Flags = Flags | FLAG_C; //Set carry flag
1723 }
1724 else
1725 {
1726 Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
1727 }
1728 set_flag_n((BYTE)temp_word);
1729 set_flag_z((BYTE)temp_word);
1730 Registers[REGISTER_A] = (BYTE)temp_word;
1731 break;
1732 case 0xF7: // SBC A,M
1733 HB = Registers[REGISTER_H];
1734 LB = Registers[REGISTER_L];
1735 address = ((WORD)HB << 8) + LB;
1736 temp_word = (WORD)Registers[REGISTER_A] - Memory[address];
1737 if ((Flags & FLAG_C) != 0)
1738 {
1739 temp_word--;
1740 }
1741 if (temp_word >= 0x100)
1742 {
1743 Flags = Flags | FLAG_C; //Set carry flag
1744 }
1745 else
1746 {
1747 Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
1748 }
1749 set_flag_n((BYTE)temp_word);
1750 set_flag_z((BYTE)temp_word);
1751 Registers[REGISTER_A] = (BYTE)temp_word;
1752 break;
1753
1754 case 0xBB: //OR A,B
1755 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_B];
1756 set_flag_n((BYTE)temp_word);
1757 set_flag_z((BYTE)temp_word);
1758 Registers[REGISTER_A] = (BYTE)temp_word;
1759 break;
1760
1761 case 0xCB: //OR A,C
1762 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_C];
1763 set_flag_n((BYTE)temp_word);
1764 set_flag_z((BYTE)temp_word);
1765 Registers[REGISTER_A] = (BYTE)temp_word;
1766 break;
1767
1768 case 0xDB: //OR A,L
1769 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_L];
1770 set_flag_n((BYTE)temp_word);
1771 set_flag_z((BYTE)temp_word);
1772 Registers[REGISTER_A] = (BYTE)temp_word;
1773 break;
1774
1775 case 0xEB: //OR A,H
1776 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_H];
1777 set_flag_n((BYTE)temp_word);
1778 set_flag_z((BYTE)temp_word);
1779 Registers[REGISTER_A] = (BYTE)temp_word;
1780 break;
1781
1782 case 0xFB: //OR A,M
1783 HB = Registers[REGISTER_H];
1784 LB = Registers[REGISTER_L];
1785 address = ((WORD)HB << 8) + LB;
1786 param1 = Registers[REGISTER_A];
1787 param2 = Memory[address];
1788 temp_word = (WORD)param1 | (WORD)param2;
1789 set_flag_n((BYTE)temp_word);
1790 set_flag_z((BYTE)temp_word);
1791 Registers[REGISTER_A] = (BYTE)temp_word;
1792 break;
1793
1794 case 0x9B: //COMA
1795 Registers[REGISTER_A] = Registers[REGISTER_A] ^ 0xFF;
1796 Flags = Flags | FLAG_C;
1797 set_flag_n(Registers[REGISTER_A]);
1798 set_flag_z(Registers[REGISTER_A]);
1799 break;
1800
1801 case 0xB9: //SUB A,B
1802 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
1803 if (temp_word >= 0x100)
1804 {
1805 Flags = Flags | FLAG_C;
1806 }
1807 else
1808 {
1809 Flags = Flags & (0xFF - FLAG_C);
1810 }
1811 set_flag_n((BYTE)temp_word);
1812 set_flag_z((BYTE)temp_word);
1813 Registers[REGISTER_A] = (BYTE)temp_word;
1814 break;
1815
1816 case 0xC9: //SUB A,C
1817 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
1818 if (temp_word >= 0x100)
1819 {
1820 Flags = Flags | FLAG_C;
1821 }
1822 else
1823 {
1824 Flags = Flags & (0xFF - FLAG_C);
1825 }
1826 set_flag_n((BYTE)temp_word);
1827 set_flag_z((BYTE)temp_word);
1828 Registers[REGISTER_A] = (BYTE)temp_word;
1829 break;
1830
1831 case 0xD9: //SUB A,L
1832 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1833 if (temp_word >= 0x100)
1834 {
1835 Flags = Flags | FLAG_C;
1836 }
1837 else
1838 {
1839 Flags = Flags & (0xFF - FLAG_C);
1840 }
1841 set_flag_n((BYTE)temp_word);
1842 set_flag_z((BYTE)temp_word);
1843 Registers[REGISTER_A] = (BYTE)temp_word;
1844 break;
1845
1846 case 0xE9: //SUB A,H
1847 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1848 if (temp_word >= 0x100)
1849 {
1850 Flags = Flags | FLAG_C;
1851 }
1852 else
1853 {
1854 Flags = Flags & (0xFF - FLAG_C);
1855 }
1856 set_flag_n((BYTE)temp_word);
1857 set_flag_z((BYTE)temp_word);
1858 Registers[REGISTER_A] = (BYTE)temp_word;
1859 break;
1860
1861 case 0xF9: //SUB A,M
1862 HB = Registers[REGISTER_H];
1863 LB = Registers[REGISTER_L];
1864 address = ((WORD)HB << 8) + LB;
1865 temp_word = (WORD)Registers[REGISTER_A] - Memory[address];
1866 if (temp_word >= 0x100)
1867 {
1868 Flags = Flags | FLAG_C; //Set carry flag
1869 }
1870 else
1871 {
1872 Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
1873 }
1874 set_flag_n((BYTE)temp_word);
1875 set_flag_z((BYTE)temp_word);
1876 Registers[REGISTER_A] = (BYTE)temp_word;
1877 break;
1878
1879
1880 case 0xBD: //XOR A,B
1881 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_B];
1882 set_flag_n((BYTE)temp_word);
1883 set_flag_z((BYTE)temp_word);
1884 Registers[REGISTER_A] = (BYTE)temp_word;
1885 break;
1886
1887 case 0xCD: //XOR A,C
1888 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_C];
1889 set_flag_n((BYTE)temp_word);
1890 set_flag_z((BYTE)temp_word);
1891 Registers[REGISTER_A] = (BYTE)temp_word;
1892 break;
1893
1894 case 0xDD: //XOR A,L
1895 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_L];
1896 set_flag_n((BYTE)temp_word);
1897 set_flag_z((BYTE)temp_word);
1898 Registers[REGISTER_A] = (BYTE)temp_word;
1899 break;
1900
1901 case 0xED: //XOR A,H
1902 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_H];
1903 set_flag_n((BYTE)temp_word);
1904 set_flag_z((BYTE)temp_word);
1905 Registers[REGISTER_A] = (BYTE)temp_word;
1906 break;
1907
1908 case 0xFD: //XOR A,M
1909 HB = Registers[REGISTER_H];
1910 LB = Registers[REGISTER_L];
1911 address = ((WORD)HB << 8) + LB;
1912 param1 = Registers[REGISTER_A];
1913 param2 = Memory[address];
1914 temp_word = (WORD)param1 ^ (WORD)param2;
1915 set_flag_n((BYTE)temp_word);
1916 set_flag_z((BYTE)temp_word);
1917 Registers[REGISTER_A] = (BYTE)temp_word;
1918 break;
1919
1920 case 0x54: //TEST Absolute
1921 LB = fetch();
1922 HB = fetch();
1923 address += (WORD)((WORD)HB << 8) + LB;
1924 data = Memory[address];
1925 set_flag_n(data);
1926 set_flag_z(data);
1927 break;
1928
1929 case 0x64: //TEST Absolute X
1930 address += Index_Registers[REGISTER_X];
1931 LB = fetch();
1932 HB = fetch();
1933 address += (WORD)((WORD)HB << 8) + LB;
1934 data = Memory[address];
1935 set_flag_n(data);
1936 set_flag_z(data);
1937 break;
1938
1939 case 0x74: //TEST Absolute Y
1940 address += Index_Registers[REGISTER_Y];
1941 LB = fetch();
1942 HB = fetch();
1943 address += (WORD)((WORD)HB << 8) + LB;
1944 data = Memory[address];
1945 set_flag_n(data);
1946 set_flag_z(data);
1947 break;
1948
1949 case 0x84: //TEST Absolute X,Y
1950 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1951 LB = fetch();
1952 HB = fetch();
1953 address += (WORD)((WORD)HB << 8) + LB;
1954 data = Memory[address];
1955 set_flag_n(data);
1956 set_flag_z(data);
1957 break;
1958
1959 case 0x56: //DEC Absolute
1960 LB = fetch();
1961 HB = fetch();
1962 address += (WORD)((WORD)HB << 8) + LB;
1963 Memory[address]--;
1964 set_flag_n(Memory[address]);
1965 set_flag_z(Memory[address]);
1966 break;
1967
1968 case 0x66: //DEC Absolute X
1969 address += Index_Registers[REGISTER_X];
1970 LB = fetch();
1971 HB = fetch();
1972 address += (WORD)((WORD)HB << 8) + LB;
1973 if (address >= 0 && address < MEMORY_SIZE)
1974 {
1975 Memory[address]--;
1976 }
1977 set_flag_n(Memory[address]);
1978 set_flag_z(Memory[address]);
1979 break;
1980
1981 case 0x76: //DEC Absolute Y
1982 address += Index_Registers[REGISTER_Y];
1983 LB = fetch();
1984 HB = fetch();
1985 address += (WORD)((WORD)HB << 8) + LB;
1986 if (address >= 0 && address < MEMORY_SIZE)
1987 {
1988 Memory[address]--;
1989 }
1990 set_flag_n(Memory[address]);
1991 set_flag_z(Memory[address]);
1992 break;
1993
1994 case 0x86: //DEC Absolute X,Y
1995 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1996 LB = fetch();
1997 HB = fetch();
1998 address += (WORD)((WORD)HB << 8) + LB;
1999 if (address >= 0 && address < MEMORY_SIZE)
2000 {
2001 Memory[address]--;
2002 }
2003 set_flag_n(Memory[address]);
2004 set_flag_z(Memory[address]);
2005 break;
2006
2007 case 0x59: //SAL Absolute
2008 LB = fetch();
2009 HB = fetch();
2010 address = (WORD)((WORD)HB << 8) + LB;
2011 saved_flags = Flags;
2012
2013 if ((Memory[address] & 0x80) == 0x80) {
2014 Flags = Flags | FLAG_C;
2015 }
2016 else {
2017 Flags = Flags & (0xFF - FLAG_C);
2018 }
2019
2020 Memory[address] = (Memory[address] << 1) & 0xFE;
2021
2022 set_flag_n(Memory[address]);
2023 set_flag_z(Memory[address]);
2024 break;
2025
2026 case 0x69: //SAL Absolute X
2027 address += Index_Registers[REGISTER_X];
2028 LB = fetch();
2029 HB = fetch();
2030 address = (WORD)((WORD)HB << 8) + LB;
2031 saved_flags = Flags;
2032
2033 if ((Memory[address] & 0x80) == 0x80) {
2034 Flags = Flags | FLAG_C;
2035 }
2036 else {
2037 Flags = Flags & (0xFF - FLAG_C);
2038 }
2039
2040 Memory[address] = (Memory[address] << 1) & 0xFE;
2041
2042 set_flag_n(Memory[address]);
2043 set_flag_z(Memory[address]);
2044 break;
2045
2046 case 0x79: //SAL Absolute Y
2047 address += Index_Registers[REGISTER_Y];
2048 LB = fetch();
2049 HB = fetch();
2050 address = (WORD)((WORD)HB << 8) + LB;
2051 saved_flags = Flags;
2052
2053 if ((Memory[address] & 0x80) == 0x80) {
2054 Flags = Flags | FLAG_C;
2055 }
2056 else {
2057 Flags = Flags & (0xFF - FLAG_C);
2058 }
2059
2060 Memory[address] = (Memory[address] << 1) & 0xFE;
2061
2062 set_flag_n(Memory[address]);
2063 set_flag_z(Memory[address]);
2064 break;
2065
2066 case 0x89: //SAL Absolute X,Y
2067 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2068 LB = fetch();
2069 HB = fetch();
2070 address = (WORD)((WORD)HB << 8) + LB;
2071 saved_flags = Flags;
2072
2073 if ((Memory[address] & 0x80) == 0x80) {
2074 Flags = Flags | FLAG_C;
2075 }
2076 else {
2077 Flags = Flags & (0xFF - FLAG_C);
2078 }
2079
2080 Memory[address] = (Memory[address] << 1) & 0xFE;
2081
2082 set_flag_n(Memory[address]);
2083 set_flag_z(Memory[address]);
2084 break;
2085
2086 case 0x5A: //SHR Absolute
2087 LB = fetch();
2088 HB = fetch();
2089 address = (WORD)((WORD)HB << 8) + LB;
2090 if ((Memory[address] & 0x01) == 0x01) {
2091 Flags = Flags | FLAG_C;
2092 }
2093 else {
2094 Flags = Flags & (0xFF - FLAG_C);
2095 }
2096 HB = Memory[address];
2097 Memory[address] = (Memory[address] >> 1) & 0x7F;
2098 if ((HB & 0x80) == 0x80) {
2099 Memory[address] = Memory[address] | 0x80;
2100 }
2101 set_flag_n(Memory[address]);
2102 set_flag_z(Memory[address]);
2103 break;
2104
2105 case 0x6A: //SHR Absolute X
2106 address += Index_Registers[REGISTER_X];
2107 LB = fetch();
2108 HB = fetch();
2109 address = (WORD)((WORD)HB << 8) + LB;
2110 if ((Memory[address] & 0x01) == 0x01) {
2111 Flags = Flags | FLAG_C;
2112 }
2113 else {
2114 Flags = Flags & (0xFF - FLAG_C);
2115 }
2116 HB = Memory[address];
2117 Memory[address] = (Memory[address] >> 1) & 0x7F;
2118 if ((HB & 0x80) == 0x80) {
2119 Memory[address] = Memory[address] | 0x80;
2120 }
2121 set_flag_n(Memory[address]);
2122 set_flag_z(Memory[address]);
2123 break;
2124
2125 case 0x7A: //SHR Absolute Y
2126 address += Index_Registers[REGISTER_Y];
2127 LB = fetch();
2128 HB = fetch();
2129 address = (WORD)((WORD)HB << 8) + LB;
2130 if ((Memory[address] & 0x01) == 0x01) {
2131 Flags = Flags | FLAG_C;
2132 }
2133 else {
2134 Flags = Flags & (0xFF - FLAG_C);
2135 }
2136 HB = Memory[address];
2137 Memory[address] = (Memory[address] >> 1) & 0x7F;
2138 if ((HB & 0x80) == 0x80) {
2139 Memory[address] = Memory[address] | 0x80;
2140 }
2141 set_flag_n(Memory[address]);
2142 set_flag_z(Memory[address]);
2143
2144 break;
2145
2146 case 0x8A: //SHR Absolute X,Y
2147 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2148 LB = fetch();
2149 HB = fetch();
2150 address = (WORD)((WORD)HB << 8) + LB;
2151 if ((Memory[address] & 0x01) == 0x01) {
2152 Flags = Flags | FLAG_C;
2153 }
2154 else {
2155 Flags = Flags & (0xFF - FLAG_C);
2156 }
2157 HB = Memory[address];
2158 Memory[address] = (Memory[address] >> 1) & 0x7F;
2159 if ((HB & 0x80) == 0x80) {
2160 Memory[address] = Memory[address] | 0x80;
2161 }
2162 set_flag_n(Memory[address]);
2163 set_flag_z(Memory[address]);
2164 break;
2165
2166 case 0x5C: //NEG Absolute
2167 LB = fetch();
2168 HB = fetch();
2169 address += (WORD)((WORD)HB << 8) + LB;
2170 Memory[address] = 0 - Memory[address];
2171 set_flag_n(Memory[address]);
2172 set_flag_z(Memory[address]);
2173 break;
2174
2175 case 0x6C: //NEG Absolute X
2176 address += Index_Registers[REGISTER_X];
2177
2178 LB = fetch();
2179 HB = fetch();
2180 address += (WORD)((WORD)HB << 8) + LB;
2181 Memory[address] = 0 - Memory[address];
2182 set_flag_n(Memory[address]);
2183 set_flag_z(Memory[address]);
2184 break;
2185
2186 case 0x7C: //NEG Absolute Y
2187 address += Index_Registers[REGISTER_Y];
2188
2189 LB = fetch();
2190 HB = fetch();
2191 address += (WORD)((WORD)HB << 8) + LB;
2192
2193 Memory[address] = 0 - Memory[address];
2194 set_flag_n(Memory[address]);
2195 set_flag_z(Memory[address]);
2196 break;
2197
2198 case 0x8C: //NEG Absolute X,Y
2199 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2200 LB = fetch();
2201 HB = fetch();
2202 address += (WORD)((WORD)HB << 8) + LB;
2203 Memory[address] = 0 - Memory[address];
2204
2205 set_flag_n(Memory[address]);
2206 set_flag_z(Memory[address]);
2207 break;
2208
2209 case 0x02: //SWI (IMPL)
2210 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2211 StackPointer--;
2212 Memory[StackPointer] = Registers[REGISTER_A];
2213 }
2214 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2215 StackPointer--;
2216 Memory[StackPointer] = (BYTE)ProgramCounter;
2217 }
2218 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2219 StackPointer--;
2220 Memory[StackPointer] = (BYTE)(ProgramCounter >> 8);
2221 }
2222 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2223 StackPointer--;
2224 Memory[StackPointer] = Flags;
2225 }
2226 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2227 StackPointer--;
2228 Memory[StackPointer] = Registers[REGISTER_B];
2229 }
2230 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2231 StackPointer--;
2232 Memory[StackPointer] = Registers[REGISTER_C];
2233 }
2234 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2235 StackPointer--;
2236 Memory[StackPointer] = Registers[REGISTER_L];
2237 }
2238 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2239 StackPointer--;
2240 Memory[StackPointer] = Registers[REGISTER_H];
2241 }
2242
2243 break;
2244
2245 case 0x03: //RTI (IMPL)
2246 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2247 Registers[REGISTER_H] = Memory[StackPointer];
2248 StackPointer++;
2249 }
2250 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2251 Registers[REGISTER_L] = Memory[StackPointer];
2252 StackPointer++;
2253 }
2254 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2255 Registers[REGISTER_C] = Memory[StackPointer];
2256 StackPointer++;
2257 }
2258 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2259 Registers[REGISTER_B] = Memory[StackPointer];
2260 StackPointer++;
2261 }
2262 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2263 Flags = Memory[StackPointer];
2264 StackPointer++;
2265 }
2266 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2267 ProgramCounter = (WORD)(Memory[StackPointer] << 8);
2268 StackPointer++;
2269 }
2270 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2271 ProgramCounter += Memory[StackPointer];
2272 StackPointer++;
2273 }
2274 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2275 Registers[REGISTER_A] = Memory[StackPointer];
2276 StackPointer++;
2277 }
2278 break;
2279
2280 case 0x98: //RCLA
2281 saved_flags = Flags;
2282
2283 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
2284 Flags = Flags | FLAG_C;
2285 }
2286 else {
2287 Flags = Flags & (0xFF - FLAG_C);
2288 }
2289 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
2290
2291 if ((saved_flags & FLAG_C) == FLAG_C) {
2292 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
2293 }
2294 set_flag_n((BYTE)Registers[REGISTER_A]);
2295 set_flag_z((BYTE)Registers[REGISTER_A]);
2296 break;
2297
2298 case 0x99: //SALA
2299 saved_flags = Flags;
2300
2301 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
2302 Flags = Flags | FLAG_C;
2303 }
2304 else {
2305 Flags = Flags & (0xFF - FLAG_C);
2306 }
2307 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
2308
2309 set_flag_n((BYTE)Registers[REGISTER_A]);
2310 set_flag_z((BYTE)Registers[REGISTER_A]);
2311 break;
2312
2313 case 0x9A: //SHRA
2314 if ((Registers[REGISTER_A] & 0x01) == 0x01)
2315 {
2316 Flags = Flags | FLAG_C;
2317 }
2318 else
2319 {
2320 Flags = Flags & (0xFF - FLAG_C);
2321 }
2322 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
2323 if ((Flags & FLAG_N) == FLAG_N)
2324 {
2325 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
2326 }
2327 set_flag_n(Registers[REGISTER_A]);
2328 set_flag_z(Registers[REGISTER_A]);
2329 break;
2330 case 0x17: //NOP
2331 break;
2332
2333 case 0x18: //WAI
2334 halt = true;
2335 break;
2336 case 0x1C: //ADI Immediate
2337 data = fetch();
2338 temp_word = (WORD)Registers[REGISTER_A] + data;
2339 if ((Flags & FLAG_C) != 0)
2340 {
2341 temp_word++;
2342 }
2343 if (temp_word >= 0x100)
2344 {
2345 Flags = Flags | FLAG_C;
2346 }
2347 else
2348 {
2349 Flags = Flags & (0xFF - FLAG_C);
2350 }
2351 set_flag_n((BYTE)temp_word);
2352 set_flag_z((BYTE)temp_word);
2353 Registers[REGISTER_A] = (BYTE)temp_word;
2354 break;
2355 ////////////////////CPI
2356 case 0x1D: // CPI
2357 data = fetch();
2358
2359 temp_word = (WORD)data - (WORD)Registers[REGISTER_A];
2360
2361 if (temp_word >= 0x100) {
2362 Flags = Flags | FLAG_C; // Set carry flag
2363 }
2364 else {
2365 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
2366 }
2367
2368 set_flag_z((BYTE)temp_word);
2369 set_flag_n((BYTE)temp_word);
2370 break;
2371 case 0x1E: //ANI Immediate
2372 data = fetch();
2373 temp_word = (WORD)Registers[REGISTER_A] & data;
2374
2375 if (temp_word >= 0x100)
2376 {
2377 Flags = Flags | FLAG_C;
2378 }
2379 else
2380 {
2381 Flags = Flags & (0xFF - FLAG_C);
2382 }
2383 set_flag_n((BYTE)temp_word);
2384 set_flag_z((BYTE)temp_word);
2385 Registers[REGISTER_A] = (BYTE)temp_word;
2386
2387 break;
2388 case 0x94: //TESTA Register A
2389 set_flag_n(Registers[REGISTER_A]);
2390 set_flag_z(Registers[REGISTER_A]);
2391 break;
2392 case 0x96: //DECA Register A
2393 Registers[REGISTER_A]--;
2394 set_flag_n(Registers[REGISTER_A]);
2395 set_flag_z(Registers[REGISTER_A]);
2396 break;
2397 case 0x57: //RR Absolute
2398 LB = fetch();
2399 HB = fetch();
2400 address += (WORD)((WORD)HB << 8) + LB;
2401 saved_flags = Flags;
2402
2403 if ((Memory[address] & 0x01) == 0x01) {
2404 Flags = Flags | FLAG_C;
2405 }
2406 else {
2407 Flags = Flags & (0xFF - FLAG_C);
2408 }
2409 Memory[address] = (Memory[address] >> 1) & 0x7F;
2410
2411 if ((saved_flags & FLAG_C) == FLAG_C) {
2412 Memory[address] = Memory[address] | 0x80;
2413 }
2414 set_flag_n((BYTE)Memory[address]);
2415 set_flag_z((BYTE)Memory[address]);
2416 break;
2417 case 0x67: //RR Absolute X
2418 address += Index_Registers[REGISTER_X];
2419
2420 LB = fetch();
2421 HB = fetch();
2422 address += (WORD)((WORD)HB << 8) + LB;
2423 saved_flags = Flags;
2424
2425 if ((Memory[address] & 0x01) == 0x01) {
2426 Flags = Flags | FLAG_C;
2427 }
2428 else {
2429 Flags = Flags & (0xFF - FLAG_C);
2430 }
2431 Memory[address] = (Memory[address] >> 1) & 0x7F;
2432
2433 if ((saved_flags & FLAG_C) == FLAG_C) {
2434 Memory[address] = Memory[address] | 0x80;
2435 }
2436 set_flag_n((BYTE)Memory[address]);
2437 set_flag_z((BYTE)Memory[address]);
2438
2439 break;
2440 case 0x77: //RR Absolute Y
2441 address += Index_Registers[REGISTER_Y];
2442
2443 LB = fetch();
2444 HB = fetch();
2445 address += (WORD)((WORD)HB << 8) + LB;
2446 saved_flags = Flags;
2447
2448 if ((Memory[address] & 0x01) == 0x01) {
2449 Flags = Flags | FLAG_C;
2450 }
2451 else {
2452 Flags = Flags & (0xFF - FLAG_C);
2453 }
2454 Memory[address] = (Memory[address] >> 1) & 0x7F;
2455
2456 if ((saved_flags & FLAG_C) == FLAG_C) {
2457 Memory[address] = Memory[address] | 0x80;
2458 }
2459 set_flag_n((BYTE)Memory[address]);
2460 set_flag_z((BYTE)Memory[address]);
2461
2462 break;
2463 case 0x87: //RR Absolute X,Y
2464 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2465 LB = fetch();
2466 HB = fetch();
2467 address += (WORD)((WORD)HB << 8) + LB;
2468 saved_flags = Flags;
2469
2470 if ((Memory[address] & 0x01) == 0x01) {
2471 Flags = Flags | FLAG_C;
2472 }
2473 else {
2474 Flags = Flags & (0xFF - FLAG_C);
2475 }
2476 Memory[address] = (Memory[address] >> 1) & 0x7F;
2477
2478 if ((saved_flags & FLAG_C) == FLAG_C) {
2479 Memory[address] = Memory[address] | 0x80;
2480 }
2481 set_flag_n((BYTE)Memory[address]);
2482 set_flag_z((BYTE)Memory[address]);
2483
2484 break;
2485 case 0x97: //RRA Register A
2486 saved_flags = Flags;
2487
2488 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
2489 Flags = Flags | FLAG_C;
2490 }
2491 else {
2492 Flags = Flags & (0xFF - FLAG_C);
2493 }
2494 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
2495
2496 if ((saved_flags & FLAG_C) == FLAG_C) {
2497 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
2498 }
2499 set_flag_n((BYTE)Registers[REGISTER_A]);
2500 set_flag_z((BYTE)Registers[REGISTER_A]);
2501 break;
2502 case 0x58: //RCL Absolute
2503 LB = fetch();
2504 HB = fetch();
2505 address += (WORD)((WORD)HB << 8) + LB;
2506 saved_flags = Flags;
2507
2508 if ((Memory[address] & 0x80) == 0x80) {
2509 Flags = Flags | FLAG_C;
2510 }
2511 else {
2512 Flags = Flags & (0xFF - FLAG_C);
2513 }
2514 Memory[address] = (Memory[address] << 1) & 0xFE;
2515
2516 if ((saved_flags & FLAG_C) == FLAG_C) {
2517 Memory[address] = Memory[address] | 0x01;
2518 }
2519 set_flag_n((BYTE)Memory[address]);
2520 set_flag_z((BYTE)Memory[address]);
2521 break;
2522 case 0x68: //RCL Absolute X
2523 address += Index_Registers[REGISTER_X];
2524
2525 LB = fetch();
2526 HB = fetch();
2527 address += (WORD)((WORD)HB << 8) + LB;
2528 saved_flags = Flags;
2529
2530 if ((Memory[address] & 0x80) == 0x80) {
2531 Flags = Flags | FLAG_C;
2532 }
2533 else {
2534 Flags = Flags & (0xFF - FLAG_C);
2535 }
2536 Memory[address] = (Memory[address] << 1) & 0xFE;
2537
2538 if ((saved_flags & FLAG_C) == FLAG_C) {
2539 Memory[address] = Memory[address] | 0x01;
2540 }
2541 set_flag_n((BYTE)Memory[address]);
2542 set_flag_z((BYTE)Memory[address]);
2543 break;
2544 case 0x78: //RCL Absolute Y
2545 address += Index_Registers[REGISTER_Y];
2546
2547 LB = fetch();
2548 HB = fetch();
2549 address += (WORD)((WORD)HB << 8) + LB;
2550 saved_flags = Flags;
2551
2552 if ((Memory[address] & 0x80) == 0x80) {
2553 Flags = Flags | FLAG_C;
2554 }
2555 else {
2556 Flags = Flags & (0xFF - FLAG_C);
2557 }
2558 Memory[address] = (Memory[address] << 1) & 0xFE;
2559
2560 if ((saved_flags & FLAG_C) == FLAG_C) {
2561 Memory[address] = Memory[address] | 0x01;
2562 }
2563 set_flag_n((BYTE)Memory[address]);
2564 set_flag_z((BYTE)Memory[address]);
2565 break;
2566 case 0x88: //RCL Absolute X,Y
2567 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2568
2569 LB = fetch();
2570 HB = fetch();
2571 address += (WORD)((WORD)HB << 8) + LB;
2572 saved_flags = Flags;
2573
2574 if ((Memory[address] & 0x80) == 0x80) {
2575 Flags = Flags | FLAG_C;
2576 }
2577 else {
2578 Flags = Flags & (0xFF - FLAG_C);
2579 }
2580 Memory[address] = (Memory[address] << 1) & 0xFE;
2581
2582 if ((saved_flags & FLAG_C) == FLAG_C) {
2583 Memory[address] = Memory[address] | 0x01;
2584 }
2585 set_flag_n((BYTE)Memory[address]);
2586 set_flag_z((BYTE)Memory[address]);
2587 break;
2588 case 0x5B: //COM Absolute
2589 LB = fetch();
2590 HB = fetch();
2591 address += (WORD)((WORD)HB << 8) + LB;
2592 Memory[address] = Memory[address] ^ 0xFFFF;
2593
2594 Flags = Flags | FLAG_C;
2595 set_flag_n(Memory[address]);
2596 set_flag_z(Memory[address]);
2597 break;
2598 case 0x6B: //COM Absolute X
2599 address += Index_Registers[REGISTER_X];
2600
2601 LB = fetch();
2602 HB = fetch();
2603 address += (WORD)((WORD)HB << 8) + LB;
2604 Memory[address] = Memory[address] ^ 0xFFFF;
2605
2606 Flags = Flags | FLAG_C;
2607 set_flag_n(Memory[address]);
2608 set_flag_z(Memory[address]);
2609 break;
2610 case 0x7B: //COM Absolute Y
2611 address += Index_Registers[REGISTER_Y];
2612
2613 LB = fetch();
2614 HB = fetch();
2615 address += (WORD)((WORD)HB << 8) + LB;
2616 Memory[address] = Memory[address] ^ 0xFFFF;
2617
2618 Flags = Flags | FLAG_C;
2619 set_flag_n(Memory[address]);
2620 set_flag_z(Memory[address]);
2621 break;
2622 case 0x8B: //COM Absolute X,Y
2623 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2624 LB = fetch();
2625 HB = fetch();
2626 address += (WORD)((WORD)HB << 8) + LB;
2627 Memory[address] = Memory[address] ^ 0xFFFF;
2628
2629 Flags = Flags | FLAG_C;
2630 set_flag_n(Memory[address]);
2631 set_flag_z(Memory[address]);
2632 break;
2633 case 0x9C: //NEGA Register A
2634 Registers[REGISTER_A] = Registers[REGISTER_A] ^ 0xFF;
2635 Registers[REGISTER_A]++;
2636
2637
2638 set_flag_n(Registers[REGISTER_A]);
2639 set_flag_z(Registers[REGISTER_A]);
2640
2641 break;
2642 case 0x5D: //RAL Absolute
2643 LB = fetch();
2644 HB = fetch();
2645 address += (WORD)((WORD)HB << 8) + LB;
2646
2647 saved_flags = Flags;
2648
2649 if ((Memory[address] & 0x80) == 0x80) {
2650 Flags = Flags | FLAG_C;
2651 }
2652 else {
2653 Flags = Flags & (0xFF - FLAG_C);
2654 }
2655 Memory[address] = (Memory[address] << 1) & 0xFE;
2656
2657 if ((Flags & FLAG_C) == FLAG_C) {
2658 Memory[address] = Memory[address] | 0x01;
2659 }
2660 Flags = saved_flags;
2661 set_flag_n((BYTE)Memory[address]);
2662 set_flag_z((BYTE)Memory[address]);
2663 break;
2664 case 0x6D: //RAL Absolute X
2665 address += Index_Registers[REGISTER_X];
2666
2667 LB = fetch();
2668 HB = fetch();
2669 address += (WORD)((WORD)HB << 8) + LB;
2670
2671 saved_flags = Flags;
2672
2673 if ((Memory[address] & 0x80) == 0x80) {
2674 Flags = Flags | FLAG_C;
2675 }
2676 else {
2677 Flags = Flags & (0xFF - FLAG_C);
2678 }
2679 Memory[address] = (Memory[address] << 1) & 0xFE;
2680
2681 if ((Flags & FLAG_C) == FLAG_C) {
2682 Memory[address] = Memory[address] | 0x01;
2683 }
2684 Flags = saved_flags;
2685 set_flag_n((BYTE)Memory[address]);
2686 set_flag_z((BYTE)Memory[address]);
2687 break;
2688 case 0x7D: //RAL Absolute Y
2689 address += Index_Registers[REGISTER_Y];
2690
2691 LB = fetch();
2692 HB = fetch();
2693 address += (WORD)((WORD)HB << 8) + LB;
2694
2695 saved_flags = Flags;
2696
2697 if ((Memory[address] & 0x80) == 0x80) {
2698 Flags = Flags | FLAG_C;
2699 }
2700 else {
2701 Flags = Flags & (0xFF - FLAG_C);
2702 }
2703 Memory[address] = (Memory[address] << 1) & 0xFE;
2704
2705 if ((Flags & FLAG_C) == FLAG_C) {
2706 Memory[address] = Memory[address] | 0x01;
2707 }
2708 Flags = saved_flags;
2709 set_flag_n((BYTE)Memory[address]);
2710 set_flag_z((BYTE)Memory[address]);
2711 break;
2712 case 0x8D: //RAL Absolute X,Y
2713 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2714 LB = fetch();
2715 HB = fetch();
2716 address += (WORD)((WORD)HB << 8) + LB;
2717
2718 saved_flags = Flags;
2719
2720 if ((Memory[address] & 0x80) == 0x80) {
2721 Flags = Flags | FLAG_C;
2722 }
2723 else {
2724 Flags = Flags & (0xFF - FLAG_C);
2725 }
2726 Memory[address] = (Memory[address] << 1) & 0xFE;
2727
2728 if ((Flags & FLAG_C) == FLAG_C) {
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 case 0x9D: //RALA Register A
2736 saved_flags = Flags;
2737
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
2746 if ((Flags & FLAG_C) == FLAG_C) {
2747 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
2748 }
2749 Flags = saved_flags;
2750 set_flag_n((BYTE)Registers[REGISTER_A]);
2751 set_flag_z((BYTE)Registers[REGISTER_A]);
2752 break;
2753 case 0x5E: //ROR Absolute
2754 LB = fetch();
2755 HB = fetch();
2756 address += (WORD)((WORD)HB << 8) + LB;
2757 saved_flags = Flags;
2758
2759 if ((Memory[address] & 0x01) == 0x01) {
2760 Flags = Flags | FLAG_C;
2761 }
2762 else {
2763 Flags = Flags & (0xFF - FLAG_C);
2764 }
2765 Memory[address] = (Memory[address] >> 1) & 0x7F;
2766
2767 if ((Flags & FLAG_C) == FLAG_C) {
2768 Memory[address] = Memory[address] | 0x80;
2769 }
2770 Flags = saved_flags;
2771 set_flag_n((BYTE)Memory[address]);
2772 set_flag_z((BYTE)Memory[address]);
2773 break;
2774 case 0x6E: //ROR Absolute X
2775 address += Index_Registers[REGISTER_X];
2776
2777 LB = fetch();
2778 HB = fetch();
2779 address += (WORD)((WORD)HB << 8) + LB;
2780 saved_flags = Flags;
2781
2782 if ((Memory[address] & 0x01) == 0x01) {
2783 Flags = Flags | FLAG_C;
2784 }
2785 else {
2786 Flags = Flags & (0xFF - FLAG_C);
2787 }
2788 Memory[address] = (Memory[address] >> 1) & 0x7F;
2789
2790 if ((Flags & FLAG_C) == FLAG_C) {
2791 Memory[address] = Memory[address] | 0x80;
2792 }
2793 Flags = saved_flags;
2794 set_flag_n((BYTE)Memory[address]);
2795 set_flag_z((BYTE)Memory[address]);
2796 break;
2797 case 0x7E: //ROR Absolute Y
2798 address += Index_Registers[REGISTER_Y];
2799
2800 LB = fetch();
2801 HB = fetch();
2802 address += (WORD)((WORD)HB << 8) + LB;
2803 saved_flags = Flags;
2804
2805 if ((Memory[address] & 0x01) == 0x01) {
2806 Flags = Flags | FLAG_C;
2807 }
2808 else {
2809 Flags = Flags & (0xFF - FLAG_C);
2810 }
2811 Memory[address] = (Memory[address] >> 1) & 0x7F;
2812
2813 if ((Flags & FLAG_C) == FLAG_C) {
2814 Memory[address] = Memory[address] | 0x80;
2815 }
2816 Flags = saved_flags;
2817 set_flag_n((BYTE)Memory[address]);
2818 set_flag_z((BYTE)Memory[address]);
2819 break;
2820 case 0x8E: //ROR Absolute X,Y
2821 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2822 LB = fetch();
2823 HB = fetch();
2824 address += (WORD)((WORD)HB << 8) + LB;
2825 saved_flags = Flags;
2826
2827 if ((Memory[address] & 0x01) == 0x01) {
2828 Flags = Flags | FLAG_C;
2829 }
2830 else {
2831 Flags = Flags & (0xFF - FLAG_C);
2832 }
2833 Memory[address] = (Memory[address] >> 1) & 0x7F;
2834
2835 if ((Flags & FLAG_C) == FLAG_C) {
2836 Memory[address] = Memory[address] | 0x80;
2837 }
2838 Flags = saved_flags;
2839 set_flag_n((BYTE)Memory[address]);
2840 set_flag_z((BYTE)Memory[address]);
2841
2842 break;
2843 case 0x9E: //RORA Register A
2844 saved_flags = Flags;
2845
2846 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
2847 Flags = Flags | FLAG_C;
2848 }
2849 else {
2850 Flags = Flags & (0xFF - FLAG_C);
2851 }
2852 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
2853
2854 if ((Flags & FLAG_C) == FLAG_C) {
2855 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
2856 }
2857 Flags = saved_flags;
2858 set_flag_n((BYTE)Registers[REGISTER_A]);
2859 set_flag_z((BYTE)Registers[REGISTER_A]);
2860 break;
2861 }
2862}
2863
2864void Group_2_Move(BYTE opcode) {
2865
2866 BYTE source = opcode >> 4;
2867 BYTE destination = opcode & 0x0F;
2868 WORD address = 0;
2869
2870 int destReg = 0;
2871 int sourceReg = 0;
2872
2873 switch (destination)
2874 {
2875 case 0x00:
2876 destReg = REGISTER_A;
2877 break;
2878
2879 case 0x01:
2880 destReg = REGISTER_B;
2881 break;
2882
2883 case 0x02:
2884 destReg = REGISTER_C;
2885 break;
2886
2887 case 0x03:
2888 destReg = REGISTER_L;
2889 break;
2890
2891 case 0x04:
2892 destReg = REGISTER_H;
2893 break;
2894
2895 case 0x05:
2896 destReg = REGISTER_M;
2897 break;
2898
2899 case 0xA0:
2900 destReg = REGISTER_A;
2901 break;
2902
2903 case 0xB0:
2904 destReg = REGISTER_A;
2905 break;
2906
2907 case 0xC0:
2908 destReg = REGISTER_A;
2909 break;
2910
2911 case 0xD0:
2912 destReg = REGISTER_A;
2913 break;
2914
2915 case 0xE0:
2916 destReg = REGISTER_A;
2917 break;
2918
2919 case 0xF0:
2920 destReg = REGISTER_A;
2921 break;
2922
2923 case 0xA1:
2924 destReg = REGISTER_B;
2925 break;
2926
2927 case 0xB1:
2928 destReg = REGISTER_B;
2929 break;
2930
2931 case 0xC1:
2932 destReg = REGISTER_B;
2933 break;
2934
2935 case 0xD1:
2936 destReg = REGISTER_B;
2937 break;
2938
2939 case 0xE1:
2940 destReg = REGISTER_B;
2941 break;
2942
2943 case 0xF1:
2944 destReg = REGISTER_B;
2945 break;
2946
2947 case 0xA2:
2948 destReg = REGISTER_C;
2949 break;
2950
2951 case 0xB2:
2952 destReg = REGISTER_C;
2953 break;
2954
2955 case 0xC2:
2956 destReg = REGISTER_C;
2957 break;
2958
2959 case 0xD2:
2960 destReg = REGISTER_C;
2961 break;
2962
2963 case 0xE2:
2964 destReg = REGISTER_C;
2965 break;
2966
2967 case 0xF2:
2968 destReg = REGISTER_C;
2969 break;
2970
2971 case 0xA3:
2972 destReg = REGISTER_L;
2973 break;
2974
2975 case 0xB3:
2976 destReg = REGISTER_L;
2977 break;
2978
2979 case 0xC3:
2980 destReg = REGISTER_L;
2981 break;
2982
2983 case 0xD3:
2984 destReg = REGISTER_L;
2985 break;
2986
2987 case 0xE3:
2988 destReg = REGISTER_L;
2989 break;
2990
2991 case 0xF3:
2992 destReg = REGISTER_L;
2993 break;
2994
2995 case 0xA4:
2996 destReg = REGISTER_H;
2997 break;
2998
2999 case 0xB4:
3000 destReg = REGISTER_H;
3001 break;
3002
3003 case 0xC4:
3004 destReg = REGISTER_H;
3005 break;
3006
3007 case 0xD4:
3008 destReg = REGISTER_H;
3009 break;
3010
3011 case 0xE4:
3012 destReg = REGISTER_H;
3013 break;
3014
3015 case 0xF4:
3016 destReg = REGISTER_H;
3017 break;
3018
3019 case 0xA5:
3020 destReg = REGISTER_M;
3021 break;
3022
3023 case 0xB5:
3024 destReg = REGISTER_M;
3025 break;
3026
3027 case 0xC5:
3028 destReg = REGISTER_M;
3029 break;
3030
3031 case 0xD5:
3032 destReg = REGISTER_M;
3033 break;
3034
3035 case 0xE5:
3036 destReg = REGISTER_M;
3037 break;
3038 }
3039
3040 switch (source)
3041 {
3042 case 0xA0:
3043 sourceReg = REGISTER_A;
3044 break;
3045
3046 case 0xA1:
3047 sourceReg = REGISTER_A;
3048 break;
3049
3050 case 0xA2:
3051 sourceReg = REGISTER_A;
3052 break;
3053
3054 case 0xA3:
3055 sourceReg = REGISTER_A;
3056 break;
3057
3058 case 0xA4:
3059 sourceReg = REGISTER_A;
3060 break;
3061
3062 case 0xA5:
3063 sourceReg = REGISTER_A;
3064 break;
3065
3066 case 0xB0:
3067 sourceReg = REGISTER_B;
3068 break;
3069
3070 case 0xB1:
3071 sourceReg = REGISTER_B;
3072 break;
3073
3074 case 0xB2:
3075 sourceReg = REGISTER_B;
3076 break;
3077
3078 case 0xB3:
3079 sourceReg = REGISTER_B;
3080 break;
3081
3082 case 0xB4:
3083 sourceReg = REGISTER_B;
3084 break;
3085
3086 case 0xB5:
3087 sourceReg = REGISTER_B;
3088 break;
3089
3090 case 0xC0:
3091 sourceReg = REGISTER_C;
3092 break;
3093
3094 case 0xC1:
3095 sourceReg = REGISTER_C;
3096 break;
3097
3098 case 0xC2:
3099 sourceReg = REGISTER_C;
3100 break;
3101
3102 case 0xC3:
3103 sourceReg = REGISTER_C;
3104 break;
3105
3106 case 0xC4:
3107 sourceReg = REGISTER_C;
3108 break;
3109
3110 case 0xC5:
3111 sourceReg = REGISTER_C;
3112 break;
3113
3114 case 0xD0:
3115 sourceReg = REGISTER_L;
3116 break;
3117
3118 case 0xD1:
3119 sourceReg = REGISTER_L;
3120 break;
3121
3122 case 0xD2:
3123 sourceReg = REGISTER_L;
3124 break;
3125
3126 case 0xD3:
3127 sourceReg = REGISTER_L;
3128 break;
3129
3130 case 0xD4:
3131 sourceReg = REGISTER_L;
3132 break;
3133
3134 case 0xD5:
3135 sourceReg = REGISTER_L;
3136 break;
3137
3138 case 0xE0:
3139 sourceReg = REGISTER_H;
3140 break;
3141
3142 case 0xE1:
3143 sourceReg = REGISTER_H;
3144 break;
3145
3146 case 0xE2:
3147 sourceReg = REGISTER_H;
3148 break;
3149
3150 case 0xE3:
3151 sourceReg = REGISTER_H;
3152 break;
3153
3154 case 0xE4:
3155 sourceReg = REGISTER_H;
3156 break;
3157
3158 case 0xE5:
3159 sourceReg = REGISTER_H;
3160 break;
3161
3162 case 0xF0:
3163 sourceReg = REGISTER_M;
3164 break;
3165
3166 case 0xF1:
3167 sourceReg = REGISTER_M;
3168 break;
3169
3170 case 0xF2:
3171 sourceReg = REGISTER_M;
3172 break;
3173
3174 case 0xF3:
3175 sourceReg = REGISTER_M;
3176 break;
3177
3178 case 0xF4:
3179 sourceReg = REGISTER_M;
3180 break;
3181
3182 case 0x0A:
3183 sourceReg = REGISTER_A;
3184 break;
3185
3186 case 0x0B:
3187 sourceReg = REGISTER_B;
3188 break;
3189
3190 case 0x0C:
3191 sourceReg = REGISTER_C;
3192 break;
3193
3194 case 0x0D:
3195 sourceReg = REGISTER_L;
3196 break;
3197
3198 case 0x0E:
3199 sourceReg = REGISTER_H;
3200 break;
3201
3202 case 0x0F:
3203 sourceReg = REGISTER_M;
3204 break;
3205 }
3206
3207 if (sourceReg == REGISTER_M) {
3208
3209 address = Registers[REGISTER_L];
3210 address += (WORD)Registers[REGISTER_H] << 8;
3211
3212 if (address >= 0 && address <= MEMORY_SIZE) {
3213
3214 Registers[REGISTER_M] = Memory[address];
3215
3216 }
3217 }
3218
3219 if (destReg == REGISTER_M) {
3220
3221 address = Registers[REGISTER_L];
3222 address += (WORD)Registers[REGISTER_H] << 8;
3223
3224 if (address >= 0 && address <= MEMORY_SIZE) {
3225
3226 Memory[address] = Registers[sourceReg];
3227
3228 }
3229 }
3230 else {
3231 Registers[destReg] = Registers[sourceReg];
3232 }
3233}
3234
3235void execute(BYTE opcode)
3236{
3237
3238 BYTE source = opcode >> 4;
3239 BYTE destination = opcode & 0x0F;
3240
3241 if (((source >= 0x0A) && (source <= 0xF5)) && ((destination >= 0x00) && (destination <= 0x05))) {
3242 Group_2_Move(opcode);
3243 }
3244 else
3245 {
3246 Group_1(opcode);
3247 }
3248}
3249
3250void emulate()
3251{
3252 BYTE opcode;
3253 int sanity;
3254
3255 ProgramCounter = 0;
3256 halt = false;
3257 memory_in_range = true;
3258 sanity = 0;
3259
3260 printf(" A B C L H X Y SP\n");
3261
3262 while ((!halt) && (memory_in_range)) {
3263 printf("%04X ", ProgramCounter); // Print current address
3264 opcode = fetch();
3265 execute(opcode);
3266
3267 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
3268
3269 printf("%02X ", Registers[REGISTER_A]);
3270 printf("%02X ", Registers[REGISTER_B]);
3271 printf("%02X ", Registers[REGISTER_C]);
3272 printf("%02X ", Registers[REGISTER_L]);
3273 printf("%02X ", Registers[REGISTER_H]);
3274 printf("%02X ", Index_Registers[REGISTER_X]);
3275 printf("%02X ", Index_Registers[REGISTER_Y]);
3276 printf("%04X ", StackPointer); // Print Stack Pointer
3277
3278 if ((Flags & FLAG_Z) == FLAG_Z)
3279 {
3280 printf("Z=1 ");
3281 }
3282 else
3283 {
3284 printf("Z=0 ");
3285 }
3286 if ((Flags & FLAG_I) == FLAG_I)
3287 {
3288 printf("I=1 ");
3289 }
3290 else
3291 {
3292 printf("I=0 ");
3293 }
3294 if ((Flags & FLAG_N) == FLAG_N)
3295 {
3296 printf("N=1 ");
3297 }
3298 else
3299 {
3300 printf("N=0 ");
3301 }
3302 if ((Flags & FLAG_C) == FLAG_C)
3303 {
3304 printf("C=1 ");
3305 }
3306 else
3307 {
3308 printf("C=0 ");
3309 }
3310
3311 printf("\n"); // New line
3312 sanity++;
3313 if (sanity > 200) halt = true;
3314
3315 }
3316
3317 printf("\n"); // New line
3318}
3319
3320
3321////////////////////////////////////////////////////////////////////////////////
3322// Simulator/Emulator (End) //
3323////////////////////////////////////////////////////////////////////////////////
3324
3325
3326void initialise_filenames() {
3327 int i;
3328
3329 for (i = 0; i < MAX_FILENAME_SIZE; i++) {
3330 hex_file[i] = '\0';
3331 trc_file[i] = '\0';
3332 }
3333}
3334
3335
3336
3337
3338int find_dot_position(char *filename) {
3339 int dot_position;
3340 int i;
3341 char chr;
3342
3343 dot_position = 0;
3344 i = 0;
3345 chr = filename[i];
3346
3347 while (chr != '\0') {
3348 if (chr == '.') {
3349 dot_position = i;
3350 }
3351 i++;
3352 chr = filename[i];
3353 }
3354
3355 return (dot_position);
3356}
3357
3358
3359int find_end_position(char *filename) {
3360 int end_position;
3361 int i;
3362 char chr;
3363
3364 end_position = 0;
3365 i = 0;
3366 chr = filename[i];
3367
3368 while (chr != '\0') {
3369 end_position = i;
3370 i++;
3371 chr = filename[i];
3372 }
3373
3374 return (end_position);
3375}
3376
3377
3378bool file_exists(char *filename) {
3379 bool exists;
3380 FILE *ifp;
3381
3382 exists = false;
3383
3384 if ((ifp = fopen(filename, "r")) != NULL) {
3385 exists = true;
3386
3387 fclose(ifp);
3388 }
3389
3390 return (exists);
3391}
3392
3393
3394
3395void create_file(char *filename) {
3396 FILE *ofp;
3397
3398 if ((ofp = fopen(filename, "w")) != NULL) {
3399 fclose(ofp);
3400 }
3401}
3402
3403
3404
3405bool getline(FILE *fp, char *buffer) {
3406 bool rc;
3407 bool collect;
3408 char c;
3409 int i;
3410
3411 rc = false;
3412 collect = true;
3413
3414 i = 0;
3415 while (collect) {
3416 c = getc(fp);
3417
3418 switch (c) {
3419 case EOF:
3420 if (i > 0) {
3421 rc = true;
3422 }
3423 collect = false;
3424 break;
3425
3426 case '\n':
3427 if (i > 0) {
3428 rc = true;
3429 collect = false;
3430 buffer[i] = '\0';
3431 }
3432 break;
3433
3434 default:
3435 buffer[i] = c;
3436 i++;
3437 break;
3438 }
3439 }
3440
3441 return (rc);
3442}
3443
3444
3445
3446
3447
3448
3449void load_and_run(int args, _TCHAR** argv) {
3450 char chr;
3451 int ln;
3452 int dot_position;
3453 int end_position;
3454 long i;
3455 FILE *ifp;
3456 long address;
3457 long load_at;
3458 int code;
3459
3460 // Prompt for the .hex file
3461
3462 printf("\n");
3463 printf("Enter the hex filename (.hex): ");
3464
3465 if (args == 2) {
3466 ln = 0;
3467 chr = argv[1][ln];
3468 while (chr != '\0')
3469 {
3470 if (ln < MAX_FILENAME_SIZE)
3471 {
3472 hex_file[ln] = chr;
3473 trc_file[ln] = chr;
3474 ln++;
3475 }
3476 chr = argv[1][ln];
3477 }
3478 }
3479 else {
3480 ln = 0;
3481 chr = '\0';
3482 while (chr != '\n') {
3483 chr = getchar();
3484
3485 switch (chr) {
3486 case '\n':
3487 break;
3488 default:
3489 if (ln < MAX_FILENAME_SIZE) {
3490 hex_file[ln] = chr;
3491 trc_file[ln] = chr;
3492 ln++;
3493 }
3494 break;
3495 }
3496 }
3497
3498 }
3499 // Tidy up the file names
3500
3501 dot_position = find_dot_position(hex_file);
3502 if (dot_position == 0) {
3503 end_position = find_end_position(hex_file);
3504
3505 hex_file[end_position + 1] = '.';
3506 hex_file[end_position + 2] = 'h';
3507 hex_file[end_position + 3] = 'e';
3508 hex_file[end_position + 4] = 'x';
3509 hex_file[end_position + 5] = '\0';
3510 }
3511 else {
3512 hex_file[dot_position + 0] = '.';
3513 hex_file[dot_position + 1] = 'h';
3514 hex_file[dot_position + 2] = 'e';
3515 hex_file[dot_position + 3] = 'x';
3516 hex_file[dot_position + 4] = '\0';
3517 }
3518
3519 dot_position = find_dot_position(trc_file);
3520 if (dot_position == 0) {
3521 end_position = find_end_position(trc_file);
3522
3523 trc_file[end_position + 1] = '.';
3524 trc_file[end_position + 2] = 't';
3525 trc_file[end_position + 3] = 'r';
3526 trc_file[end_position + 4] = 'c';
3527 trc_file[end_position + 5] = '\0';
3528 }
3529 else {
3530 trc_file[dot_position + 0] = '.';
3531 trc_file[dot_position + 1] = 't';
3532 trc_file[dot_position + 2] = 'r';
3533 trc_file[dot_position + 3] = 'c';
3534 trc_file[dot_position + 4] = '\0';
3535 }
3536
3537 if (file_exists(hex_file)) {
3538 // Clear Registers and Memory
3539
3540 Registers[REGISTER_A] = 0;
3541 Registers[REGISTER_B] = 0;
3542 Registers[REGISTER_C] = 0;
3543 Registers[REGISTER_L] = 0;
3544 Registers[REGISTER_H] = 0;
3545 Index_Registers[REGISTER_X] = 0;
3546 Index_Registers[REGISTER_Y] = 0;
3547 Flags = 0;
3548 ProgramCounter = 0;
3549 StackPointer = 0;
3550
3551 for (i = 0; i < MEMORY_SIZE; i++) {
3552 Memory[i] = 0x00;
3553 }
3554
3555 // Load hex file
3556
3557 if ((ifp = fopen(hex_file, "r")) != NULL) {
3558 printf("Loading file...\n\n");
3559
3560 load_at = 0;
3561
3562 while (getline(ifp, InputBuffer)) {
3563 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
3564 load_at = address;
3565 }
3566 else if (sscanf(InputBuffer, "%x", &code) == 1) {
3567 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
3568 Memory[load_at] = (BYTE)code;
3569 }
3570 load_at++;
3571 }
3572 else {
3573 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
3574 }
3575 }
3576
3577 fclose(ifp);
3578 }
3579
3580 // Emulate
3581
3582 emulate();
3583 }
3584 else {
3585 printf("\n");
3586 printf("ERROR> Input file %s does not exist!\n", hex_file);
3587 printf("\n");
3588 }
3589}
3590
3591void building(int args, _TCHAR** argv) {
3592 char buffer[1024];
3593 load_and_run(args, argv);
3594 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",
3595 Memory[TEST_ADDRESS_1],
3596 Memory[TEST_ADDRESS_2],
3597 Memory[TEST_ADDRESS_3],
3598 Memory[TEST_ADDRESS_4],
3599 Memory[TEST_ADDRESS_5],
3600 Memory[TEST_ADDRESS_6],
3601 Memory[TEST_ADDRESS_7],
3602 Memory[TEST_ADDRESS_8],
3603 Memory[TEST_ADDRESS_9],
3604 Memory[TEST_ADDRESS_10],
3605 Memory[TEST_ADDRESS_11],
3606 Memory[TEST_ADDRESS_12]
3607 );
3608 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
3609}
3610
3611
3612
3613void test_and_mark() {
3614 char buffer[1024];
3615 bool testing_complete;
3616 int len = sizeof(SOCKADDR);
3617 char chr;
3618 int i;
3619 int j;
3620 bool end_of_program;
3621 long address;
3622 long load_at;
3623 int code;
3624 int mark;
3625 int passed;
3626
3627 printf("\n");
3628 printf("Automatic Testing and Marking\n");
3629 printf("\n");
3630
3631 testing_complete = false;
3632
3633 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
3634 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
3635
3636 while (!testing_complete) {
3637 memset(buffer, '\0', sizeof(buffer));
3638
3639 if (recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
3640 printf("Incoming Data: %s \n", buffer);
3641
3642 //if (strcmp(buffer, "Testing complete") == 1)
3643 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
3644 testing_complete = true;
3645 printf("Current mark = %d\n", mark);
3646
3647 }
3648 else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
3649 //testing_complete = true;
3650 printf("Passed = %d\n", passed);
3651
3652 }
3653 else if (strcmp(buffer, "Error") == 0) {
3654 printf("ERROR> Testing abnormally terminated\n");
3655 testing_complete = true;
3656 }
3657 else {
3658 // Clear Registers and Memory
3659
3660 Registers[REGISTER_A] = 0;
3661 Registers[REGISTER_B] = 0;
3662 Registers[REGISTER_C] = 0;
3663 Registers[REGISTER_L] = 0;
3664 Registers[REGISTER_H] = 0;
3665 Index_Registers[REGISTER_X] = 0;
3666 Index_Registers[REGISTER_Y] = 0;
3667 Flags = 0;
3668 ProgramCounter = 0;
3669 StackPointer = 0;
3670 for (i = 0; i < MEMORY_SIZE; i++) {
3671 Memory[i] = 0;
3672 }
3673
3674 // Load hex file
3675
3676 i = 0;
3677 j = 0;
3678 load_at = 0;
3679 end_of_program = false;
3680 FILE *ofp;
3681 fopen_s(&ofp, "branch.txt", "a");
3682
3683 while (!end_of_program) {
3684 chr = buffer[i];
3685 switch (chr) {
3686 case '\0':
3687 end_of_program = true;
3688
3689 case ',':
3690 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
3691 load_at = address;
3692 }
3693 else if (sscanf(InputBuffer, "%x", &code) == 1) {
3694 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
3695 Memory[load_at] = (BYTE)code;
3696 fprintf(ofp, "%02X\n", (BYTE)code);
3697 }
3698 load_at++;
3699 }
3700 else {
3701 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
3702 }
3703 j = 0;
3704 break;
3705
3706 default:
3707 InputBuffer[j] = chr;
3708 j++;
3709 break;
3710 }
3711 i++;
3712 }
3713 fclose(ofp);
3714 // Emulate
3715
3716 if (load_at > 1) {
3717 emulate();
3718 // Send and store results
3719 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
3720 Memory[TEST_ADDRESS_1],
3721 Memory[TEST_ADDRESS_2],
3722 Memory[TEST_ADDRESS_3],
3723 Memory[TEST_ADDRESS_4],
3724 Memory[TEST_ADDRESS_5],
3725 Memory[TEST_ADDRESS_6],
3726 Memory[TEST_ADDRESS_7],
3727 Memory[TEST_ADDRESS_8],
3728 Memory[TEST_ADDRESS_9],
3729 Memory[TEST_ADDRESS_10],
3730 Memory[TEST_ADDRESS_11],
3731 Memory[TEST_ADDRESS_12]
3732 );
3733 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
3734 }
3735 }
3736 }
3737 }
3738}
3739
3740
3741
3742int _tmain(int argc, _TCHAR* argv[])
3743{
3744 char chr;
3745 char dummy;
3746
3747 printf("\n");
3748 printf("Microprocessor Emulator\n");
3749 printf("UWE Computer and Network Systems Assignment 1\n");
3750 printf("\n");
3751
3752 initialise_filenames();
3753
3754 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
3755
3756 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
3757 if (!sock) {
3758 // Creation failed!
3759 }
3760
3761 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
3762 server_addr.sin_family = AF_INET;
3763 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
3764 server_addr.sin_port = htons(PORT_SERVER);
3765
3766 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
3767 client_addr.sin_family = AF_INET;
3768 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
3769 client_addr.sin_port = htons(PORT_CLIENT);
3770
3771 chr = '\0';
3772 while ((chr != 'e') && (chr != 'E'))
3773 {
3774 printf("\n");
3775 printf("Please select option\n");
3776 printf("L - Load and run a hex file\n");
3777 printf("T - Have the server test and mark your emulator\n");
3778 printf("E - Exit\n");
3779 if (argc == 2) { building(argc, argv); exit(0); }
3780 printf("Enter option: ");
3781 chr = getchar();
3782 if (chr != 0x0A)
3783 {
3784 dummy = getchar(); // read in the <CR>
3785 }
3786 printf("\n");
3787
3788 switch (chr)
3789 {
3790 case 'L':
3791 case 'l':
3792 load_and_run(argc, argv);
3793 break;
3794
3795 case 'T':
3796 case 't':
3797 test_and_mark();
3798 break;
3799
3800 default:
3801 break;
3802 }
3803 }
3804
3805 closesocket(sock);
3806 WSACleanup();
3807
3808
3809 return 0;
3810}