· 8 years ago · Feb 20, 2018, 04:24 PM
1#include "stdafx.h"
2#include <winsock2.h>
3
4#pragma comment(lib, "wsock32.lib")
5
6#define STUDENT_NUMBER "17043938"
7#define IP_ADDRESS_SERVER "127.0.0.1"
8
9#define PORT_SERVER 0x1984 //We define a port that we are going to use.
10#define PORT_CLIENT 0x1985 //We define a port that we are going to use.
11
12#define WORD unsigned short
13#define DWORD unsigned long
14#define BYTE unsigned char
15
16#define MAX_FILENAME_SIZE 500
17#define MAX_BUFFER_SIZE 500
18
19SOCKADDR_IN server_addr;
20SOCKADDR_IN client_addr;
21
22SOCKET sock; //This is our socket, it is the handle to the IO address to read/write packets
23
24WSADATA data;
25
26char InputBuffer [MAX_BUFFER_SIZE];
27char hex_file [MAX_BUFFER_SIZE];
28char trc_file [MAX_BUFFER_SIZE];
29
30//Any mathematical/logical instructions set the flags
31//Any conditional jump or return reads the value from flags
32
33//C = carry flag, Z = zero flag, N = negative flag, I = interrupt flag, O = overflow flag
34//Zero flag = 1 if result of mathematical or logical operation = 0, or it is set to 0
35//Carry flag = 1 if addition result > 8 bits, or when a borrow is used in subtraction, otherwise it is set to 0
36//Negative flag = 1 if the MSB of the result = 1, or 0
37//Interrupt flag is used to enable/disable interrupts
38//Overflow flag = 1 if there is an overflow or borrow on the MSB. Important when signed binary arithmetic is being used.
39//16-bit WORDs can be used if the result of an operation is > 8 bits.
40
41//////////////////////////
42// Registers //
43//////////////////////////
44
45#define FLAG_I 0x10
46#define FLAG_V 0x08
47#define FLAG_N 0x04
48#define FLAG_Z 0x02
49#define FLAG_C 0x01
50#define REGISTER_A 5
51#define REGISTER_F 4
52#define REGISTER_E 3
53#define REGISTER_D 2
54#define REGISTER_C 1
55#define REGISTER_B 0
56#define REGISTER_X 0
57#define REGISTER_Y 1
58BYTE Index_Registers[2];
59
60BYTE Registers[6];
61BYTE Flags;
62WORD ProgramCounter;
63WORD StackPointer;
64
65////////////
66// Memory //
67////////////
68
69#define MEMORY_SIZE 65536
70
71BYTE Memory[MEMORY_SIZE];
72
73#define TEST_ADDRESS_1 0x01FA
74#define TEST_ADDRESS_2 0x01FB
75#define TEST_ADDRESS_3 0x01FC
76#define TEST_ADDRESS_4 0x01FD
77#define TEST_ADDRESS_5 0x01FE
78#define TEST_ADDRESS_6 0x01FF
79#define TEST_ADDRESS_7 0x0200
80#define TEST_ADDRESS_8 0x0201
81#define TEST_ADDRESS_9 0x0202
82#define TEST_ADDRESS_10 0x0203
83#define TEST_ADDRESS_11 0x0204
84#define TEST_ADDRESS_12 0x0205
85
86///////////////////////
87// Control variables //
88///////////////////////
89
90bool memory_in_range = true;
91bool halt = false;
92
93///////////////////////
94// Disassembly table //
95///////////////////////
96
97char opcode_mneumonics[][14] = {
98"ILLEGAL ",
99"ILLEGAL ",
100"STX abs ",
101"ILLEGAL ",
102"ILLEGAL ",
103"ILLEGAL ",
104"ILLEGAL ",
105"MV #,B ",
106"MV #,C ",
107"MV #,D ",
108"MV #,E ",
109"MV #,F ",
110"MAY impl ",
111"MYA impl ",
112"MAS impl ",
113"CSA impl ",
114
115"ILLEGAL ",
116"ILLEGAL ",
117"STX abs,X ",
118"ILLEGAL ",
119"ILLEGAL ",
120"ILLEGAL ",
121"SWI impl ",
122"RTI impl ",
123"CLC impl ",
124"SEC impl ",
125"CLI impl ",
126"STI impl ",
127"STV impl ",
128"CLV impl ",
129"ILLEGAL ",
130"ILLEGAL ",
131
132"ILLEGAL ",
133"ILLEGAL ",
134"STX abs,Y ",
135"ADD A,B ",
136"SUB A,B ",
137"CMP A,B ",
138"OR A,B ",
139"AND A,B ",
140"EOR A,B ",
141"BT A,B ",
142"LD A,A ",
143"LD B,A ",
144"LD C,A ",
145"LD D,A ",
146"LD E,A ",
147"LD F,A ",
148
149"ILLEGAL ",
150"LDX # ",
151"STX abs,XY ",
152"ADD A,C ",
153"SUB A,C ",
154"CMP A,C ",
155"OR A,C ",
156"AND A,C ",
157"EOR A,C ",
158"BT A,C ",
159"LD A,B ",
160"LD B,B ",
161"LD C,B ",
162"LD D,B ",
163"LD E,B ",
164"LD F,B ",
165
166"ILLEGAL ",
167"LDX abs ",
168"STX (ind),XY ",
169"ADD A,D ",
170"SUB A,D ",
171"CMP A,D ",
172"OR A,D ",
173"AND A,D ",
174"EOR A,D ",
175"BT A,D ",
176"LD A,C ",
177"LD B,C ",
178"LD C,C ",
179"LD D,C ",
180"LD E,C ",
181"LD F,C ",
182
183"ILLEGAL ",
184"LDX abs,X ",
185"ILLEGAL ",
186"ADD A,E ",
187"SUB A,E ",
188"CMP A,E ",
189"OR A,E ",
190"AND A,E ",
191"EOR A,E ",
192"BT A,E ",
193"LD A,D ",
194"LD B,D ",
195"LD C,D ",
196"LD D,D ",
197"LD E,D ",
198"LD F,D ",
199
200"ILLEGAL ",
201"LDX abs,Y ",
202"ILLEGAL ",
203"ADD A,F ",
204"SUB A,F ",
205"CMP A,F ",
206"OR A,F ",
207"AND A,F ",
208"EOR A,F ",
209"BT A,F ",
210"LD A,E ",
211"LD B,E ",
212"LD C,E ",
213"LD D,E ",
214"LD E,E ",
215"LD F,E ",
216
217"ILLEGAL ",
218"LDX abs,XY ",
219"ILLEGAL ",
220"NOP impl ",
221"HLT impl ",
222"ILLEGAL ",
223"ILLEGAL ",
224"ILLEGAL ",
225"ILLEGAL ",
226"ILLEGAL ",
227"LD A,F ",
228"LD B,F ",
229"LD C,F ",
230"LD D,F ",
231"LD E,F ",
232"LD F,F ",
233
234"ILLEGAL ",
235"LDX (ind),XY ",
236"ADI # ",
237"SBI # ",
238"CPI # ",
239"ORI # ",
240"ANI # ",
241"XRI # ",
242"ILLEGAL ",
243"ILLEGAL ",
244"ILLEGAL ",
245"ILLEGAL ",
246"ILLEGAL ",
247"ILLEGAL ",
248"ILLEGAL ",
249"ILLEGAL ",
250
251"LDA # ",
252"TST abs ",
253"INC abs ",
254"DEC abs ",
255"RCR abs ",
256"RLC abs ",
257"ASL abs ",
258"SAR abs ",
259"COM abs ",
260"RAL abs ",
261"ROR abs ",
262"LX #,A ",
263"ILLEGAL ",
264"LODS # ",
265"PUSH ,A ",
266"POP A, ",
267
268"LDA abs ",
269"TST abs,X ",
270"INC abs,X ",
271"DEC abs,X ",
272"RCR abs,X ",
273"RLC abs,X ",
274"ASL abs,X ",
275"SAR abs,X ",
276"COM abs,X ",
277"RAL abs,X ",
278"ROR abs,X ",
279"ILLEGAL ",
280"STO abs ",
281"LODS abs ",
282"PUSH ,s ",
283"POP s, ",
284
285"LDA abs,X ",
286"TST abs,Y ",
287"INC abs,Y ",
288"DEC abs,Y ",
289"RCR abs,Y ",
290"RLC abs,Y ",
291"ASL abs,Y ",
292"SAR abs,Y ",
293"COM abs,Y ",
294"RAL abs,Y ",
295"ROR abs,Y ",
296"ILLEGAL ",
297"STO abs,X ",
298"LODS abs,X ",
299"PUSH ,B ",
300"POP B, ",
301
302"LDA abs,Y ",
303"TST abs,XY ",
304"INC abs,XY ",
305"DEC abs,XY ",
306"RCR abs,XY ",
307"RLC abs,XY ",
308"ASL abs,XY ",
309"SAR abs,XY ",
310"COM abs,XY ",
311"RAL abs,XY ",
312"ROR abs,XY ",
313"ILLEGAL ",
314"STO abs,Y ",
315"LODS abs,Y ",
316"PUSH ,C ",
317"POP C, ",
318
319"LDA abs,XY ",
320"TSTA A,A ",
321"INCA A,A ",
322"DECA A,A ",
323"RCRA A,A ",
324"RLCA A,A ",
325"ASLA A,A ",
326"SARA A,A ",
327"COMA A,A ",
328"RALA A,A ",
329"RORA A,A ",
330"RTN impl ",
331"STO abs,XY ",
332"LODS abs,XY ",
333"PUSH ,D ",
334"POP D, ",
335
336"LDA (ind),XY ",
337"DEX impl ",
338"INX impl ",
339"DEY impl ",
340"INCY impl ",
341"ILLEGAL ",
342"ILLEGAL ",
343"ILLEGAL ",
344"ILLEGAL ",
345"JSR abs ",
346"JMP abs ",
347"ILLEGAL ",
348"STO (ind),XY ",
349"LODS (ind),XY",
350"PUSH ,E ",
351"POP E, ",
352
353"BRA rel ",
354"BCC rel ",
355"BCS rel ",
356"BNE rel ",
357"BEQ rel ",
358"BVC rel ",
359"BVS rel ",
360"BMI rel ",
361"BPL rel ",
362"BGE rel ",
363"BLE rel ",
364"BGT rel ",
365"BLT rel ",
366"ILLEGAL ",
367"PUSH ,F ",
368"POP F, ",
369};
370
371////////////////////////////////////////////////////////////////////////////////
372// Emulator (Start) //
373////////////////////////////////////////////////////////////////////////////////
374
375BYTE fetch() { //returns value in memory
376 BYTE b = 0;
377
378 if ((ProgramCounter >= 0) && (ProgramCounter <= MEMORY_SIZE)) {
379 memory_in_range = true;
380 b = Memory[ProgramCounter];
381 ProgramCounter++;
382 } else memory_in_range = false;
383
384 return b;
385}
386
387//functions for setting flags
388void set_flag_v(BYTE in1, BYTE in2, BYTE out) {
389 if ((((in1 & 0x80) == 0x80) && ((in2 & 0x80) == 0x80) && ((out & 0x80) != 0x80)) //overflow
390 || (((in1 & 0x80) != 0x80) && ((in2 & 0x80) != 0x80) && ((out & 0x80) == 0x80))) //overflow
391 {
392 Flags = Flags | FLAG_V;
393 }
394 else Flags = Flags & (0xFF - FLAG_V);
395}
396void set_flag_n(BYTE inReg) {
397 if ((inReg & 0x80) != 0) Flags = Flags | FLAG_N;
398 else Flags = Flags & (0xFF - FLAG_N);
399}
400void set_flag_z(BYTE inReg) {
401 if (inReg == 0) Flags = Flags | FLAG_Z;
402 else Flags = Flags & (0xFF - FLAG_Z);
403}
404void set_flags_nz(BYTE inReg) {
405 set_flag_n(inReg);
406 set_flag_z(inReg);
407}
408void set_flag_c(WORD inWord) {
409 if (inWord >= 0x100) Flags = Flags | FLAG_C;
410 else Flags = Flags & (0xFF - FLAG_C);
411}
412
413//functions that return the address for different addressing modes
414WORD address_abs() {
415 BYTE HB = fetch();
416 BYTE LB = fetch();
417 WORD address = (WORD)((WORD)HB << 8) + LB;
418 return address;
419}
420WORD address_absX() {
421 BYTE HB = fetch();
422 BYTE LB = fetch();
423 WORD address = Index_Registers[REGISTER_X];
424 address += (WORD)((WORD)HB << 8) + LB;
425 return address;
426}
427WORD address_absY() {
428 BYTE HB = fetch();
429 BYTE LB = fetch();
430 WORD address = Index_Registers[REGISTER_Y];
431 address += (WORD)((WORD)HB << 8) + LB;
432 return address;
433}
434WORD address_absXY() {
435 BYTE HB = fetch();
436 BYTE LB = fetch();
437 WORD address = (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
438 address += (WORD)((WORD)HB << 8) + LB;
439 return address;
440}
441WORD address_indXY() {
442 BYTE HB = fetch();
443 BYTE LB = fetch();
444 WORD address = (WORD)((WORD)HB << 8) + LB;
445 HB = Memory[address];
446 LB = Memory[address + 1];
447 address = (WORD)((WORD)HB << 8) + LB;
448 address += Index_Registers[REGISTER_X] + (WORD)((WORD)Index_Registers[REGISTER_Y] << 8);
449 return address;
450}
451
452//functions for different operations
453void LDA(WORD address) {
454 if (address >= 0 && address < MEMORY_SIZE) {
455 Registers[REGISTER_A] = Memory[address];
456 set_flags_nz((BYTE)Registers[REGISTER_A]);
457 }
458}
459void STO(WORD address) {
460 if (address >= 0 && address < MEMORY_SIZE) {
461 Memory[address] = Registers[REGISTER_A];
462 set_flags_nz((BYTE)Registers[REGISTER_A]);
463 }
464}
465void MV(BYTE b) {
466 Registers[b] = fetch();
467 set_flags_nz((BYTE)Registers[b]);
468}
469void LODS(WORD address) {
470 if (address >= 0 && address < MEMORY_SIZE - 1) {
471 StackPointer = (WORD)Memory[address] << 8;
472 StackPointer += Memory[address + 1];
473 set_flags_nz((BYTE)StackPointer);
474 }
475}
476void ADD(BYTE b) {
477 WORD temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[b];
478 if ((Flags & FLAG_C) != 0) temp_word++;
479
480 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[b], (BYTE)temp_word);
481 set_flags_nz((BYTE)temp_word);
482 set_flag_c((WORD)temp_word);
483
484 Registers[REGISTER_A] = (BYTE)temp_word;
485}
486void SUB(BYTE b) {
487 WORD temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[b];
488 if ((Flags & FLAG_C) != 0) temp_word--;
489
490 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[b]), (BYTE)temp_word);
491 set_flags_nz((BYTE)temp_word);
492 set_flag_c((WORD)temp_word);
493
494 Registers[REGISTER_A] = (BYTE)temp_word;
495}
496void AND(BYTE b) {
497 WORD temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[b];
498 set_flags_nz((BYTE)temp_word);
499 Registers[REGISTER_A] = (BYTE)temp_word;
500}
501void OR(BYTE b) {
502 WORD temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[b];
503 set_flags_nz((BYTE)temp_word);
504 Registers[REGISTER_A] = (BYTE)temp_word;
505}
506void EOR(BYTE b) {
507 WORD temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[b];
508 set_flags_nz((BYTE)temp_word);
509 Registers[REGISTER_A] = (BYTE)temp_word;
510}
511void BT(BYTE b) {
512 WORD temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[b];
513 set_flags_nz((BYTE)temp_word);
514}
515void CMP(BYTE b) {
516 WORD temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[b];
517 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[b]), (BYTE)temp_word);
518 set_flags_nz((BYTE)temp_word);
519 set_flag_c((WORD)temp_word);
520}
521void LDX(WORD address) {
522 if (address >= 0 && address < MEMORY_SIZE) {
523 Index_Registers[REGISTER_X] = Memory[address];
524 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
525 }
526}
527void STX(WORD address) {
528 if (address >= 0 && address < MEMORY_SIZE) {
529 Memory[address] = Index_Registers[REGISTER_X];
530 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
531 }
532}
533void INC(WORD address) {
534 if (address >= 0 && address < MEMORY_SIZE) {
535 Memory[address]++;
536 set_flags_nz((BYTE)Memory[address]);
537 }
538}
539void DEC(WORD address) {
540 if (address >= 0 && address < MEMORY_SIZE) {
541 Memory[address]--;
542 set_flags_nz((BYTE)Memory[address]);
543 }
544}
545void TST(WORD address) {
546 if (address >= 0 && address < MEMORY_SIZE) {
547 WORD temp_word = (WORD)Memory[address];
548 Memory[address] = (BYTE)temp_word;
549 set_flags_nz((BYTE)temp_word);
550 }
551}
552void ASL(WORD address) {
553 if (address >= 0 && address < MEMORY_SIZE) {
554 WORD temp_word = Memory[address] << 1;
555 Memory[address] = (BYTE)temp_word;
556 set_flags_nz((BYTE)temp_word);
557 set_flag_c((WORD)temp_word);
558 }
559}
560void SAR(WORD address) {
561 if (address >= 0 && address < MEMORY_SIZE) {
562 WORD temp_word = Memory[address] >> 1;
563 Memory[address] = (BYTE)temp_word;
564 set_flags_nz((BYTE)temp_word);
565 set_flag_c((WORD)temp_word);
566 }
567}
568void RCR(WORD address) {
569 if (address >= 0 && address < MEMORY_SIZE) {
570 BYTE saved_flags = Flags;
571 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
572 else Flags = Flags & (0xFF - FLAG_C);
573 Memory[address] = (Memory[address] >> 1) & 0x7F;
574 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
575 set_flags_nz((BYTE)Memory[address]);
576 }
577}
578void RLC(WORD address) {
579 if (address >= 0 && address < MEMORY_SIZE) {
580 BYTE saved_flags = Flags;
581 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
582 else Flags = Flags & (0xFF - FLAG_C);
583 Memory[address] = (Memory[address] << 1) & 0xFE;
584 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
585 set_flags_nz((BYTE)Memory[address]);
586 }
587}
588void RAL(WORD address) {
589 if (address >= 0 && address < MEMORY_SIZE) {
590 WORD temp_word = (Memory[address] << 1);
591 if (temp_word >= 0x100) temp_word = temp_word | 0x01;
592 Memory[address] = (BYTE)temp_word;
593 set_flags_nz((BYTE)Memory[address]);
594 }
595}
596void ROR(WORD address) {
597 if (address >= 0 && address < MEMORY_SIZE) {
598 WORD temp_word = (Memory[address] >> 1);
599 if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
600 Memory[address] = (BYTE)temp_word;
601 set_flags_nz((BYTE)Memory[address]);
602 }
603}
604void COM(WORD address) {
605 if (address >= 0 && address < MEMORY_SIZE) {
606 WORD temp_word = ~Memory[address]; // ~ is the bitwise complement
607 set_flag_c((WORD)temp_word);
608 Memory[address] = (BYTE)temp_word;
609 set_flags_nz((BYTE)Memory[address]);
610 }
611}
612void PUSH(BYTE b) {
613 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
614 Memory[StackPointer] = Registers[b];
615 StackPointer--;
616 }
617}
618void POP(BYTE b) {
619 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
620 StackPointer++;
621 Registers[b] = Memory[StackPointer];
622 }
623}
624
625void Group_1(BYTE opcode) {
626 BYTE LB = 0, HB = 0, saved_flags = 0;
627 WORD address = 0;
628 WORD data = 0;
629 WORD temp_word = 0;
630 WORD offset = 0;
631
632 switch (opcode) {
633 ////////////////////////////////////////////////// NOP (no operation) //////////////////////////////////////////////////
634 case 0x73: //NOP impl
635 //nothing
636 break;
637 ////////////////////////////////////////////////// HLT (wait for interrupt) //////////////////////////////////////////////////
638 case 0x74: //HLT impl
639 halt = true;
640 break;
641 ////////////////////////////////////////////////// LDA (loads memory into accumulator) //////////////////////////////////////////////////
642 case 0x90: //LDA #
643 Registers[REGISTER_A] = fetch();
644 set_flags_nz((BYTE)Registers[REGISTER_A]);
645 break;
646 case 0xA0: //LDA abs
647 address = address_abs();
648 LDA(address);
649 break;
650 case 0xB0: //LDA abs,X
651 address = address_absX();
652 LDA(address);
653 break;
654 case 0xC0: //LDA abs,Y
655 address = address_absY();
656 LDA(address);
657 break;
658 case 0xD0: //LDA abs,XY
659 address = address_absXY();
660 LDA(address);
661 break;
662 case 0xE0: //LDA (ind),XY
663 address = address_indXY();
664 LDA(address);
665 break;
666 ////////////////////////////////////////////////// STO (stores accumulator into memory) //////////////////////////////////////////////////
667 case 0xAC: //STO abs
668 address = address_abs();
669 STO(address);
670 break;
671 case 0xBC: //STO abs,X
672 address = address_absX();
673 STO(address);
674 break;
675 case 0xCC: //STO abs,Y
676 address = address_absY();
677 STO(address);
678 break;
679 case 0xDC: //STO abs,XY
680 address = address_absXY();
681 STO(address);
682 break;
683 case 0xEC: //STO (ind),XY
684 address = address_indXY();
685 STO(address);
686 break;
687 ////////////////////////////////////////////////// MV (loads memory into register) //////////////////////////////////////////////////
688 case 0x07: //MV B,#
689 MV(REGISTER_B);
690 break;
691 case 0x08: //MV C,#
692 MV(REGISTER_C);
693 break;
694 case 0x09: //MV D,#
695 MV(REGISTER_D);
696 break;
697 case 0x0A: //MV E,#
698 MV(REGISTER_E);
699 break;
700 case 0x0B: //MV F,#
701 MV(REGISTER_F);
702 break;
703 ////////////////////////////////////////////////// LODS (loads memory into stackpointer) //////////////////////////////////////////////////
704 case 0x9D: //LODS #
705 data = fetch();
706 StackPointer = data << 8;
707 StackPointer += fetch();
708 set_flags_nz((BYTE)StackPointer);
709 break;
710 case 0xAD: //LODS abs
711 address = address_abs();
712 LODS(address);
713 break;
714 case 0xBD: //LODS abs,X
715 address = address_absX();
716 LODS(address);
717 break;
718 case 0xCD: //LODS abs,Y
719 address = address_absY();
720 LODS(address);
721 break;
722 case 0xDD: //LODS abs,XY
723 address = address_absXY();
724 LODS(address);
725 break;
726 case 0xED: //LODS (ind),XY
727 address = address_indXY();
728 LODS(address);
729 break;
730 ////////////////////////////////////////////////// ADD (register added to accumulator with carry) //////////////////////////////////////////////////
731 case 0x23: //ADD A,B
732 ADD(REGISTER_B);
733 break;
734 case 0x33: //ADD A,C
735 ADD(REGISTER_C);
736 break;
737 case 0x43: //ADD A,D
738 ADD(REGISTER_D);
739 break;
740 case 0x53: //ADD A,E
741 ADD(REGISTER_E);
742 break;
743 case 0x63: //ADD A,F
744 ADD(REGISTER_F);
745 break;
746 ////////////////////////////////////////////////// SUB (register subtracted to accumulator with carry) //////////////////////////////////////////////////
747 case 0x24: //SUB A,B
748 SUB(REGISTER_B);
749 break;
750 case 0x34: //SUB A,C
751 SUB(REGISTER_C);
752 break;
753 case 0x44: //SUB A,D
754 SUB(REGISTER_D);
755 break;
756 case 0x54: //SUB A,E
757 SUB(REGISTER_E);
758 break;
759 case 0x64: //SUB A,F
760 SUB(REGISTER_F);
761 break;
762 ////////////////////////////////////////////////// ADI (data added to accumulator with carry) //////////////////////////////////////////////////
763 case 0x82: //ADI #
764 data = fetch();
765 temp_word = (WORD)Registers[REGISTER_A] + (WORD)data;
766 if ((Flags & FLAG_C) != 0) temp_word++;
767
768 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)data, (BYTE)temp_word);
769 set_flags_nz((BYTE)temp_word);
770 set_flag_c((WORD)temp_word);
771
772 Registers[REGISTER_A] = (BYTE)temp_word;
773 break;
774 ////////////////////////////////////////////////// SBI (data subtracted to accumulator with carry) //////////////////////////////////////////////////
775 case 0x83: //SBI #
776 data = fetch();
777 temp_word = (WORD)Registers[REGISTER_A] - (WORD)data;
778 if ((Flags & FLAG_C) != 0) temp_word--;
779
780 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-data), (BYTE)temp_word);
781 set_flags_nz((BYTE)temp_word);
782 set_flag_c((WORD)temp_word);
783
784 Registers[REGISTER_A] = (BYTE)temp_word;
785 break;
786 ////////////////////////////////////////////////// AND (register bitwise AND with accumulator) //////////////////////////////////////////////////
787 case 0x27: //AND A,B
788 AND(REGISTER_B);
789 break;
790 case 0x37: //AND A,C
791 AND(REGISTER_C);
792 break;
793 case 0x47: //AND A,D
794 AND(REGISTER_D);
795 break;
796 case 0x57: //AND A,E
797 AND(REGISTER_E);
798 break;
799 case 0x67: //AND A,F
800 AND(REGISTER_F);
801 break;
802 ////////////////////////////////////////////////// OR (register bitwise OR with accumulator) //////////////////////////////////////////////////
803 case 0x26: //OR A,B
804 OR(REGISTER_B);
805 break;
806 case 0x36: //OR A,C
807 OR(REGISTER_C);
808 break;
809 case 0x46: //OR A,D
810 OR(REGISTER_D);
811 break;
812 case 0x56: //OR A,E
813 OR(REGISTER_E);
814 break;
815 case 0x66: //OR A,F
816 OR(REGISTER_F);
817 break;
818 ////////////////////////////////////////////////// EOR (register bitwise XOR with accumulator) //////////////////////////////////////////////////
819 case 0x28: //EOR A,B
820 EOR(REGISTER_B);
821 break;
822 case 0x38: //EOR A,C
823 EOR(REGISTER_C);
824 break;
825 case 0x48: //EOR A,D
826 EOR(REGISTER_D);
827 break;
828 case 0x58: //EOR A,E
829 EOR(REGISTER_E);
830 break;
831 case 0x68: //EOR A,F
832 EOR(REGISTER_F);
833 break;
834 ////////////////////////////////////////////////// BT (register bit tested with accumulator) //////////////////////////////////////////////////
835 case 0x29: //BT A,B
836 BT(REGISTER_B);
837 break;
838 case 0x39: //BT A,C
839 BT(REGISTER_C);
840 break;
841 case 0x49: //BT A,D
842 BT(REGISTER_D);
843 break;
844 case 0x59: //BT A,E
845 BT(REGISTER_E);
846 break;
847 case 0x69: //BT A,F
848 BT(REGISTER_F);
849 break;
850 ////////////////////////////////////////////////// CMP (register compared to accumulator) //////////////////////////////////////////////////
851 case 0x25: //CMP A,B
852 CMP(REGISTER_B);
853 break;
854 case 0x35: //CMP A,C
855 CMP(REGISTER_C);
856 break;
857 case 0x45: //CMP A,D
858 CMP(REGISTER_D);
859 break;
860 case 0x55: //CMP A,E
861 CMP(REGISTER_E);
862 break;
863 case 0x65: //CMP A,F
864 CMP(REGISTER_F);
865 break;
866 ////////////////////////////////////////////////// CPI (data compared to accumulator) //////////////////////////////////////////////////
867 case 0x84: //CPI #
868 data = fetch();
869 temp_word = (WORD)Registers[REGISTER_A] - data;
870 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-data), (BYTE)temp_word);
871 set_flags_nz((BYTE)temp_word);
872 set_flag_c((WORD)temp_word);
873 break;
874 ////////////////////////////////////////////////// ANI (data bitwise AND with accumulator) //////////////////////////////////////////////////
875 case 0x86: //ANI #
876 data = fetch();
877 temp_word = (WORD)data & (WORD)Registers[REGISTER_A];
878 set_flags_nz((BYTE)temp_word);
879 Registers[REGISTER_A] = (BYTE)temp_word;
880 break;
881 ////////////////////////////////////////////////// ORI (data bitwise OR with accumulator) //////////////////////////////////////////////////
882 case 0x85: //ORI #
883 data = fetch();
884 temp_word = (WORD)data | (WORD)Registers[REGISTER_A];
885 set_flags_nz((BYTE)temp_word);
886 Registers[REGISTER_A] = (BYTE)temp_word;
887 break;
888 ////////////////////////////////////////////////// XRI (data bitwise XOR with accumulator) //////////////////////////////////////////////////
889 case 0x87: //XRI #
890 data = fetch();
891 temp_word = (WORD)data ^ (WORD)Registers[REGISTER_A];
892 set_flags_nz((BYTE)temp_word);
893 Registers[REGISTER_A] = (BYTE)temp_word;
894 break;
895 ////////////////////////////////////////////////// CSA (transfers status register to accumulator) //////////////////////////////////////////////////
896 case 0x0F: //CSA impl
897 Registers[REGISTER_A] = Flags;
898 break;
899 ////////////////////////////////////////////////// LDX (loads memory into register X) //////////////////////////////////////////////////
900 case 0x31: //LDX #
901 Index_Registers[REGISTER_X] = fetch();
902 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
903 break;
904 case 0x41: //LDX abs
905 address = address_abs();
906 LDX(address);
907 break;
908 case 0x51: //LDX abs,X
909 address = address_absX();
910 LDX(address);
911 break;
912 case 0x61: //LDX abs,Y
913 address = address_absY();
914 LDX(address);
915 break;
916 case 0x71: //LDX abs,XY
917 address = address_absXY();
918 LDX(address);
919 break;
920 case 0x81: //LDX (ind),XY
921 address = address_indXY();
922 LDX(address);
923 break;
924 ////////////////////////////////////////////////// STX (stores register X into memory) //////////////////////////////////////////////////
925 case 0x02: //STX abs
926 address = address_abs();
927 STX(address);
928 break;
929 case 0x12: //STX abs,X
930 address = address_absX();
931 STX(address);
932 break;
933 case 0x22: //STX abs,Y
934 address = address_absY();
935 STX(address);
936 break;
937 case 0x32: //STX abs,XY
938 address = address_absXY();
939 STX(address);
940 break;
941 case 0x42: //STX (ind),XY
942 address = address_indXY();
943 STX(address);
944 break;
945 ////////////////////////////////////////////////// MAY (transfers accumulator into register Y) //////////////////////////////////////////////////
946 case 0x0C: //MAY impl
947 Index_Registers[REGISTER_Y] = Registers[REGISTER_A];
948 set_flag_n((BYTE)Registers[REGISTER_A]);
949 break;
950 ////////////////////////////////////////////////// MYA (transfers register Y to accumulator) //////////////////////////////////////////////////
951 case 0x0D: //MYA impl
952 Registers[REGISTER_A] = Index_Registers[REGISTER_Y];
953 set_flags_nz((BYTE)Index_Registers[REGISTER_Y]);
954 break;
955 ////////////////////////////////////////////////// MAS (transfers accumulator to status register) //////////////////////////////////////////////////
956 case 0x0E: //MAS impl
957 Flags = Registers[REGISTER_A];
958 break;
959 ////////////////////////////////////////////////// INC (increment memory or accumulator) //////////////////////////////////////////////////
960 case 0x92: //INC abs
961 address = address_abs();
962 INC(address);
963 break;
964 case 0xA2: //INC abs,X
965 address = address_absX();
966 INC(address);
967 break;
968 case 0xB2: //INC abs,Y
969 address = address_absY();
970 INC(address);
971 break;
972 case 0xC2: //INC abs,XY
973 address = address_absXY();
974 INC(address);
975 break;
976 ////////////////////////////////////////////////// DEC (decrement memory or accumulator) //////////////////////////////////////////////////
977 case 0x93: //DEC abs
978 address = address_abs();
979 DEC(address);
980 break;
981 case 0xA3: //DEC abs,X
982 address = address_absX();
983 DEC(address);
984 break;
985 case 0xB3: //DEC abs,Y
986 address = address_absY();
987 DEC(address);
988 break;
989 case 0xC3: //DEC abs,XY
990 address = address_absXY();
991 DEC(address);
992 break;
993 ////////////////////////////////////////////////// TST (bit test memory or accumulator) //////////////////////////////////////////////////
994 case 0x91: //TST abs
995 address = address_abs();
996 TST(address);
997 break;
998 case 0xA1: //TST abs,X
999 address = address_absX();
1000 TST(address);
1001 break;
1002 case 0xB1: //TST abs,Y
1003 address = address_absY();
1004 TST(address);
1005 break;
1006 case 0xC1: //TST abs,XY
1007 address = address_absXY();
1008 TST(address);
1009 break;
1010 ////////////////////////////////////////////////// TSTA (bit test memory or accumulator) //////////////////////////////////////////////////
1011 case 0xD1: //TSTA A
1012 temp_word = (WORD)Registers[REGISTER_A];
1013 set_flags_nz((BYTE)temp_word);
1014 Registers[REGISTER_A] = (BYTE)temp_word;
1015 break;
1016 ////////////////////////////////////////////////// INCA (increment memory or accumulator) //////////////////////////////////////////////////
1017 case 0xD2: //INCA A
1018 Registers[REGISTER_A]++;
1019 set_flags_nz((BYTE)Registers[REGISTER_A]);
1020 break;
1021 ////////////////////////////////////////////////// DECA (decrement memory or accumulator) //////////////////////////////////////////////////
1022 case 0xD3: //DECA A
1023 Registers[REGISTER_A]--;
1024 set_flags_nz((BYTE)Registers[REGISTER_A]);
1025 break;
1026 ////////////////////////////////////////////////// INX (increment register X) //////////////////////////////////////////////////
1027 case 0xE2: //INX impl
1028 Index_Registers[REGISTER_X]++;
1029 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
1030 break;
1031 ////////////////////////////////////////////////// DEX (decrement register X) //////////////////////////////////////////////////
1032 case 0xE1: //DEX impl
1033 Index_Registers[REGISTER_X]--;
1034 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
1035 break;
1036 ////////////////////////////////////////////////// INCY (increment register Y) //////////////////////////////////////////////////
1037 case 0xE4: //INCY impl
1038 Index_Registers[REGISTER_Y]++;
1039 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
1040 break;
1041 ////////////////////////////////////////////////// DEY (decrement register Y) //////////////////////////////////////////////////
1042 case 0xE3: //DEY impl
1043 Index_Registers[REGISTER_Y]--;
1044 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
1045 break;
1046 ////////////////////////////////////////////////// ASL (arithmetic shift left memory or accumulator) //////////////////////////////////////////////////
1047 case 0x96: //ASL abs
1048 address = address_abs();
1049 ASL(address);
1050 break;
1051 case 0xA6: //ASL abs,X
1052 address = address_absX();
1053 ASL(address);
1054 break;
1055 case 0xB6: //ASL abs,Y
1056 address = address_absY();
1057 ASL(address);
1058 break;
1059 case 0xC6: //ASL abs,XY
1060 address = address_absXY();
1061 ASL(address);
1062 break;
1063 ////////////////////////////////////////////////// ASLA (arithmetic shift left memory or accumulator) //////////////////////////////////////////////////
1064 case 0xD6: //ASLA A
1065 temp_word = Registers[REGISTER_A] << 1;
1066 Registers[REGISTER_A] = (BYTE)temp_word;
1067 set_flags_nz((BYTE)temp_word);
1068 set_flag_c((WORD)temp_word);
1069 break;
1070 ////////////////////////////////////////////////// SAR (arithmetic shift right memory or accumulator) //////////////////////////////////////////////////
1071 case 0x97: //SAR abs
1072 address = address_abs();
1073 SAR(address);
1074 break;
1075 case 0xA7: //SAR abs,X
1076 address = address_absX();
1077 SAR(address);
1078 break;
1079 case 0xB7: //SAR abs,Y
1080 address = address_absY();
1081 SAR(address);
1082 break;
1083 case 0xC7: //SAR abs,XY
1084 address = address_absXY();
1085 SAR(address);
1086 break;
1087 ////////////////////////////////////////////////// SARA (arithmetic shift right memory or accumulator) //////////////////////////////////////////////////
1088 case 0xD7: //SARA A
1089 temp_word = Registers[REGISTER_A] >> 1;
1090 Registers[REGISTER_A] = (BYTE)temp_word;
1091 set_flags_nz((BYTE)temp_word);
1092 set_flag_c((WORD)temp_word);
1093 break;
1094 ////////////////////////////////////////////////// RCR (rotate right through carry memory or accumulator) //////////////////////////////////////////////////
1095 case 0x94: //RCR abs
1096 address = address_abs();
1097 RCR(address);
1098 break;
1099 case 0xA4: //RCR abs,X
1100 address = address_absX();
1101 RCR(address);
1102 break;
1103 case 0xB4: //RCR abs,Y
1104 address = address_absY();
1105 RCR(address);
1106 break;
1107 case 0xC4: //RCR abs,XY
1108 address = address_absXY();
1109 RCR(address);
1110 break;
1111 ////////////////////////////////////////////////// RCRA (rotate right through carry memory or accumulator) //////////////////////////////////////////////////
1112 case 0xD4: //RCRA A
1113 if ((Registers[REGISTER_A] & 0x01) == 0x01) Flags = Flags | FLAG_C;
1114 else Flags = Flags & (0xFF - FLAG_C);
1115 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
1116 if ((Flags & FLAG_C) == FLAG_C) Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
1117 set_flags_nz((BYTE)Registers[REGISTER_A]);
1118 break;
1119 ////////////////////////////////////////////////// RLC (rotate left through carry memory or accumulator) //////////////////////////////////////////////////
1120 case 0x95: //RLC abs
1121 address = address_abs();
1122 RLC(address);
1123 break;
1124 case 0xA5: //RLC abs,X
1125 address = address_absX();
1126 RLC(address);
1127 break;
1128 case 0xB5: //RLC abs,Y
1129 address = address_absY();
1130 RLC(address);
1131 break;
1132 case 0xC5: //RLC abs,XY
1133 address = address_absXY();
1134 RLC(address);
1135 break;
1136 ////////////////////////////////////////////////// RLCA (rotate left through carry memory or accumulator) //////////////////////////////////////////////////
1137 case 0xD5: //RLCA A
1138 if ((Registers[REGISTER_A] & 0x80) == 0x80) Flags = Flags | FLAG_C; //set carry based on MSB of A
1139 else Flags = Flags & (0xFF - FLAG_C);
1140
1141 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
1142 if ((Flags & FLAG_C) == FLAG_C) Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
1143
1144 set_flags_nz((BYTE)Registers[REGISTER_A]);
1145 break;
1146 ////////////////////////////////////////////////// RAL (rotate left without carry memory or accumulator) //////////////////////////////////////////////////
1147 case 0x99: //RAL abs
1148 address = address_abs();
1149 RAL(address);
1150 break;
1151 case 0xA9: //RAL abs,X
1152 address = address_absX();
1153 RAL(address);
1154 break;
1155 case 0xB9: //RAL abs,Y
1156 address = address_absY();
1157 RAL(address);
1158 break;
1159 case 0xC9: //RAL abs,XY
1160 address = address_absXY();
1161 RAL(address);
1162 break;
1163 ////////////////////////////////////////////////// RALA (rotate left without carry memory or accumulator) //////////////////////////////////////////////////
1164 case 0xD9: //RALA A
1165 temp_word = (Registers[REGISTER_A] << 1);
1166 if (temp_word >= 0x100) temp_word = temp_word | 0x01;
1167 Registers[REGISTER_A] = (BYTE)temp_word;
1168 set_flags_nz((BYTE)Registers[REGISTER_A]);
1169 break;
1170 ////////////////////////////////////////////////// ROR (rotate right without carry memory or accumulator) //////////////////////////////////////////////////
1171 case 0x9A: //ROR abs
1172 address = address_abs();
1173 ROR(address);
1174 break;
1175 case 0xAA: //ROR abs,X
1176 address = address_absX();
1177 ROR(address);
1178 break;
1179 case 0xBA: //ROR abs,Y
1180 address = address_absY();
1181 ROR(address);
1182 break;
1183 case 0xCA: //ROR abs,XY
1184 address = address_absXY();
1185 ROR(address);
1186 break;
1187 ////////////////////////////////////////////////// RORA (rotate right without carry memory or accumulator) //////////////////////////////////////////////////
1188 case 0xDA: //RORA A
1189 temp_word = (Registers[REGISTER_A] >> 1);
1190 if ((Registers[REGISTER_A] & 0x01) != 0) temp_word = temp_word | 0x80;
1191 Registers[REGISTER_A] = (BYTE)temp_word;
1192 set_flags_nz((BYTE)Registers[REGISTER_A]);
1193 break;
1194 ////////////////////////////////////////////////// COM (negate memory or accumulator) //////////////////////////////////////////////////
1195 case 0x98: //COM abs
1196 address = address_abs();
1197 COM(address);
1198 break;
1199 case 0xA8: //COM abs,X
1200 address = address_absX();
1201 COM(address);
1202 break;
1203 case 0xB8: //COM abs,Y
1204 address = address_absY();
1205 COM(address);
1206 break;
1207 case 0xC8: //COM abs,XY
1208 address = address_absXY();
1209 COM(address);
1210 break;
1211 ////////////////////////////////////////////////// COMA (negate memory or accumulator) //////////////////////////////////////////////////
1212 case 0xD8: //COMA A
1213 temp_word = ~Registers[REGISTER_A];
1214 set_flags_nz((BYTE)temp_word);
1215 set_flag_c((WORD)temp_word);
1216 Registers[REGISTER_A] = (BYTE)temp_word;
1217 break;
1218 ////////////////////////////////////////////////// LX (loads memory into register pair) //////////////////////////////////////////////////
1219 case 0x9B: //LX AB,#
1220 HB = fetch();
1221 LB = fetch();
1222 Registers[REGISTER_A] = LB;
1223 Registers[REGISTER_B] = HB;
1224 temp_word = ((WORD)LB << 8) + (WORD)HB;
1225 set_flags_nz((BYTE)temp_word);
1226 break;
1227 ////////////////////////////////////////////////// JMP (loads memory into ProgramCounter) //////////////////////////////////////////////////
1228 case 0xEA: //JMP abs
1229 address = address_abs();
1230 ProgramCounter = address;
1231 break;
1232 ////////////////////////////////////////////////// JSR (jump to subroutine) //////////////////////////////////////////////////
1233 case 0xE9: //JSR abs
1234 address = address_abs();
1235 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1236 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1237 StackPointer--;
1238 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1239 StackPointer--;
1240 }
1241 ProgramCounter = address;
1242 break;
1243 ////////////////////////////////////////////////// RTN (return from subroutine) //////////////////////////////////////////////////
1244 case 0xDB: //RTN impl
1245 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
1246 StackPointer++;
1247 HB = Memory[StackPointer];
1248 StackPointer++;
1249 LB = Memory[StackPointer];
1250 }
1251 ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
1252 break;
1253 ////////////////////////////////////////////////// BRA (branch always) //////////////////////////////////////////////////
1254 case 0xF0: //BRA rel
1255 LB = fetch();
1256 offset = (WORD)LB;
1257 if ((offset & 0x80) != 0) offset += 0xFF00;
1258 address = ProgramCounter + offset;
1259 ProgramCounter = address;
1260 break;
1261 ////////////////////////////////////////////////// BCC (branch on carry clear) //////////////////////////////////////////////////
1262 case 0xF1: //BCC rel
1263 LB = fetch();
1264 if (FLAG_C == 0x00) {
1265 offset = (WORD)LB;
1266 if ((offset & 0x80) != 0) offset += 0xFF00;
1267 address = ProgramCounter + offset;
1268 ProgramCounter = address;
1269 } else fetch();
1270 break;
1271 ////////////////////////////////////////////////// BCS (branch on carry set) //////////////////////////////////////////////////
1272 case 0xF2: //BCS rel
1273 LB = fetch();
1274 if (FLAG_C == 0x01) {
1275 offset = (WORD)LB;
1276 if ((offset & 0x80) != 0) offset += 0xFF00;
1277 address = ProgramCounter + offset;
1278 ProgramCounter = address;
1279 } else fetch();
1280 break;
1281 ////////////////////////////////////////////////// BNE (branch on result not zero) //////////////////////////////////////////////////
1282 case 0xF3: //BNE rel
1283 LB = fetch();
1284 if (FLAG_Z == 0x00) {
1285 offset = (WORD)LB;
1286 if ((offset & 0x80) != 0) offset += 0xFF00;
1287 address = ProgramCounter + offset;
1288 ProgramCounter = address;
1289 } else fetch();
1290 break;
1291 ////////////////////////////////////////////////// BEQ (branch on result equal to zero) //////////////////////////////////////////////////
1292 case 0xF4: //BEQ rel
1293 LB = fetch();
1294 if (FLAG_Z == 0x01) {
1295 offset = (WORD)LB;
1296 if ((offset & 0x80) != 0) offset += 0xFF00;
1297 address = ProgramCounter + offset;
1298 ProgramCounter = address;
1299 } else fetch();
1300 break;
1301 ////////////////////////////////////////////////// BVC (branch on overflow clear) //////////////////////////////////////////////////
1302 case 0xF5: //BVC rel
1303 LB = fetch();
1304 if (FLAG_V == 0x00) {
1305 offset = (WORD)LB;
1306 if ((offset & 0x80) != 0) offset += 0xFF00;
1307 address = ProgramCounter + offset;
1308 ProgramCounter = address;
1309 } else fetch();
1310 break;
1311 ////////////////////////////////////////////////// BVS (branch on overflow set) //////////////////////////////////////////////////
1312 case 0xF6: //BVS rel
1313 LB = fetch();
1314 if (FLAG_V == 0x01) {
1315 offset = (WORD)LB;
1316 if ((offset & 0x80) != 0) offset += 0xFF00;
1317 address = ProgramCounter + offset;
1318 ProgramCounter = address;
1319 } else fetch();
1320 break;
1321 ////////////////////////////////////////////////// BMI (branch on negative result) //////////////////////////////////////////////////
1322 case 0xF7: //BMI rel
1323 LB = fetch();
1324 if (FLAG_N == 0x01) {
1325 offset = (WORD)LB;
1326 if ((offset & 0x80) != 0) offset += 0xFF00;
1327 address = ProgramCounter + offset;
1328 ProgramCounter = address;
1329 } else fetch();
1330 break;
1331 ////////////////////////////////////////////////// BPL (branch on positive result) //////////////////////////////////////////////////
1332 case 0xF8: //BPL rel
1333 LB = fetch();
1334 if (FLAG_N == 0x00) {
1335 offset = (WORD)LB;
1336 if ((offset & 0x80) != 0) offset += 0xFF00;
1337 address = ProgramCounter + offset;
1338 ProgramCounter = address;
1339 } else fetch();
1340 break;
1341 ////////////////////////////////////////////////// BGE (branch on result <= 0) //////////////////////////////////////////////////
1342 case 0xF9: //BGE rel
1343 LB = fetch();
1344 if ((FLAG_N ^ FLAG_V) == 0x00) {
1345 offset = (WORD)LB;
1346 if ((offset & 0x80) != 0) offset += 0xFF00;
1347 address = ProgramCounter + offset;
1348 ProgramCounter = address;
1349 } else fetch();
1350 break;
1351 ////////////////////////////////////////////////// BLE (branch on result >= 0) //////////////////////////////////////////////////
1352 case 0xFA: //BLE rel
1353 LB = fetch();
1354 if ((FLAG_Z | FLAG_N ^ FLAG_V) == 0x01) {
1355 offset = (WORD)LB;
1356 if ((offset & 0x80) != 0) offset += 0xFF00;
1357 address = ProgramCounter + offset;
1358 ProgramCounter = address;
1359 } else fetch();
1360 break;
1361 ////////////////////////////////////////////////// BGT (branch on result < 0) //////////////////////////////////////////////////
1362 case 0xFB: //BGT rel
1363 LB = fetch();
1364 if ((FLAG_Z | FLAG_N ^ FLAG_V) == 0x00) {
1365 offset = (WORD)LB;
1366 if ((offset & 0x80) != 0) offset += 0xFF00;
1367 address = ProgramCounter + offset;
1368 ProgramCounter = address;
1369 } else fetch();
1370 break;
1371 ////////////////////////////////////////////////// BLT (branch on result > 0) //////////////////////////////////////////////////
1372 case 0xFC: //BLT rel
1373 LB = fetch();
1374 if ((FLAG_N ^ FLAG_V) == 0x01) {
1375 offset = (WORD)LB;
1376 if ((offset & 0x80) != 0) offset += 0xFF00;
1377 address = ProgramCounter + offset;
1378 ProgramCounter = address;
1379 } else fetch();
1380 break;
1381 ////////////////////////////////////////////////// PUSH (pushes register onto stack) //////////////////////////////////////////////////
1382 case 0x9E: //PUSH A
1383 PUSH(REGISTER_A);
1384 break;
1385 case 0xAE: //PUSH FL
1386 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1387 Memory[StackPointer] = Flags;
1388 StackPointer--;
1389 }
1390 break;
1391 case 0xBE: //PUSH B
1392 PUSH(REGISTER_B);
1393 break;
1394 case 0xCE: //PUSH C
1395 PUSH(REGISTER_C);
1396 break;
1397 case 0xDE: //PUSH D
1398 PUSH(REGISTER_D);
1399 break;
1400 case 0xEE: //PUSH E
1401 PUSH(REGISTER_E);
1402 break;
1403 case 0xFE: //PUSH F
1404 PUSH(REGISTER_F);
1405 break;
1406 ////////////////////////////////////////////////// POP (pop top of stack into register) //////////////////////////////////////////////////
1407 case 0x9F: //POP A
1408 POP(REGISTER_A);
1409 break;
1410 case 0xAF: //POP FL
1411 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1412 StackPointer++;
1413 Flags = Memory[StackPointer];
1414 }
1415 break;
1416 case 0xBF: //POP B
1417 POP(REGISTER_B);
1418 break;
1419 case 0xCF: //POP C
1420 POP(REGISTER_C);
1421 break;
1422 case 0xDF: //POP D
1423 POP(REGISTER_D);
1424 break;
1425 case 0xEF: //POP E
1426 POP(REGISTER_E);
1427 break;
1428 case 0xFF: //POP F
1429 POP(REGISTER_F);
1430 break;
1431 ////////////////////////////////////////////////// SWI (software interrupt) //////////////////////////////////////////////////
1432 case 0x16: //SWI impl
1433
1434 break;
1435 ////////////////////////////////////////////////// RTN (return from software interrupt) //////////////////////////////////////////////////
1436 case 0x17: //RTN impl
1437
1438 break;
1439 ////////////////////////////////////////////////// SEC (set carry flag) //////////////////////////////////////////////////
1440 case 0x19: //SEC impl
1441 Flags = Flags | FLAG_C;
1442 break;
1443 ////////////////////////////////////////////////// CLC (clear carry flag) //////////////////////////////////////////////////
1444 case 0x18: //CLC impl
1445 Flags = Flags & (0xFF - FLAG_C);
1446 break;
1447 ////////////////////////////////////////////////// STI (set interrupt flag) //////////////////////////////////////////////////
1448 case 0x1B: //STI impl
1449 Flags = Flags | FLAG_I;
1450 break;
1451 ////////////////////////////////////////////////// CLI (clear interrupt flag) //////////////////////////////////////////////////
1452 case 0x1A: //CLI impl
1453 Flags = Flags & (0xFF - FLAG_I);
1454 break;
1455 ////////////////////////////////////////////////// STV (set overflow flag) //////////////////////////////////////////////////
1456 case 0x1C: //STV impl
1457 Flags = Flags | FLAG_V;
1458 break;
1459 ////////////////////////////////////////////////// CLV (clear overflow flag) //////////////////////////////////////////////////
1460 case 0x1D: //CLV impl
1461 Flags = Flags & (0xFF - FLAG_V);
1462 break;
1463 }
1464}
1465
1466//LD function
1467void Group_2_Move(BYTE opcode) {
1468 BYTE destination = opcode >> 4; //top four bits point at one register....shift right to keep only top four
1469 BYTE source = opcode & 0x0F;//takes bottom four bits
1470 int destReg = 0, sourceReg = 0;
1471
1472 switch (destination) { //COMBO OF DEST AND SOURCE GIVE REGISTERS ADDRESSES TO FOR MEMORY ADRESSER AT BOTTOM
1473 case 0x02://top four bits from op code
1474 destReg = REGISTER_A;
1475 break;
1476 case 0x03:
1477 destReg = REGISTER_B;
1478 break;
1479 case 0x04:
1480 destReg = REGISTER_C;
1481 break;
1482 case 0x05:
1483 destReg = REGISTER_D;
1484 break;
1485 case 0x06:
1486 destReg = REGISTER_E;
1487 break;
1488 case 0x07:
1489 destReg = REGISTER_F;
1490 break;
1491 }
1492
1493 switch (source) {
1494 case 0x0A:
1495 sourceReg = REGISTER_A;
1496 break;
1497 case 0x0B:
1498 sourceReg = REGISTER_B;
1499 break;
1500 case 0x0C:
1501 sourceReg = REGISTER_C;
1502 break;
1503 case 0x0D:
1504 sourceReg = REGISTER_D;
1505 break;
1506 case 0x0E:
1507 sourceReg = REGISTER_E;
1508 break;
1509 case 0x0F:
1510 sourceReg = REGISTER_F;
1511 break;
1512 }
1513
1514 Registers[sourceReg] = Registers[destReg]; //code to assign sourcereg to dest reg
1515}
1516
1517void execute(BYTE opcode) {
1518 if (((opcode >= 0x2A) && (opcode <= 0x2F))
1519 || ((opcode >= 0x3A) && (opcode <= 0x3F))
1520 || ((opcode >= 0x4A) && (opcode <= 0x4F))
1521 || ((opcode >= 0x5A) && (opcode <= 0x5F))
1522 || ((opcode >= 0x6A) && (opcode <= 0x6F))
1523 || ((opcode >= 0x7A) && (opcode <= 0x7F)))
1524 {
1525 Group_2_Move(opcode);
1526 }
1527 else Group_1(opcode);
1528}
1529
1530void emulate() {
1531 BYTE opcode;
1532 int sanity = 0;
1533
1534 ProgramCounter = 0;
1535 halt = false;
1536 memory_in_range = true;
1537
1538 printf(" A B C D E F X Y SP\n");
1539
1540 while ((!halt) && (memory_in_range)) {
1541 sanity++;
1542 if (sanity > 500) halt = true;
1543 printf("%04X ", ProgramCounter); // Print current address
1544 opcode = fetch();
1545 execute(opcode);
1546
1547 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
1548 printf("%02X ", Registers[REGISTER_A]);
1549 printf("%02X ", Registers[REGISTER_B]);
1550 printf("%02X ", Registers[REGISTER_C]);
1551 printf("%02X ", Registers[REGISTER_D]);
1552 printf("%02X ", Registers[REGISTER_E]);
1553 printf("%02X ", Registers[REGISTER_F]);
1554 printf("%02X ", Index_Registers[REGISTER_X]);
1555 printf("%02X ", Index_Registers[REGISTER_Y]);
1556 printf("%04X ", StackPointer); // Print Stack Pointer
1557
1558 if ((Flags & FLAG_I) == FLAG_I) printf("I = 1, ");
1559 else printf("I = 0, ");
1560
1561 if ((Flags & FLAG_V) == FLAG_V) printf("V = 1, ");
1562 else printf("V = 0, ");
1563
1564 if ((Flags & FLAG_N) == FLAG_N) printf("N = 1, ");
1565 else printf("N = 0, ");
1566
1567 if ((Flags & FLAG_Z) == FLAG_Z) printf("Z = 1, ");
1568 else printf("Z = 0, ");
1569
1570 if ((Flags & FLAG_C) == FLAG_C) printf("C = 1 ");
1571 else printf("C = 0 ");
1572
1573 printf("\n");
1574 }
1575 printf("\n");
1576}
1577
1578
1579////////////////////////////////////////////////////////////////////////////////
1580// Emulator (End) //
1581////////////////////////////////////////////////////////////////////////////////
1582
1583void initialise_filenames() {
1584 int i;
1585
1586 for (i=0; i<MAX_FILENAME_SIZE; i++) {
1587 hex_file [i] = '\0';
1588 trc_file [i] = '\0';
1589 }
1590}
1591
1592int find_dot_position(char *filename) {
1593 int dot_position;
1594 int i;
1595 char chr;
1596
1597 dot_position = 0;
1598 i = 0;
1599 chr = filename[i];
1600
1601 while (chr != '\0') {
1602 if (chr == '.') dot_position = i;
1603
1604 i++;
1605 chr = filename[i];
1606 }
1607
1608 return dot_position;
1609}
1610
1611int find_end_position(char *filename) {
1612 int end_position;
1613 int i;
1614 char chr;
1615
1616 end_position = 0;
1617 i = 0;
1618 chr = filename[i];
1619
1620 while (chr != '\0') {
1621 end_position = i;
1622 i++;
1623 chr = filename[i];
1624 }
1625
1626 return end_position;
1627}
1628
1629bool file_exists(char *filename) {
1630 bool exists;
1631 FILE *ifp;
1632
1633 exists = false;
1634
1635 if ((ifp = fopen(filename, "r")) != NULL) {
1636 exists = true;
1637
1638 fclose(ifp);
1639 }
1640
1641 return exists;
1642}
1643
1644void create_file(char *filename) {
1645 FILE *ofp;
1646
1647 if ((ofp = fopen(filename, "w")) != NULL) fclose(ofp);
1648}
1649
1650bool getline(FILE *fp, char *buffer) {
1651 bool rc;
1652 bool collect;
1653 char c;
1654 int i;
1655
1656 rc = false;
1657 collect = true;
1658
1659 i = 0;
1660 while (collect) {
1661 c = getc(fp);
1662
1663 switch (c) {
1664 case EOF:
1665 if (i > 0) rc = true;
1666
1667 collect = false;
1668 break;
1669 case '\n':
1670 if (i > 0) {
1671 rc = true;
1672 collect = false;
1673 buffer[i] = '\0';
1674 }
1675 break;
1676 default:
1677 buffer[i] = c;
1678 i++;
1679 }
1680 }
1681
1682 return rc;
1683}
1684
1685void load_and_run(int args,_TCHAR** argv) {
1686 char chr;
1687 int ln;
1688 int dot_position;
1689 int end_position;
1690 long i;
1691 FILE *ifp;
1692 long address;
1693 long load_at;
1694 int code;
1695
1696 // Prompt for the .hex file
1697
1698 printf("\n");
1699 printf("Enter the hex filename (.hex): ");
1700
1701 if(args == 2) {
1702 ln = 0;
1703 chr = argv[1][ln];
1704 while (chr != '\0') {
1705 if (ln < MAX_FILENAME_SIZE) {
1706 hex_file [ln] = chr;
1707 trc_file [ln] = chr;
1708 ln++;
1709 }
1710 chr = argv[1][ln];
1711 }
1712 } else {
1713 ln = 0;
1714 chr = '\0';
1715 while (chr != '\n') {
1716 chr = getchar();
1717
1718 switch(chr) {
1719 case '\n':
1720 break;
1721 default:
1722 if (ln < MAX_FILENAME_SIZE) {
1723 hex_file [ln] = chr;
1724 trc_file [ln] = chr;
1725 ln++;
1726 }
1727 break;
1728 }
1729 }
1730 }
1731 // Tidy up the file names
1732
1733 dot_position = find_dot_position(hex_file);
1734 if (dot_position == 0) {
1735 end_position = find_end_position(hex_file);
1736
1737 hex_file[end_position + 1] = '.';
1738 hex_file[end_position + 2] = 'h';
1739 hex_file[end_position + 3] = 'e';
1740 hex_file[end_position + 4] = 'x';
1741 hex_file[end_position + 5] = '\0';
1742 } else {
1743 hex_file[dot_position + 0] = '.';
1744 hex_file[dot_position + 1] = 'h';
1745 hex_file[dot_position + 2] = 'e';
1746 hex_file[dot_position + 3] = 'x';
1747 hex_file[dot_position + 4] = '\0';
1748 }
1749
1750 dot_position = find_dot_position(trc_file);
1751 if (dot_position == 0) {
1752 end_position = find_end_position(trc_file);
1753
1754 trc_file[end_position + 1] = '.';
1755 trc_file[end_position + 2] = 't';
1756 trc_file[end_position + 3] = 'r';
1757 trc_file[end_position + 4] = 'c';
1758 trc_file[end_position + 5] = '\0';
1759 } else {
1760 trc_file[dot_position + 0] = '.';
1761 trc_file[dot_position + 1] = 't';
1762 trc_file[dot_position + 2] = 'r';
1763 trc_file[dot_position + 3] = 'c';
1764 trc_file[dot_position + 4] = '\0';
1765 }
1766
1767 if (file_exists(hex_file)) {
1768 // Clear Registers and Memory
1769 Registers[REGISTER_A] = 0;
1770 Registers[REGISTER_B] = 0;
1771 Registers[REGISTER_C] = 0;
1772 Registers[REGISTER_D] = 0;
1773 Registers[REGISTER_E] = 0;
1774 Registers[REGISTER_F] = 0;
1775 Index_Registers[REGISTER_X] = 0;
1776 Index_Registers[REGISTER_Y] = 0;
1777 Flags = 0;
1778 ProgramCounter = 0;
1779 StackPointer = 0;
1780
1781 for (i = 0; i < MEMORY_SIZE; i++) Memory[i] = 0x00;
1782
1783 // Load hex file
1784 if ((ifp = fopen(hex_file, "r")) != NULL) {
1785 printf("Loading file...\n\n");
1786
1787 load_at = 0;
1788
1789 while (getline(ifp, InputBuffer)) {
1790 if (sscanf(InputBuffer, "L=%x", &address) == 1) load_at = address;
1791 else if (sscanf(InputBuffer, "%x", &code) == 1) {
1792 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) Memory[load_at] = (BYTE)code;
1793
1794 load_at++;
1795 } else printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
1796 }
1797
1798 fclose(ifp);
1799 }
1800
1801 emulate();
1802 } else {
1803 printf("\n");
1804 printf("ERROR> Input file %s does not exist!\n", hex_file);
1805 printf("\n");
1806 }
1807}
1808
1809void building(int args,_TCHAR** argv){
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
1829void test_and_mark() {
1830 char buffer[1024];
1831 bool testing_complete;
1832 int len = sizeof(SOCKADDR);
1833 char chr;
1834 int i;
1835 int j;
1836 bool end_of_program;
1837 long address;
1838 long load_at;
1839 int code;
1840 int mark;
1841 int passed;
1842
1843 printf("Automatic Testing and Marking\n");
1844 printf("\n");
1845
1846 testing_complete = false;
1847
1848 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
1849 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1850
1851 while (!testing_complete) {
1852 memset(buffer, '\0', sizeof(buffer));
1853
1854 if (recvfrom(sock, buffer, sizeof(buffer)-1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
1855 printf("Incoming Data: %s \n", buffer);
1856
1857 //if (strcmp(buffer, "Testing complete") == 1)
1858 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
1859 testing_complete = true;
1860 printf("Current mark = %d\n", mark);
1861 }else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
1862 //testing_complete = true;
1863 printf("Passed = %d\n", passed);
1864 } else if (strcmp(buffer, "Error") == 0) {
1865 printf("ERROR> Testing abnormally terminated\n");
1866 testing_complete = true;
1867 } else {
1868 // Clear Registers and Memory
1869 Registers[REGISTER_A] = 0;
1870 Registers[REGISTER_B] = 0;
1871 Registers[REGISTER_C] = 0;
1872 Registers[REGISTER_D] = 0;
1873 Registers[REGISTER_E] = 0;
1874 Registers[REGISTER_F] = 0;
1875 Index_Registers[REGISTER_X] = 0;
1876 Index_Registers[REGISTER_Y] = 0;
1877 Flags = 0;
1878 ProgramCounter = 0;
1879 StackPointer = 0;
1880 for (i = 0; i < MEMORY_SIZE; i++) Memory[i] = 0;
1881
1882 // Load hex file
1883 i = 0;
1884 j = 0;
1885 load_at = 0;
1886 end_of_program = false;
1887 FILE *ofp;
1888 fopen_s(&ofp ,"branch.txt", "a");
1889
1890 while (!end_of_program) {
1891 chr = buffer[i];
1892 switch (chr) {
1893 case '\0':
1894 end_of_program = true;
1895 case ',':
1896 if (sscanf(InputBuffer, "L=%x", &address) == 1) load_at = address;
1897 else if (sscanf(InputBuffer, "%x", &code) == 1) {
1898 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
1899 Memory[load_at] = (BYTE)code;
1900 fprintf(ofp, "%02X\n", (BYTE)code);
1901 }
1902 load_at++;
1903 } else printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
1904
1905 j = 0;
1906 break;
1907 default:
1908 InputBuffer[j] = chr;
1909 j++;
1910 break;
1911 }
1912 i++;
1913 }
1914 fclose(ofp);
1915 // Emulate
1916
1917 if (load_at > 1) {
1918 emulate();
1919 // Send and store results
1920 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
1921 Memory[TEST_ADDRESS_1],
1922 Memory[TEST_ADDRESS_2],
1923 Memory[TEST_ADDRESS_3],
1924 Memory[TEST_ADDRESS_4],
1925 Memory[TEST_ADDRESS_5],
1926 Memory[TEST_ADDRESS_6],
1927 Memory[TEST_ADDRESS_7],
1928 Memory[TEST_ADDRESS_8],
1929 Memory[TEST_ADDRESS_9],
1930 Memory[TEST_ADDRESS_10],
1931 Memory[TEST_ADDRESS_11],
1932 Memory[TEST_ADDRESS_12]
1933 );
1934 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
1935 }
1936 }
1937 }
1938 }
1939}
1940
1941int _tmain(int argc, _TCHAR* argv[]) {
1942 char chr;
1943 char dummy;
1944
1945 printf("Microprocessor Emulator\n");
1946 printf("UWE Computer and Network Systems Assignment 1\n");
1947 printf("\n");
1948
1949 initialise_filenames();
1950
1951 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
1952
1953 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
1954 if (!sock) {
1955 //Creation failed!
1956 }
1957
1958 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
1959 server_addr.sin_family = AF_INET;
1960 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
1961 server_addr.sin_port = htons(PORT_SERVER);
1962
1963 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
1964 client_addr.sin_family = AF_INET;
1965 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
1966 client_addr.sin_port = htons(PORT_CLIENT);
1967
1968 chr = '\0';
1969 while ((chr != 'e') && (chr != 'E')) {
1970 printf("\nPlease select option\n");
1971 printf("L - Load and run a hex file\n");
1972 printf("T - Have the server test and mark your emulator\n");
1973 printf("E - Exit\n");
1974 if(argc == 2){ building(argc,argv); exit(0);}
1975 printf("Enter option: ");
1976 chr = getchar();
1977 if (chr != 0x0A) dummy = getchar(); // read in the <CR>
1978
1979 printf("\n");
1980
1981 switch (chr) {
1982 case 'L': case 'l':
1983 load_and_run(argc,argv);
1984 break;
1985 case 'T': case 't':
1986 test_and_mark();
1987 break;
1988 }
1989 }
1990
1991 closesocket(sock);
1992 WSACleanup();
1993
1994 return 0;
1995}