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