· 9 years ago · Nov 01, 2016, 02:12 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 ((reg & 0x80) != 0) // msbit set
393 {
394 Flags = Flags | FLAG_Z;
395 }
396 else
397 {
398 Flags = Flags & (0xFF - FLAG_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 Group_1(BYTE opcode){
415 WORD temp_word = 0;
416 BYTE LB = 0;
417 BYTE HB = 0;
418 WORD address = 0;
419 WORD data = 0;
420 BYTE param1 = 0;
421 BYTE param2 = 0;
422 switch (opcode) {
423 case 0x0A: //LDAA Immidiate(#)
424 data = fetch();
425 Registers[REGISTER_A] = data; //fetch data and assign it to LDAA(REGISTER_A)
426 break;
427 case 0x01A:
428 HB = fetch();
429 LB = fetch();
430 address += (WORD)((WORD)HB << 8) + LB;
431 if (address >= 0 && address < MEMORY_SIZE) {
432 Registers[REGISTER_A] = Memory[address];
433 }
434 break;
435 case 0x02A:
436 address += Index_Registers[REGISTER_X];
437 HB = fetch();
438 LB = fetch();
439 address+= (WORD)((WORD)HB << 8) + LB;
440 if (address >= 0 && address < MEMORY_SIZE) {
441 Registers[REGISTER_A] = Memory[address];
442 }
443 break;
444 case 0x03A: //LDAA(abs,Y)
445 address += Index_Registers[REGISTER_Y];
446 HB = fetch();
447 LB = fetch();
448 address += (WORD)((WORD)HB << 8) + LB;
449 if (address >= 0 && address < MEMORY_SIZE) {
450 Registers[REGISTER_A] = Memory[address];
451 }
452 break;
453 case 0x04A: //LDAA(ind)
454 HB = fetch();
455 LB = fetch();
456 address = (WORD)((WORD)HB << 8) + LB;
457 HB = Memory[address];
458 LB = Memory[address+1];
459 address = (WORD)((WORD)HB << 8) + LB;
460 if (address >= 0 && address < MEMORY_SIZE) {
461 Registers[REGISTER_A] = Memory[address];
462 }
463 break;
464 case 0x05A: //LDAA (ind, X)
465 HB = fetch();
466 LB = fetch();
467 address = (WORD)((WORD)HB << 8) + LB;
468 HB = Memory[address];
469 LB = Memory[address + 1];
470 address = (WORD)((WORD)HB << 8) + LB;
471 address += Index_Registers[REGISTER_X];
472 if (address >= 0 && address < MEMORY_SIZE) {
473 Registers[REGISTER_A] = Memory[address];
474 }
475 break;
476 case 0xBA: //STORA(abs)
477 HB = fetch();
478 LB = fetch();
479 address += (WORD)((WORD)HB << 8) + LB;
480 if (address >= 0 && address < MEMORY_SIZE) {
481 Memory[address] = Registers[REGISTER_A];
482 }
483 break;
484 case 0xCA: //STORA(abs,X)
485 address += Index_Registers[REGISTER_X];
486 HB = fetch();
487 LB = fetch();
488 address += (WORD)((WORD)HB << 8) + LB;
489 if (address >= 0 && address < MEMORY_SIZE) {
490 Memory[address] = Registers[REGISTER_A];
491 }
492 break;
493 case 0xDA: //STORA (abs,Y)
494 address += Index_Registers[REGISTER_Y];
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 case 0xEA: //STORA (ind)
503 HB = fetch();
504 LB = fetch();
505 address = (WORD)((WORD)HB << 8) + LB;
506 HB = Memory[address];
507 LB = Memory[address + 1];
508 address = (WORD)((WORD)HB << 8) + LB;
509 if (address >= 0 && address < MEMORY_SIZE) {
510 Memory[address] = Registers[REGISTER_A];
511 }
512 break;
513 case 0xFA: //STORA (ind,X)
514 HB = fetch();
515 LB = fetch();
516 address = (WORD)((WORD)HB << 8) + LB;
517 HB = Memory[address];
518 LB = Memory[address + 1];
519 address = (WORD)((WORD)HB << 8) + LB;
520 address += Index_Registers[REGISTER_X];
521 if (address >= 0 && address < MEMORY_SIZE) {
522 Memory[address] = Registers[REGISTER_A];
523 }
524 break;
525 case 0x1C: //MVI(L,#)
526 data = fetch();
527 Registers[REGISTER_L] = data;
528 break;
529 case 0x1D: //MVI(H,#)
530 data = fetch();
531 Registers[REGISTER_H] = data;
532 break;
533
534 case 0x0B: //LDAB Immidiate(#)
535 data = fetch();
536 Registers[REGISTER_B] = data; //fetch data and assign it to LDAB(REGISTER_A)
537 break;
538 case 0x01B:
539 HB = fetch();
540 LB = fetch();
541 address += (WORD)((WORD)HB << 8) + LB;
542 if (address >= 0 && address < MEMORY_SIZE) {
543 Registers[REGISTER_B] = Memory[address];
544 }
545 break;
546 case 0x02B:
547 address += Index_Registers[REGISTER_X];
548 HB = fetch();
549 LB = fetch();
550 address += (WORD)((WORD)HB << 8) + LB;
551 if (address >= 0 && address < MEMORY_SIZE) {
552 Registers[REGISTER_B] = Memory[address];
553 }
554 break;
555 case 0x03B: //LDAB(abs,Y)
556 address += Index_Registers[REGISTER_Y];
557 HB = fetch();
558 LB = fetch();
559 address += (WORD)((WORD)HB << 8) + LB;
560 if (address >= 0 && address < MEMORY_SIZE) {
561 Registers[REGISTER_B] = Memory[address];
562 }
563 break;
564 case 0x04B: //LDAB(ind)
565 HB = fetch();
566 LB = fetch();
567 address = (WORD)((WORD)HB << 8) + LB;
568 HB = Memory[address];
569 LB = Memory[address + 1];
570 address = (WORD)((WORD)HB << 8) + LB;
571 if (address >= 0 && address < MEMORY_SIZE) {
572 Registers[REGISTER_B] = Memory[address];
573 }
574 break;
575 case 0x05B: //LDAB (ind, X)
576 HB = fetch();
577 LB = fetch();
578 address = (WORD)((WORD)HB << 8) + LB;
579 HB = Memory[address];
580 LB = Memory[address + 1];
581 address = (WORD)((WORD)HB << 8) + LB;
582 address += Index_Registers[REGISTER_X];
583 if (address >= 0 && address < MEMORY_SIZE) {
584 Registers[REGISTER_B] = Memory[address];
585 }
586 break;
587 case 0xBB: //STORB(abs)
588 HB = fetch();
589 LB = fetch();
590 address += (WORD)((WORD)HB << 8) + LB;
591 if (address >= 0 && address < MEMORY_SIZE) {
592 Memory[address] = Registers[REGISTER_B];
593 }
594 break;
595 case 0xCB: //STORB(abs,X)
596 address += Index_Registers[REGISTER_X];
597 HB = fetch();
598 LB = fetch();
599 address += (WORD)((WORD)HB << 8) + LB;
600 if (address >= 0 && address < MEMORY_SIZE) {
601 Memory[address] = Registers[REGISTER_B];
602 }
603 break;
604 case 0xDB: //STORB (abs,Y)
605 address += Index_Registers[REGISTER_Y];
606 HB = fetch();
607 LB = fetch();
608 address += (WORD)((WORD)HB << 8) + LB;
609 if (address >= 0 && address < MEMORY_SIZE) {
610 Memory[address] = Registers[REGISTER_B];
611 }
612 break;
613 case 0xEB: //STORB (ind)
614 HB = fetch();
615 LB = fetch();
616 address = (WORD)((WORD)HB << 8) + LB;
617 HB = Memory[address];
618 LB = Memory[address + 1];
619 address = (WORD)((WORD)HB << 8) + LB;
620 if (address >= 0 && address < MEMORY_SIZE) {
621 Memory[address] = Registers[REGISTER_B];
622 }
623 break;
624 case 0xFB: //STORB (ind,X)
625 HB = fetch();
626 LB = fetch();
627 address = (WORD)((WORD)HB << 8) + LB;
628 HB = Memory[address];
629 LB = Memory[address + 1];
630 address = (WORD)((WORD)HB << 8) + LB;
631 address += Index_Registers[REGISTER_X];
632 if (address >= 0 && address < MEMORY_SIZE) {
633 Memory[address] = Registers[REGISTER_B];
634 }
635 break;
636 case 0x0E: //LDX Immidiate(#)
637 data = fetch();
638 Registers[REGISTER_X] = data; //fetch data and assign it to LDAA(REGISTER_A)
639 break;
640 case 0x01E: //LDX(abs)
641 HB = fetch();
642 LB = fetch();
643 address += (WORD)((WORD)HB << 8) + LB;
644 if (address >= 0 && address < MEMORY_SIZE) {
645 Registers[REGISTER_X] = Memory[address];
646 }
647 break;
648 case 0x02E: //LDX(abs, X)
649 address += Index_Registers[REGISTER_X];
650 HB = fetch();
651 LB = fetch();
652 address += (WORD)((WORD)HB << 8) + LB;
653 if (address >= 0 && address < MEMORY_SIZE) {
654 Registers[REGISTER_X] = Memory[address];
655 }
656 break;
657 case 0x03E: //LDX(abs,Y)
658 address += Index_Registers[REGISTER_Y];
659 HB = fetch();
660 LB = fetch();
661 address += (WORD)((WORD)HB << 8) + LB;
662 if (address >= 0 && address < MEMORY_SIZE) {
663 Registers[REGISTER_X] = Memory[address];
664 }
665 break;
666 case 0x04E: //LDX(ind)
667 HB = fetch();
668 LB = fetch();
669 address = (WORD)((WORD)HB << 8) + LB;
670 HB = Memory[address];
671 LB = Memory[address + 1];
672 address = (WORD)((WORD)HB << 8) + LB;
673 if (address >= 0 && address < MEMORY_SIZE) {
674 Registers[REGISTER_X] = Memory[address];
675 }
676 break;
677 case 0x05E: //LDX(ind, X)
678 HB = fetch();
679 LB = fetch();
680 address = (WORD)((WORD)HB << 8) + LB;
681 HB = Memory[address];
682 LB = Memory[address + 1];
683 address = (WORD)((WORD)HB << 8) + LB;
684 address += Index_Registers[REGISTER_X];
685 if (address >= 0 && address < MEMORY_SIZE) {
686 Registers[REGISTER_X] = Memory[address];
687 }
688 break;
689 case 0xBC: //STOX(abs)
690 HB = fetch();
691 LB = fetch();
692 address += (WORD)((WORD)HB << 8) + LB;
693 if (address >= 0 && address < MEMORY_SIZE) {
694 Memory[address] = Registers[REGISTER_X];
695 }
696 break;
697 case 0xCC: //STOX(abs,X)
698 address += Index_Registers[REGISTER_X];
699 HB = fetch();
700 LB = fetch();
701 address += (WORD)((WORD)HB << 8) + LB;
702 if (address >= 0 && address < MEMORY_SIZE) {
703 Memory[address] = Registers[REGISTER_X];
704 }
705 break;
706 case 0xDC: //STOX (abs,Y)
707 address += Index_Registers[REGISTER_Y];
708 HB = fetch();
709 LB = fetch();
710 address += (WORD)((WORD)HB << 8) + LB;
711 if (address >= 0 && address < MEMORY_SIZE) {
712 Memory[address] = Registers[REGISTER_X];
713 }
714 break;
715 case 0xEC: //STOX (ind)
716 HB = fetch();
717 LB = fetch();
718 address = (WORD)((WORD)HB << 8) + LB;
719 HB = Memory[address];
720 LB = Memory[address + 1];
721 address = (WORD)((WORD)HB << 8) + LB;
722 if (address >= 0 && address < MEMORY_SIZE) {
723 Memory[address] = Registers[REGISTER_X];
724 }
725 break;
726 case 0xFC: //STOX (ind,X)
727 HB = fetch();
728 LB = fetch();
729 address = (WORD)((WORD)HB << 8) + LB;
730 HB = Memory[address];
731 LB = Memory[address + 1];
732 address = (WORD)((WORD)HB << 8) + LB;
733 address += Index_Registers[REGISTER_X];
734 if (address >= 0 && address < MEMORY_SIZE) {
735 Memory[address] = Registers[REGISTER_X];
736 }
737 break;
738
739
740
741 case 0x0F: //LDY Immidiate(#)
742 data = fetch();
743 Registers[REGISTER_Y] = data; //fetch data and assign it to LDAA(REGISTER_A)
744 break;
745 case 0x01F: //LDY(abs)
746 HB = fetch();
747 LB = fetch();
748 address += (WORD)((WORD)HB << 8) + LB;
749 if (address >= 0 && address < MEMORY_SIZE) {
750 Registers[REGISTER_Y] = Memory[address];
751 }
752 break;
753 case 0x02F: //LDY(abs, X)
754 address += Index_Registers[REGISTER_X];
755 HB = fetch();
756 LB = fetch();
757 address += (WORD)((WORD)HB << 8) + LB;
758 if (address >= 0 && address < MEMORY_SIZE) {
759 Registers[REGISTER_Y] = Memory[address];
760 }
761 break;
762 case 0x03F: //LDY(abs,Y)
763 address += Index_Registers[REGISTER_Y];
764 HB = fetch();
765 LB = fetch();
766 address += (WORD)((WORD)HB << 8) + LB;
767 if (address >= 0 && address < MEMORY_SIZE) {
768 Registers[REGISTER_Y] = Memory[address];
769 }
770 break;
771 case 0x04F: //LDY(ind)
772 HB = fetch();
773 LB = fetch();
774 address = (WORD)((WORD)HB << 8) + LB;
775 HB = Memory[address];
776 LB = Memory[address + 1];
777 address = (WORD)((WORD)HB << 8) + LB;
778 if (address >= 0 && address < MEMORY_SIZE) {
779 Registers[REGISTER_Y] = Memory[address];
780 }
781 break;
782 case 0x05F: //LDY(ind, X)
783 HB = fetch();
784 LB = fetch();
785 address = (WORD)((WORD)HB << 8) + LB;
786 HB = Memory[address];
787 LB = Memory[address + 1];
788 address = (WORD)((WORD)HB << 8) + LB;
789 address += Index_Registers[REGISTER_X];
790 if (address >= 0 && address < MEMORY_SIZE) {
791 Registers[REGISTER_Y] = Memory[address];
792 }
793 break;
794 case 0xBD: //STOY(abs)
795 HB = fetch();
796 LB = fetch();
797 address += (WORD)((WORD)HB << 8) + LB;
798 if (address >= 0 && address < MEMORY_SIZE) {
799 Memory[address] = Registers[REGISTER_Y];
800 }
801 break;
802 case 0xCD: //STOY(abs,X)
803 address += Index_Registers[REGISTER_X];
804 HB = fetch();
805 LB = fetch();
806 address += (WORD)((WORD)HB << 8) + LB;
807 if (address >= 0 && address < MEMORY_SIZE) {
808 Memory[address] = Registers[REGISTER_Y];
809 }
810 break;
811 case 0xDD: //STOY (abs,Y)
812 address += Index_Registers[REGISTER_Y];
813 HB = fetch();
814 LB = fetch();
815 address += (WORD)((WORD)HB << 8) + LB;
816 if (address >= 0 && address < MEMORY_SIZE) {
817 Memory[address] = Registers[REGISTER_Y];
818 }
819 break;
820 case 0xED: //STOY (ind)
821 HB = fetch();
822 LB = fetch();
823 address = (WORD)((WORD)HB << 8) + LB;
824 HB = Memory[address];
825 LB = Memory[address + 1];
826 address = (WORD)((WORD)HB << 8) + LB;
827 if (address >= 0 && address < MEMORY_SIZE) {
828 Memory[address] = Registers[REGISTER_Y];
829 }
830 break;
831 case 0xFD: //STOY (ind,X)
832 HB = fetch();
833 LB = fetch();
834 address = (WORD)((WORD)HB << 8) + LB;
835 HB = Memory[address];
836 LB = Memory[address + 1];
837 address = (WORD)((WORD)HB << 8) + LB;
838 address += Index_Registers[REGISTER_X];
839 if (address >= 0 && address < MEMORY_SIZE) {
840 Memory[address] = Registers[REGISTER_Y];
841 }
842 break;
843
844 //PRACTICAL 2
845
846 case 0x31: //ADC A,L
847
848 param1 = Registers[REGISTER_A];
849 param2 = Registers[REGISTER_L];
850 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
851 if ((Flags& FLAG_C) != 0)
852 {
853 temp_word++;
854 }
855 if (temp_word >= 0x100)
856 {
857 Flags = Flags | FLAG_C;//set carry flag
858 }
859 else
860 {
861 Flags = Flags&(0xFF-FLAG_C);//clear carry flag
862 }
863 set_flag_n((BYTE)temp_word);
864 set_flag_z((BYTE)temp_word);
865 Registers[REGISTER_A] = (BYTE)temp_word;
866 break;
867 case 0x41: //ADC A,H
868 param1 = Registers[REGISTER_A];
869 param2 = Registers[REGISTER_H];
870 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
871 if ((Flags& FLAG_C) != 0)
872 {
873 temp_word++;
874 }
875 if (temp_word >= 0x100)
876 {
877 Flags = Flags | FLAG_C;//set carry flag
878 }
879 else
880 {
881 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
882 }
883 set_flag_n((BYTE)temp_word);
884 set_flag_z((BYTE)temp_word);
885 Registers[REGISTER_A] = (BYTE)temp_word;
886 break;
887 case 0x51: //ADC A,M
888 param1 = Registers[REGISTER_A];
889 param2 = Registers[REGISTER_M];
890 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_M];
891 if ((Flags& FLAG_C) != 0)
892 {
893 temp_word++;
894 }
895 if (temp_word >= 0x100)
896 {
897 Flags = Flags | FLAG_C;//set carry flag
898 }
899 else
900 {
901 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
902 }
903 set_flag_n((BYTE)temp_word);
904 set_flag_z((BYTE)temp_word);
905 Registers[REGISTER_A] = (BYTE)temp_word;
906 break;
907 case 0x61: //ADC B,L
908 param1 = Registers[REGISTER_B];
909 param2 = Registers[REGISTER_L];
910 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_L];
911 if ((Flags& FLAG_C) != 0)
912 {
913 temp_word++;
914 }
915 if (temp_word >= 0x100)
916 {
917 Flags = Flags | FLAG_C;//set carry flag
918 }
919 else
920 {
921 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
922 }
923 set_flag_n((BYTE)temp_word);
924 set_flag_z((BYTE)temp_word);
925 Registers[REGISTER_B] = (BYTE)temp_word;
926 break;
927 case 0x71: //ADC B,H
928 param1 = Registers[REGISTER_B];
929 param2 = Registers[REGISTER_H];
930 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_H];
931 if ((Flags& FLAG_C) != 0)
932 {
933 temp_word++;
934 }
935 if (temp_word >= 0x100)
936 {
937 Flags = Flags | FLAG_C;//set carry flag
938 }
939 else
940 {
941 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
942 }
943 set_flag_n((BYTE)temp_word);
944 set_flag_z((BYTE)temp_word);
945 Registers[REGISTER_B] = (BYTE)temp_word;
946 break;
947 case 0x81: //ADC B,M
948 param1 = Registers[REGISTER_B];
949 param2 = Registers[REGISTER_M];
950 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_M];
951 if ((Flags& FLAG_C) != 0)
952 {
953 temp_word++;
954 }
955 if (temp_word >= 0x100)
956 {
957 Flags = Flags | FLAG_C;//set carry flag
958 }
959 else
960 {
961 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
962 }
963 set_flag_n((BYTE)temp_word);
964 set_flag_z((BYTE)temp_word);
965 Registers[REGISTER_M] = (BYTE)temp_word;
966 break;
967
968
969 case 0x33: //ADD A,L
970
971 param1 = Registers[REGISTER_A];
972 param2 = Registers[REGISTER_L];
973 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
974 Registers[REGISTER_A] = (BYTE)temp_word;
975 break;
976
977 case 0x43: //ADD A,H
978 param1 = Registers[REGISTER_A];
979 param2 = Registers[REGISTER_H];
980 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
981 Registers[REGISTER_A] = (BYTE)temp_word;
982 break;
983
984 case 0x53: //ADD A,M
985 param1 = Registers[REGISTER_A];
986 param2 = Registers[REGISTER_M];
987 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_M];
988 Registers[REGISTER_A] = (BYTE)temp_word;
989 break;
990 case 0x63: //ADD B,L
991 param1 = Registers[REGISTER_B];
992 param2 = Registers[REGISTER_L];
993 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_L];
994 Registers[REGISTER_B] = (BYTE)temp_word;
995 break;
996 case 0x73: //ADD B,H
997 param1 = Registers[REGISTER_B];
998 param2 = Registers[REGISTER_H];
999 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_H];
1000 Registers[REGISTER_B] = (BYTE)temp_word;
1001 break;
1002 case 0x83: //ADD B,M
1003 param1 = Registers[REGISTER_B];
1004 param2 = Registers[REGISTER_M];
1005 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_M];
1006 Registers[REGISTER_M] = (BYTE)temp_word;
1007 break;
1008
1009 case 0x34: //SUB A,L
1010
1011 param1 = Registers[REGISTER_A];
1012 param2 = Registers[REGISTER_L];
1013 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1014 Registers[REGISTER_A] = (BYTE)temp_word;
1015 break;
1016
1017 case 0x44: //SUB A,H
1018 param1 = Registers[REGISTER_A];
1019 param2 = Registers[REGISTER_H];
1020 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1021 Registers[REGISTER_A] = (BYTE)temp_word;
1022 break;
1023
1024 case 0x54: //SUB A,M
1025 param1 = Registers[REGISTER_A];
1026 param2 = Registers[REGISTER_M];
1027 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
1028 Registers[REGISTER_A] = (BYTE)temp_word;
1029 break;
1030 case 0x64: //SUB B,L
1031 param1 = Registers[REGISTER_B];
1032 param2 = Registers[REGISTER_L];
1033 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_L];
1034 Registers[REGISTER_B] = (BYTE)temp_word;
1035 break;
1036 case 0x74: //SUB B,H
1037 param1 = Registers[REGISTER_B];
1038 param2 = Registers[REGISTER_H];
1039 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_H];
1040 Registers[REGISTER_B] = (BYTE)temp_word;
1041 break;
1042 case 0x84: //SUB B,M
1043 param1 = Registers[REGISTER_B];
1044 param2 = Registers[REGISTER_M];
1045 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_M];
1046 Registers[REGISTER_M] = (BYTE)temp_word;
1047 break;
1048 case 0xF3: //ABA?
1049 param1 = Registers[REGISTER_B];
1050 param2 = Registers[REGISTER_A];
1051 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_A];
1052 Registers[REGISTER_A] = (BYTE)temp_word;
1053 break;
1054 case 0xF5: //AAB?
1055 param1 = Registers[REGISTER_B];
1056 param2 = Registers[REGISTER_A];
1057 temp_word = (WORD)Registers[REGISTER_B] + (WORD)Registers[REGISTER_A];
1058 Registers[REGISTER_B] = (BYTE)temp_word;
1059 break;
1060 case 0xF4: //SBA?
1061 param1 = Registers[REGISTER_A];
1062 param2 = Registers[REGISTER_B];
1063 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
1064 Registers[REGISTER_A] = (BYTE)temp_word;
1065 break;
1066 case 0xF6: //SAB?
1067 param1 = Registers[REGISTER_B];
1068 param2 = Registers[REGISTER_A];
1069 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_A];
1070 Registers[REGISTER_B] = (BYTE)temp_word;
1071 break;
1072 case 0x32: //SBC A,L
1073 param1 = Registers[REGISTER_A];
1074 param2 = Registers[REGISTER_L];
1075 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1076 if ((Flags& FLAG_C) != 0)
1077 {
1078 temp_word++;
1079 }
1080 if (temp_word >= 0x100)
1081 {
1082 Flags = Flags | FLAG_C;//set carry flag
1083 }
1084 else
1085 {
1086 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
1087 }
1088 set_flag_n((BYTE)temp_word);
1089 set_flag_z((BYTE)temp_word);
1090 break;
1091 case 0x42: //SBC A,H
1092
1093 param1 = Registers[REGISTER_A];
1094 param2 = Registers[REGISTER_H];
1095 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1096 if ((Flags& FLAG_C) != 0)
1097 {
1098 temp_word++;
1099 }
1100 if (temp_word >= 0x100)
1101 {
1102 Flags = Flags | FLAG_C;//set carry flag
1103 }
1104 else
1105 {
1106 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
1107 }
1108 set_flag_n((BYTE)temp_word);
1109 set_flag_z((BYTE)temp_word);
1110 break;
1111 case 0x52: //SBC A,M
1112
1113 param1 = Registers[REGISTER_A];
1114 param2 = Registers[REGISTER_M];
1115 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
1116 if ((Flags& FLAG_C) != 0)
1117 {
1118 temp_word++;
1119 }
1120 if (temp_word >= 0x100)
1121 {
1122 Flags = Flags | FLAG_C;//set carry flag
1123 }
1124 else
1125 {
1126 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
1127 }
1128 set_flag_n((BYTE)temp_word);
1129 set_flag_z((BYTE)temp_word);
1130 break;
1131 case 0x62: //SBC B,L
1132
1133 param1 = Registers[REGISTER_B];
1134 param2 = Registers[REGISTER_L];
1135 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_L];
1136 if ((Flags& FLAG_C) != 0)
1137 {
1138 temp_word++;
1139 }
1140 if (temp_word >= 0x100)
1141 {
1142 Flags = Flags | FLAG_C;//set carry flag
1143 }
1144 else
1145 {
1146 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
1147 }
1148 set_flag_n((BYTE)temp_word);
1149 set_flag_z((BYTE)temp_word);
1150 break;
1151 case 0x72: //SBC B,H
1152
1153 param1 = Registers[REGISTER_B];
1154 param2 = Registers[REGISTER_H];
1155 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_H];
1156 if ((Flags& FLAG_C) != 0)
1157 {
1158 temp_word++;
1159 }
1160 if (temp_word >= 0x100)
1161 {
1162 Flags = Flags | FLAG_C;//set carry flag
1163 }
1164 else
1165 {
1166 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
1167 }
1168 set_flag_n((BYTE)temp_word);
1169 set_flag_z((BYTE)temp_word);
1170 break;
1171 case 0x82: //SBC B,M
1172
1173 param1 = Registers[REGISTER_B];
1174 param2 = Registers[REGISTER_M];
1175 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_M];
1176 if ((Flags& FLAG_C) != 0)
1177 {
1178 temp_word++;
1179 }
1180 if (temp_word >= 0x100)
1181 {
1182 Flags = Flags | FLAG_C;//set carry flag
1183 }
1184 else
1185 {
1186 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
1187 }
1188 set_flag_n((BYTE)temp_word);
1189 set_flag_z((BYTE)temp_word);
1190 break;
1191
1192 case 0x45: //CMP A,H
1193
1194 param1 = Registers[REGISTER_A];
1195 param2 = Registers[REGISTER_H];
1196 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1197 if ((Flags& FLAG_C) != 0)
1198 {
1199 temp_word++;
1200 }
1201 if (temp_word >= 0x100)
1202 {
1203 Flags = Flags | FLAG_C;//set carry flag
1204 }
1205 else
1206 {
1207 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
1208 }
1209 set_flag_n((BYTE)temp_word);
1210 set_flag_z((BYTE)temp_word);
1211 break;
1212 case 0x55: //CMP A,M
1213
1214 param1 = Registers[REGISTER_A];
1215 param2 = Registers[REGISTER_M];
1216 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
1217 if ((Flags& FLAG_C) != 0)
1218 {
1219 temp_word++;
1220 }
1221 if (temp_word >= 0x100)
1222 {
1223 Flags = Flags | FLAG_C;//set carry flag
1224 }
1225 else
1226 {
1227 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
1228 }
1229 set_flag_n((BYTE)temp_word);
1230 set_flag_z((BYTE)temp_word);
1231 break;
1232 case 0x65: //CMP B,L
1233
1234 param1 = Registers[REGISTER_B];
1235 param2 = Registers[REGISTER_L];
1236 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_L];
1237 if ((Flags& FLAG_C) != 0)
1238 {
1239 temp_word++;
1240 }
1241 if (temp_word >= 0x100)
1242 {
1243 Flags = Flags | FLAG_C;//set carry flag
1244 }
1245 else
1246 {
1247 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
1248 }
1249 set_flag_n((BYTE)temp_word);
1250 set_flag_z((BYTE)temp_word);
1251 break;
1252 case 0x75: //CMP B,H
1253
1254 param1 = Registers[REGISTER_B];
1255 param2 = Registers[REGISTER_H];
1256 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_H];
1257 if ((Flags& FLAG_C) != 0)
1258 {
1259 temp_word++;
1260 }
1261 if (temp_word >= 0x100)
1262 {
1263 Flags = Flags | FLAG_C;//set carry flag
1264 }
1265 else
1266 {
1267 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
1268 }
1269 set_flag_n((BYTE)temp_word);
1270 set_flag_z((BYTE)temp_word);
1271 break;
1272 case 0x85: //CMP B,M
1273
1274 param1 = Registers[REGISTER_B];
1275 param2 = Registers[REGISTER_M];
1276 temp_word = (WORD)Registers[REGISTER_B] - (WORD)Registers[REGISTER_M];
1277 if ((Flags& FLAG_C) != 0)
1278 {
1279 temp_word++;
1280 }
1281 if (temp_word >= 0x100)
1282 {
1283 Flags = Flags | FLAG_C;//set carry flag
1284 }
1285 else
1286 {
1287 Flags = Flags&(0xFF - FLAG_C);//clear carry flag
1288 }
1289 set_flag_n((BYTE)temp_word);
1290 set_flag_z((BYTE)temp_word);
1291 break;
1292
1293
1294 case 0xF2: //CSA
1295 Registers[REGISTER_A] = Flags;
1296 break;
1297
1298 }
1299}
1300
1301void Group_2_Move(BYTE opcode)
1302{
1303 BYTE LB = 0;
1304 BYTE HB = 0;
1305 WORD address = 0;
1306 WORD data = 0;
1307 BYTE destination = opcode >> 4;
1308 BYTE source = opcode & 0x0F;
1309 int destReg;
1310 int sourceReg;
1311 switch (source) {
1312 case 0x06:
1313 sourceReg = REGISTER_A;
1314 break;
1315 case 0x07:
1316 sourceReg = REGISTER_B;
1317 break;
1318 case 0x08:
1319 sourceReg = REGISTER_L;
1320 break;
1321 case 0x09:
1322 sourceReg = REGISTER_H;
1323 break;
1324 case 0x0A:
1325 sourceReg = REGISTER_M;
1326 break;
1327 Registers[destReg] = Registers[sourceReg];
1328 if (destReg == REGISTER_M) {
1329 address = Registers[REGISTER_L];
1330 address += (WORD)Registers[REGISTER_H] << 4;
1331 if (address >= 0 && address <= MEMORY_SIZE) {
1332 Memory[address] = Registers[sourceReg];
1333 }
1334 }
1335 else {
1336 Registers[destReg] = Registers[sourceReg];
1337 }
1338
1339 case 0x20: //LODS(#)
1340 data = fetch();
1341 StackPointer = data << 8; StackPointer += fetch();
1342 break;
1343 case 0x30:
1344 HB = fetch();
1345 LB = fetch();
1346 address += (WORD)((WORD)HB << 8) + LB;
1347 if (address >= 0 && address < MEMORY_SIZE-1) {
1348 StackPointer=(WORD)Memory[address]<<8;
1349 StackPointer += Memory[address + 1];
1350 }
1351 break;
1352 case 0x40: //LODS(abs,X)
1353 address += Index_Registers[REGISTER_X];
1354 HB = fetch();
1355 LB = fetch();
1356 address += (WORD)((WORD)HB << 8) + LB;
1357 if (address >= 0 && address < MEMORY_SIZE - 1) {
1358 StackPointer = (WORD)Memory[address] << 8;
1359 StackPointer += Memory[address + 1];
1360 }
1361 break;
1362 case 0x50: //LODS(abs,Y)
1363 address += Index_Registers[REGISTER_Y];
1364 HB = fetch();
1365 LB = fetch();
1366 address += (WORD)((WORD)HB << 8) + LB;
1367 if (address >= 0 && address < MEMORY_SIZE - 1) {
1368 StackPointer = (WORD)Memory[address] << 8;
1369 StackPointer += Memory[address + 1];
1370 }
1371 break;
1372 case 0x60://LODS(ind)
1373 HB = fetch();
1374 LB = fetch();
1375 address = (WORD)((WORD)HB << 8) + LB;
1376 HB = Memory[address];
1377 LB = Memory[address + 1];
1378 address = (WORD)((WORD)HB << 8) + LB;
1379 if (address >= 0 && address < MEMORY_SIZE - 1) {
1380 StackPointer = (WORD)Memory[address] << 8;
1381 StackPointer += Memory[address + 1];
1382 }
1383 break;
1384 case 0x70://LODS(ind,x)
1385 HB = fetch();
1386 LB = fetch();
1387 address = (WORD)((WORD)HB << 8) + LB;
1388 HB = Memory[address];
1389 LB = Memory[address + 1];
1390 address = (WORD)((WORD)HB << 8) + LB;
1391 address += Index_Registers[REGISTER_X];
1392 if (address >= 0 && address < MEMORY_SIZE - 1) {
1393 StackPointer = (WORD)Memory[address] << 8;
1394 StackPointer += Memory[address + 1];
1395 }
1396 break;
1397 case 0x6A: //STOS(abs)
1398 HB = fetch();
1399 LB = fetch();
1400 address += (WORD)((WORD)HB << 8) + LB;
1401 if (address >= 0 && address < MEMORY_SIZE) {
1402 Memory[address] = StackPointer;
1403 }
1404 break;
1405 case 0x7A: //STOS(abs,X)
1406 address += Index_Registers[REGISTER_X];
1407 HB = fetch();
1408 LB = fetch();
1409 address += (WORD)((WORD)HB << 8) + LB;
1410 if (address >= 0 && address < MEMORY_SIZE) {
1411 Memory[address] = StackPointer;
1412 }
1413 break;
1414 case 0x8A: //STOS (abs,Y)
1415 address += Index_Registers[REGISTER_Y];
1416 HB = fetch();
1417 LB = fetch();
1418 address += (WORD)((WORD)HB << 8) + LB;
1419 if (address >= 0 && address < MEMORY_SIZE) {
1420 Memory[address] = StackPointer;
1421 }
1422 break;
1423 case 0x9A: //STOS (ind)
1424 HB = fetch();
1425 LB = fetch();
1426 address = (WORD)((WORD)HB << 8) + LB;
1427 HB = Memory[address];
1428 LB = Memory[address + 1];
1429 address = (WORD)((WORD)HB << 8) + LB;
1430 if (address >= 0 && address < MEMORY_SIZE) {
1431 Memory[address] = StackPointer;
1432 }
1433 break;
1434 case 0xAA: //STOS (ind,X)
1435 HB = fetch();
1436 LB = fetch();
1437 address = (WORD)((WORD)HB << 8) + LB;
1438 HB = Memory[address];
1439 LB = Memory[address + 1];
1440 address = (WORD)((WORD)HB << 8) + LB;
1441 address += Index_Registers[REGISTER_X];
1442 if (address >= 0 && address < MEMORY_SIZE) {
1443 Memory[address] = StackPointer;
1444 }
1445 break;
1446
1447 }
1448
1449 switch(opcode) {
1450
1451 default:
1452 break;
1453 }
1454}
1455
1456
1457void execute(BYTE opcode)
1458{
1459
1460 if (((opcode >= 0x6B) && (opcode <= 0x6F))
1461 || ((opcode >= 0x7B) && (opcode <= 0x7F))
1462 || ((opcode >= 0x8B) && (opcode <= 0x8F))
1463 || ((opcode >= 0x9B) && (opcode <= 0x9F))
1464 || ((opcode >= 0xAB) && (opcode <= 0xAF)))
1465
1466 {
1467 Group_2_Move(opcode);
1468 }
1469 else
1470 {
1471 Group_1(opcode);
1472 }
1473}
1474
1475void emulate()
1476{
1477 BYTE opcode;
1478 int sanity;
1479
1480 ProgramCounter = 0;
1481 halt = false;
1482 memory_in_range = true;
1483 sanity = 0;
1484
1485 printf(" A B L H X Y SP\n");
1486
1487 while ((!halt) && (memory_in_range) && (sanity < 200))
1488 {
1489 printf("%04X ", ProgramCounter); // Print current address
1490 opcode = fetch();
1491 execute(opcode);
1492
1493 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
1494
1495 printf("%02X ", Registers[REGISTER_A]);
1496 printf("%02X ", Registers[REGISTER_B]);
1497 printf("%02X ", Registers[REGISTER_L]);
1498 printf("%02X ", Registers[REGISTER_H]);
1499 printf("%02X ", Index_Registers[REGISTER_X]);
1500 printf("%02X ", Index_Registers[REGISTER_Y]);
1501 printf("%04X ", StackPointer); // Print Stack Pointer
1502
1503 if ((Flags & FLAG_I) == FLAG_I)
1504 {
1505 printf("I=1 ");
1506 }
1507 else
1508 {
1509 printf("I=0 ");
1510 }
1511 if ((Flags & FLAG_Z) == FLAG_Z)
1512 {
1513 printf("Z=1 ");
1514 }
1515 else
1516 {
1517 printf("Z=0 ");
1518 }
1519 if ((Flags & FLAG_N) == FLAG_N)
1520 {
1521 printf("N=1 ");
1522 }
1523 else
1524 {
1525 printf("N=0 ");
1526 }
1527 if ((Flags & FLAG_C) == FLAG_C)
1528 {
1529 printf("C=1 ");
1530 }
1531 else
1532 {
1533 printf("C=0 ");
1534 }
1535
1536 printf("\n"); // New line
1537 sanity++;
1538 }
1539
1540 printf("\n"); // New line
1541}
1542
1543
1544////////////////////////////////////////////////////////////////////////////////
1545// Simulator/Emulator (End) //
1546////////////////////////////////////////////////////////////////////////////////
1547
1548
1549void initialise_filenames() {
1550 int i;
1551
1552 for (i=0; i<MAX_FILENAME_SIZE; i++) {
1553 hex_file [i] = '\0';
1554 trc_file [i] = '\0';
1555 }
1556}
1557
1558
1559
1560
1561int find_dot_position(char *filename) {
1562 int dot_position;
1563 int i;
1564 char chr;
1565
1566 dot_position = 0;
1567 i = 0;
1568 chr = filename[i];
1569
1570 while (chr != '\0') {
1571 if (chr == '.') {
1572 dot_position = i;
1573 }
1574 i++;
1575 chr = filename[i];
1576 }
1577
1578 return (dot_position);
1579}
1580
1581
1582int find_end_position(char *filename) {
1583 int end_position;
1584 int i;
1585 char chr;
1586
1587 end_position = 0;
1588 i = 0;
1589 chr = filename[i];
1590
1591 while (chr != '\0') {
1592 end_position = i;
1593 i++;
1594 chr = filename[i];
1595 }
1596
1597 return (end_position);
1598}
1599
1600
1601bool file_exists(char *filename) {
1602 bool exists;
1603 FILE *ifp;
1604
1605 exists = false;
1606
1607 if ( ( ifp = fopen( filename, "r" ) ) != NULL )
1608 {
1609 exists = true;
1610
1611 fclose(ifp);
1612 }
1613
1614 return (exists);
1615}
1616
1617
1618
1619void create_file(char *filename) {
1620 FILE *ofp;
1621
1622 if ( ( ofp = fopen( filename, "w" ) ) != NULL ) {
1623 fclose(ofp);
1624 }
1625}
1626
1627
1628
1629bool getline(FILE *fp, char *buffer) {
1630 bool rc;
1631 bool collect;
1632 char c;
1633 int i;
1634
1635 rc = false;
1636 collect = true;
1637
1638 i = 0;
1639 while (collect) {
1640 c = getc(fp);
1641
1642 switch (c) {
1643 case EOF:
1644 if (i > 0) {
1645 rc = true;
1646 }
1647 collect = false;
1648 break;
1649
1650 case '\n':
1651 if (i > 0) {
1652 rc = true;
1653 collect = false;
1654 buffer[i] = '\0';
1655 }
1656 break;
1657
1658 default:
1659 buffer[i] = c;
1660 i++;
1661 break;
1662 }
1663 }
1664
1665 return (rc);
1666}
1667
1668
1669
1670
1671
1672
1673void load_and_run(int args,_TCHAR** argv) {
1674 char chr;
1675 int ln;
1676 int dot_position;
1677 int end_position;
1678 long i;
1679 FILE *ifp;
1680 long address;
1681 long load_at;
1682 int code;
1683
1684 // Prompt for the .hex file
1685
1686 printf("\n");
1687 printf("Enter the hex filename (.hex): ");
1688
1689 if(args == 2){
1690 ln = 0;
1691 chr = argv[1][ln];
1692 while (chr != '\0')
1693 {
1694 if (ln < MAX_FILENAME_SIZE)
1695 {
1696 hex_file [ln] = chr;
1697 trc_file [ln] = chr;
1698 ln++;
1699 }
1700 chr = argv[1][ln];
1701 }
1702 } else {
1703 ln = 0;
1704 chr = '\0';
1705 while (chr != '\n') {
1706 chr = getchar();
1707
1708 switch(chr) {
1709 case '\n':
1710 break;
1711 default:
1712 if (ln < MAX_FILENAME_SIZE) {
1713 hex_file [ln] = chr;
1714 trc_file [ln] = chr;
1715 ln++;
1716 }
1717 break;
1718 }
1719 }
1720
1721 }
1722 // Tidy up the file names
1723
1724 dot_position = find_dot_position(hex_file);
1725 if (dot_position == 0) {
1726 end_position = find_end_position(hex_file);
1727
1728 hex_file[end_position + 1] = '.';
1729 hex_file[end_position + 2] = 'h';
1730 hex_file[end_position + 3] = 'e';
1731 hex_file[end_position + 4] = 'x';
1732 hex_file[end_position + 5] = '\0';
1733 } else {
1734 hex_file[dot_position + 0] = '.';
1735 hex_file[dot_position + 1] = 'h';
1736 hex_file[dot_position + 2] = 'e';
1737 hex_file[dot_position + 3] = 'x';
1738 hex_file[dot_position + 4] = '\0';
1739 }
1740
1741 dot_position = find_dot_position(trc_file);
1742 if (dot_position == 0) {
1743 end_position = find_end_position(trc_file);
1744
1745 trc_file[end_position + 1] = '.';
1746 trc_file[end_position + 2] = 't';
1747 trc_file[end_position + 3] = 'r';
1748 trc_file[end_position + 4] = 'c';
1749 trc_file[end_position + 5] = '\0';
1750 } else {
1751 trc_file[dot_position + 0] = '.';
1752 trc_file[dot_position + 1] = 't';
1753 trc_file[dot_position + 2] = 'r';
1754 trc_file[dot_position + 3] = 'c';
1755 trc_file[dot_position + 4] = '\0';
1756 }
1757
1758 if (file_exists(hex_file)) {
1759 // Clear Registers and Memory
1760
1761 Registers[REGISTER_A] = 0;
1762 Registers[REGISTER_B] = 0;
1763 Registers[REGISTER_L] = 0;
1764 Registers[REGISTER_H] = 0;
1765 Index_Registers[REGISTER_X] = 0;
1766 Index_Registers[REGISTER_Y] = 0;
1767 Flags = 0;
1768 ProgramCounter = 0;
1769 StackPointer = 0;
1770
1771 for (i=0; i<MEMORY_SIZE; i++) {
1772 Memory[i] = 0x00;
1773 }
1774
1775 // Load hex file
1776
1777 if ( ( ifp = fopen( hex_file, "r" ) ) != NULL ) {
1778 printf("Loading file...\n\n");
1779
1780 load_at = 0;
1781
1782 while (getline(ifp, InputBuffer)) {
1783 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
1784 load_at = address;
1785 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
1786 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
1787 Memory[load_at] = (BYTE)code;
1788 }
1789 load_at++;
1790 } else {
1791 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
1792 }
1793 }
1794
1795 fclose(ifp);
1796 }
1797
1798 // Emulate
1799
1800 emulate();
1801 } else {
1802 printf("\n");
1803 printf("ERROR> Input file %s does not exist!\n", hex_file);
1804 printf("\n");
1805 }
1806}
1807
1808void building(int args,_TCHAR** argv)
1809{
1810 char buffer[1024];
1811 load_and_run(args,argv);
1812 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",
1813 Memory[TEST_ADDRESS_1],
1814 Memory[TEST_ADDRESS_2],
1815 Memory[TEST_ADDRESS_3],
1816 Memory[TEST_ADDRESS_4],
1817 Memory[TEST_ADDRESS_5],
1818 Memory[TEST_ADDRESS_6],
1819 Memory[TEST_ADDRESS_7],
1820 Memory[TEST_ADDRESS_8],
1821 Memory[TEST_ADDRESS_9],
1822 Memory[TEST_ADDRESS_10],
1823 Memory[TEST_ADDRESS_11],
1824 Memory[TEST_ADDRESS_12]
1825 );
1826 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1827}
1828
1829
1830
1831void test_and_mark() {
1832 char buffer[1024];
1833 bool testing_complete;
1834 int len = sizeof(SOCKADDR);
1835 char chr;
1836 int i;
1837 int j;
1838 bool end_of_program;
1839 long address;
1840 long load_at;
1841 int code;
1842 int mark;
1843 int passed;
1844
1845 printf("\n");
1846 printf("Automatic Testing and Marking\n");
1847 printf("\n");
1848
1849 testing_complete = false;
1850
1851 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
1852 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1853
1854 while (!testing_complete) {
1855 memset(buffer, '\0', sizeof(buffer));
1856
1857 if (recvfrom(sock, buffer, sizeof(buffer)-1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
1858 printf("Incoming Data: %s \n", buffer);
1859
1860 //if (strcmp(buffer, "Testing complete") == 1)
1861 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
1862 testing_complete = true;
1863 printf("Current mark = %d\n", mark);
1864
1865 }else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
1866 //testing_complete = true;
1867 printf("Passed = %d\n", passed);
1868
1869 } else if (strcmp(buffer, "Error") == 0) {
1870 printf("ERROR> Testing abnormally terminated\n");
1871 testing_complete = true;
1872 } else {
1873 // Clear Registers and Memory
1874
1875 Registers[REGISTER_A] = 0;
1876 Registers[REGISTER_B] = 0;
1877 Registers[REGISTER_L] = 0;
1878 Registers[REGISTER_H] = 0;
1879 Index_Registers[REGISTER_X] = 0;
1880 Index_Registers[REGISTER_Y] = 0;
1881 Flags = 0;
1882 ProgramCounter = 0;
1883 StackPointer = 0;
1884 for (i=0; i<MEMORY_SIZE; i++) {
1885 Memory[i] = 0;
1886 }
1887
1888 // Load hex file
1889
1890 i = 0;
1891 j = 0;
1892 load_at = 0;
1893 end_of_program = false;
1894 FILE *ofp;
1895 fopen_s(&ofp ,"branch.txt", "a");
1896
1897 while (!end_of_program) {
1898 chr = buffer[i];
1899 switch (chr) {
1900 case '\0':
1901 end_of_program = true;
1902
1903 case ',':
1904 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
1905 load_at = address;
1906 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
1907 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
1908 Memory[load_at] = (BYTE)code;
1909 fprintf(ofp, "%02X\n", (BYTE)code);
1910 }
1911 load_at++;
1912 } else {
1913 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
1914 }
1915 j = 0;
1916 break;
1917
1918 default:
1919 InputBuffer[j] = chr;
1920 j++;
1921 break;
1922 }
1923 i++;
1924 }
1925 fclose(ofp);
1926 // Emulate
1927
1928 if (load_at > 1) {
1929 emulate();
1930 // Send and store results
1931 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
1932 Memory[TEST_ADDRESS_1],
1933 Memory[TEST_ADDRESS_2],
1934 Memory[TEST_ADDRESS_3],
1935 Memory[TEST_ADDRESS_4],
1936 Memory[TEST_ADDRESS_5],
1937 Memory[TEST_ADDRESS_6],
1938 Memory[TEST_ADDRESS_7],
1939 Memory[TEST_ADDRESS_8],
1940 Memory[TEST_ADDRESS_9],
1941 Memory[TEST_ADDRESS_10],
1942 Memory[TEST_ADDRESS_11],
1943 Memory[TEST_ADDRESS_12]
1944 );
1945 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1946 }
1947 }
1948 }
1949 }
1950}
1951
1952
1953
1954int _tmain(int argc, _TCHAR* argv[])
1955{
1956 char chr;
1957 char dummy;
1958
1959 printf("\n");
1960 printf("Microprocessor Emulator\n");
1961 printf("UWE Computer and Network Systems Assignment 1\n");
1962 printf("\n");
1963
1964 initialise_filenames();
1965
1966 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
1967
1968 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
1969 if (!sock) {
1970 // Creation failed!
1971 }
1972
1973 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
1974 server_addr.sin_family = AF_INET;
1975 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
1976 server_addr.sin_port = htons(PORT_SERVER);
1977
1978 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
1979 client_addr.sin_family = AF_INET;
1980 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
1981 client_addr.sin_port = htons(PORT_CLIENT);
1982
1983 chr = '\0';
1984 while ((chr != 'e') && (chr != 'E'))
1985 {
1986 printf("\n");
1987 printf("Please select option\n");
1988 printf("L - Load and run a hex file\n");
1989 printf("T - Have the server test and mark your emulator\n");
1990 printf("E - Exit\n");
1991 if(argc == 2){ building(argc,argv); exit(0);}
1992 printf("Enter option: ");
1993 chr = getchar();
1994 if (chr != 0x0A)
1995 {
1996 dummy = getchar(); // read in the <CR>
1997 }
1998 printf("\n");
1999
2000 switch (chr)
2001 {
2002 case 'L':
2003 case 'l':
2004 load_and_run(argc,argv);
2005 break;
2006
2007 case 'T':
2008 case 't':
2009 test_and_mark();
2010 break;
2011
2012 default:
2013 break;
2014 }
2015 }
2016
2017 closesocket(sock);
2018 WSACleanup();
2019
2020
2021 return 0;
2022}