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