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