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