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