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