· 8 years ago · Feb 20, 2018, 03:22 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
452void Group_1(BYTE opcode) {
453 BYTE LB = 0, HB = 0, saved_flags = 0;
454 WORD address = 0;
455 WORD data = 0;
456 WORD temp_word = 0;
457 WORD offset = 0;
458
459 switch (opcode) {
460 ////////////////////////////////////////////////// NOP (no operation) //////////////////////////////////////////////////
461 case 0x73: //NOP impl
462 //nothing
463 break;
464 ////////////////////////////////////////////////// HLT (wait for interrupt) //////////////////////////////////////////////////
465 case 0x74: //HLT impl
466 halt = true;
467 break;
468 ////////////////////////////////////////////////// LDA (loads memory into accumulator) //////////////////////////////////////////////////
469 case 0x90: //LDA #
470 Registers[REGISTER_A] = fetch();
471 set_flags_nz((BYTE)Registers[REGISTER_A]);
472 break;
473 case 0xA0: //LDA abs
474 address = address_abs();
475 if (address >= 0 && address < MEMORY_SIZE) {
476 Registers[REGISTER_A] = Memory[address];
477 set_flags_nz((BYTE)Registers[REGISTER_A]);
478 }
479 break;
480 case 0xB0: //LDA abs,X
481 address = address_absX();
482 if (address >= 0 && address < MEMORY_SIZE) {
483 Registers[REGISTER_A] = Memory[address];
484 set_flags_nz((BYTE)Registers[REGISTER_A]);
485 }
486 break;
487 case 0xC0: //LDA abs,Y
488 address = address_absY();
489 if (address >= 0 && address < MEMORY_SIZE) {
490 Registers[REGISTER_A] = Memory[address];
491 set_flags_nz((BYTE)Registers[REGISTER_A]);
492 }
493 break;
494 case 0xD0: //LDA abs,XY
495 address = address_absXY();
496 if (address >= 0 && address < MEMORY_SIZE) {
497 Registers[REGISTER_A] = Memory[address];
498 set_flags_nz((BYTE)Registers[REGISTER_A]);
499 }
500 break;
501 case 0xE0: //LDA (ind),XY
502 address = address_indXY();
503 if (address >= 0 && address < MEMORY_SIZE) {
504 Registers[REGISTER_A] = Memory[address];
505 set_flags_nz((BYTE)Registers[REGISTER_A]);
506 }
507 break;
508 ////////////////////////////////////////////////// STO (stores accumulator into memory) //////////////////////////////////////////////////
509 case 0xAC: //STO abs
510 address = address_abs();
511 if (address >= 0 && address < MEMORY_SIZE) {
512 Memory[address] = Registers[REGISTER_A];
513 set_flags_nz((BYTE)Registers[REGISTER_A]);
514 }
515 break;
516 case 0xBC: //STO abs,X
517 address = address_absX();
518 if (address >= 0 && address < MEMORY_SIZE) {
519 Memory[address] = Registers[REGISTER_A];
520 set_flags_nz((BYTE)Registers[REGISTER_A]);
521 }
522 break;
523 case 0xCC: //STO abs,Y
524 address = address_absY();
525 if (address >= 0 && address < MEMORY_SIZE) {
526 Memory[address] = Registers[REGISTER_A];
527 set_flags_nz((BYTE)Registers[REGISTER_A]);
528 }
529 break;
530 case 0xDC: //STO abs,XY
531 address = address_absXY();
532 if (address >= 0 && address < MEMORY_SIZE) {
533 Memory[address] = Registers[REGISTER_A];
534 set_flags_nz((BYTE)Registers[REGISTER_A]);
535 }
536 break;
537 case 0xEC: //STO (ind),XY
538 address = address_indXY();
539 if (address >= 0 && address < MEMORY_SIZE) {
540 Memory[address] = Registers[REGISTER_A];
541 set_flags_nz((BYTE)Registers[REGISTER_A]);
542 }
543 break;
544 ////////////////////////////////////////////////// MV (loads memory into register) //////////////////////////////////////////////////
545 case 0x07: //MV B,#
546 Registers[REGISTER_B] = fetch();
547 set_flags_nz((BYTE)Registers[REGISTER_B]);
548 break;
549 case 0x08: //MV C,#
550 Registers[REGISTER_C] = fetch();
551 set_flags_nz((BYTE)Registers[REGISTER_C]);
552 break;
553 case 0x09: //MV D,#
554 Registers[REGISTER_D] = fetch();
555 set_flags_nz((BYTE)Registers[REGISTER_D]);
556 break;
557 case 0x0A: //MV E,#
558 Registers[REGISTER_E] = fetch();
559 set_flags_nz((BYTE)Registers[REGISTER_E]);
560 break;
561 case 0x0B: //MV F,#
562 Registers[REGISTER_F] = fetch();
563 set_flags_nz((BYTE)Registers[REGISTER_F]);
564 break;
565 ////////////////////////////////////////////////// LODS (loads memory into stackpointer) //////////////////////////////////////////////////
566 case 0x9D: //LODS #
567 data = fetch();
568 StackPointer = data << 8;
569 StackPointer += fetch();
570 set_flags_nz((BYTE)StackPointer);
571 break;
572 case 0xAD: //LODS abs
573 address = address_abs();
574 if (address >= 0 && address < MEMORY_SIZE - 1) {
575 StackPointer = (WORD)Memory[address] << 8;
576 StackPointer += Memory[address + 1];
577 set_flags_nz((BYTE)StackPointer);
578 }
579 break;
580 case 0xBD: //LODS abs,X
581 address = address_absX();
582 if (address >= 0 && address < MEMORY_SIZE - 1) {
583 StackPointer = (WORD)Memory[address] << 8;
584 StackPointer += Memory[address + 1];
585 set_flags_nz((BYTE)StackPointer);
586 }
587 break;
588 case 0xCD: //LODS abs,Y
589 address = address_absY();
590 if (address >= 0 && address < MEMORY_SIZE - 1) {
591 StackPointer = (WORD)Memory[address] << 8;
592 StackPointer += Memory[address + 1];
593 set_flags_nz((BYTE)StackPointer);
594 }
595 break;
596 case 0xDD: //LODS abs,XY
597 address = address_absXY();
598 if (address >= 0 && address < MEMORY_SIZE - 1) {
599 StackPointer = (WORD)Memory[address] << 8;
600 StackPointer += Memory[address + 1];
601 set_flags_nz((BYTE)StackPointer);
602 }
603 break;
604 case 0xED: //LODS (ind),XY
605 address = address_indXY();
606 if (address >= 0 && address < MEMORY_SIZE - 1) {
607 StackPointer = (WORD)Memory[address] << 8;
608 StackPointer += Memory[address + 1];
609 set_flags_nz((BYTE)StackPointer);
610 }
611 break;
612 ////////////////////////////////////////////////// ADD (register added to accumulator with carry) //////////////////////////////////////////////////
613 case 0x23: //ADD A,B
614 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
615 if ((Flags & FLAG_C) != 0) temp_word++;
616
617 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_B], (BYTE)temp_word);
618 set_flags_nz((BYTE)temp_word);
619 set_flag_c((WORD)temp_word);
620
621 Registers[REGISTER_A] = (BYTE)temp_word;
622 break;
623 case 0x33: //ADD A,C
624 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
625 if ((Flags & FLAG_C) != 0) temp_word++;
626
627 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_C], (BYTE)temp_word);
628 set_flags_nz((BYTE)temp_word);
629 set_flag_c((WORD)temp_word);
630
631 Registers[REGISTER_A] = (BYTE)temp_word;
632 break;
633 case 0x43: //ADD A,D
634 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_D];
635 if ((Flags & FLAG_C) != 0) temp_word++;
636
637 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_D], (BYTE)temp_word);
638 set_flags_nz((BYTE)temp_word);
639 set_flag_c((WORD)temp_word);
640
641 Registers[REGISTER_A] = (BYTE)temp_word;
642 break;
643 case 0x53: //ADD A,E
644 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_E];
645 if ((Flags & FLAG_C) != 0) temp_word++;
646
647 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_E], (BYTE)temp_word);
648 set_flags_nz((BYTE)temp_word);
649 set_flag_c((WORD)temp_word);
650
651 Registers[REGISTER_A] = (BYTE)temp_word;
652 break;
653 case 0x63: //ADD A,F
654 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_F];
655 if ((Flags & FLAG_C) != 0) temp_word++;
656
657 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_F], (BYTE)temp_word);
658 set_flags_nz((BYTE)temp_word);
659 set_flag_c((WORD)temp_word);
660
661 Registers[REGISTER_A] = (BYTE)temp_word;
662 break;
663 ////////////////////////////////////////////////// SUB (register subtracted to accumulator with carry) //////////////////////////////////////////////////
664 case 0x24: //SUB A,B
665 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
666 if ((Flags & FLAG_C) != 0) temp_word--;
667
668 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_B]), (BYTE)temp_word);
669 set_flags_nz((BYTE)temp_word);
670 set_flag_c((WORD)temp_word);
671
672 Registers[REGISTER_A] = (BYTE)temp_word;
673 break;
674 case 0x34: //SUB A,C
675 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
676 if ((Flags & FLAG_C) != 0) temp_word--;
677
678 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_C]), (BYTE)temp_word);
679 set_flags_nz((BYTE)temp_word);
680 set_flag_c((WORD)temp_word);
681
682 Registers[REGISTER_A] = (BYTE)temp_word;
683 break;
684 case 0x44: //SUB A,D
685 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
686 if ((Flags & FLAG_C) != 0) temp_word--;
687
688 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_D]), (BYTE)temp_word);
689 set_flags_nz((BYTE)temp_word);
690 set_flag_c((WORD)temp_word);
691
692 Registers[REGISTER_A] = (BYTE)temp_word;
693 break;
694 case 0x54: //SUB A,E
695 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
696 if ((Flags & FLAG_C) != 0) temp_word--;
697
698 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_E]), (BYTE)temp_word);
699 set_flags_nz((BYTE)temp_word);
700 set_flag_c((WORD)temp_word);
701
702 Registers[REGISTER_A] = (BYTE)temp_word;
703 break;
704 case 0x64: //SUB A,F
705 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_F];
706 if ((Flags & FLAG_C) != 0) temp_word--;
707
708 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_F]), (BYTE)temp_word);
709 set_flags_nz((BYTE)temp_word);
710 set_flag_c((WORD)temp_word);
711
712 Registers[REGISTER_A] = (BYTE)temp_word;
713 break;
714 ////////////////////////////////////////////////// ADI (data added to accumulator with carry) //////////////////////////////////////////////////
715 case 0x82: //ADI #
716 data = fetch();
717 temp_word = (WORD)Registers[REGISTER_A] + (WORD)data;
718 if ((Flags & FLAG_C) != 0) temp_word++;
719
720 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)data, (BYTE)temp_word);
721 set_flags_nz((BYTE)temp_word);
722 set_flag_c((WORD)temp_word);
723
724 Registers[REGISTER_A] = (BYTE)temp_word;
725 break;
726 ////////////////////////////////////////////////// SBI (data subtracted to accumulator with carry) //////////////////////////////////////////////////
727 case 0x83: //SBI #
728 data = fetch();
729 temp_word = (WORD)Registers[REGISTER_A] - (WORD)data;
730 if ((Flags & FLAG_C) != 0) temp_word--;
731
732 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-data), (BYTE)temp_word);
733 set_flags_nz((BYTE)temp_word);
734 set_flag_c((WORD)temp_word);
735
736 Registers[REGISTER_A] = (BYTE)temp_word;
737 break;
738 ////////////////////////////////////////////////// AND (register bitwise AND with accumulator) //////////////////////////////////////////////////
739 case 0x27: //AND A,B
740 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_B];
741 set_flags_nz((BYTE)temp_word);
742 Registers[REGISTER_A] = (BYTE)temp_word;
743 break;
744 case 0x37: //AND A,C
745 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_C];
746 set_flags_nz((BYTE)temp_word);
747 Registers[REGISTER_A] = (BYTE)temp_word;
748 break;
749 case 0x47: //AND A,D
750 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_D];
751 set_flags_nz((BYTE)temp_word);
752 Registers[REGISTER_A] = (BYTE)temp_word;
753 break;
754 case 0x57: //AND A,E
755 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_E];
756 set_flags_nz((BYTE)temp_word);
757 Registers[REGISTER_A] = (BYTE)temp_word;
758 break;
759 case 0x67: //AND A,F
760 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_F];
761 set_flags_nz((BYTE)temp_word);
762 Registers[REGISTER_A] = (BYTE)temp_word;
763 break;
764 ////////////////////////////////////////////////// OR (register bitwise OR with accumulator) //////////////////////////////////////////////////
765 case 0x26: //OR A,B
766 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_B];
767 set_flags_nz((BYTE)temp_word);
768 Registers[REGISTER_A] = (BYTE)temp_word;
769 break;
770 case 0x36: //OR A,C
771 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_C];
772 set_flags_nz((BYTE)temp_word);
773 Registers[REGISTER_A] = (BYTE)temp_word;
774 break;
775 case 0x46: //OR A,D
776 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_D];
777 set_flags_nz((BYTE)temp_word);
778 Registers[REGISTER_A] = (BYTE)temp_word;
779 break;
780 case 0x56: //OR A,E
781 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_E];
782 set_flags_nz((BYTE)temp_word);
783 Registers[REGISTER_A] = (BYTE)temp_word;
784 break;
785 case 0x66: //OR A,F
786 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_F];
787 set_flags_nz((BYTE)temp_word);
788 Registers[REGISTER_A] = (BYTE)temp_word;
789 break;
790 ////////////////////////////////////////////////// EOR (register bitwise XOR with accumulator) //////////////////////////////////////////////////
791 case 0x28: //EOR A,B
792 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_B];
793 set_flags_nz((BYTE)temp_word);
794 Registers[REGISTER_A] = (BYTE)temp_word;
795 break;
796 case 0x38: //EOR A,C
797 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_C];
798 set_flags_nz((BYTE)temp_word);
799 Registers[REGISTER_A] = (BYTE)temp_word;
800 break;
801 case 0x48: //EOR A,D
802 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_D];
803 set_flags_nz((BYTE)temp_word);
804 Registers[REGISTER_A] = (BYTE)temp_word;
805 break;
806 case 0x58: //EOR A,E
807 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_E];
808 set_flags_nz((BYTE)temp_word);
809 Registers[REGISTER_A] = (BYTE)temp_word;
810 break;
811 case 0x68: //EOR A,F
812 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_F];
813 set_flags_nz((BYTE)temp_word);
814 Registers[REGISTER_A] = (BYTE)temp_word;
815 break;
816 ////////////////////////////////////////////////// BT (register bit tested with accumulator) //////////////////////////////////////////////////
817 case 0x29: //BT A,B
818 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_B];
819 set_flags_nz((BYTE)temp_word);
820 break;
821 case 0x39: //BT A,C
822 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_C];
823 set_flags_nz((BYTE)temp_word);
824 break;
825 case 0x49: //BT A,D
826 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_D];
827 set_flags_nz((BYTE)temp_word);
828 break;
829 case 0x59: //BT A,E
830 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_E];
831 set_flags_nz((BYTE)temp_word);
832 break;
833 case 0x69: //BT A,F
834 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_F];
835 set_flags_nz((BYTE)temp_word);
836 break;
837 ////////////////////////////////////////////////// CMP (register compared to accumulator) //////////////////////////////////////////////////
838 case 0x25: //CMP A,B
839 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
840 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_B]), (BYTE)temp_word);
841 set_flags_nz((BYTE)temp_word);
842 set_flag_c((WORD)temp_word);
843 break;
844 case 0x35: //CMP A,C
845 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
846 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_C]), (BYTE)temp_word);
847 set_flags_nz((BYTE)temp_word);
848 set_flag_c((WORD)temp_word);
849 break;
850 case 0x45: //CMP A,D
851 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
852 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_D]), (BYTE)temp_word);
853 set_flags_nz((BYTE)temp_word);
854 set_flag_c((WORD)temp_word);
855 break;
856 case 0x55: //CMP A,E
857 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
858 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_E]), (BYTE)temp_word);
859 set_flags_nz((BYTE)temp_word);
860 set_flag_c((WORD)temp_word);
861 break;
862 case 0x65: //CMP A,F
863 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_F];
864 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_F]), (BYTE)temp_word);
865 set_flags_nz((BYTE)temp_word);
866 set_flag_c((WORD)temp_word);
867 break;
868 ////////////////////////////////////////////////// CPI (data compared to accumulator) //////////////////////////////////////////////////
869 case 0x84: //CPI #
870 data = fetch();
871 temp_word = (WORD)Registers[REGISTER_A] - data;
872 set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-data), (BYTE)temp_word);
873 set_flags_nz((BYTE)temp_word);
874 set_flag_c((WORD)temp_word);
875 break;
876 ////////////////////////////////////////////////// ANI (data bitwise AND with accumulator) //////////////////////////////////////////////////
877 case 0x86: //ANI #
878 data = fetch();
879 temp_word = (WORD)data & (WORD)Registers[REGISTER_A];
880 set_flags_nz((BYTE)temp_word);
881 Registers[REGISTER_A] = (BYTE)temp_word;
882 break;
883 ////////////////////////////////////////////////// ORI (data bitwise OR with accumulator) //////////////////////////////////////////////////
884 case 0x85: //ORI #
885 data = fetch();
886 temp_word = (WORD)data | (WORD)Registers[REGISTER_A];
887 set_flags_nz((BYTE)temp_word);
888 Registers[REGISTER_A] = (BYTE)temp_word;
889 break;
890 ////////////////////////////////////////////////// XRI (data bitwise XOR with accumulator) //////////////////////////////////////////////////
891 case 0x87: //XRI #
892 data = fetch();
893 temp_word = (WORD)data ^ (WORD)Registers[REGISTER_A];
894 set_flags_nz((BYTE)temp_word);
895 Registers[REGISTER_A] = (BYTE)temp_word;
896 break;
897 ////////////////////////////////////////////////// CSA (transfers status register to accumulator) //////////////////////////////////////////////////
898 case 0x0F: //CSA impl
899 Registers[REGISTER_A] = Flags;
900 break;
901 ////////////////////////////////////////////////// LDX (loads memory into register X) //////////////////////////////////////////////////
902 case 0x31: //LDX #
903 Index_Registers[REGISTER_X] = fetch();
904 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
905 break;
906 case 0x41: //LDX abs
907 address = address_abs();
908 if (address >= 0 && address < MEMORY_SIZE) {
909 Index_Registers[REGISTER_X] = Memory[address];
910 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
911 }
912 break;
913 case 0x51: //LDX abs,X
914 address = address_absX();
915 if (address >= 0 && address < MEMORY_SIZE) {
916 Index_Registers[REGISTER_X] = Memory[address];
917 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
918 }
919 break;
920 case 0x61: //LDX abs,Y
921 address = address_absY();
922 if (address >= 0 && address < MEMORY_SIZE) {
923 Index_Registers[REGISTER_X] = Memory[address];
924 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
925 }
926 break;
927 case 0x71: //LDX abs,XY
928 address = address_absXY();
929 if (address >= 0 && address < MEMORY_SIZE) {
930 Index_Registers[REGISTER_X] = Memory[address];
931 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
932 }
933 break;
934 case 0x81: //LDX (ind),XY
935 address = address_indXY();
936 if (address >= 0 && address < MEMORY_SIZE) {
937 Index_Registers[REGISTER_A] = Memory[address];
938 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
939 }
940 break;
941 ////////////////////////////////////////////////// STX (stores register X into memory) //////////////////////////////////////////////////
942 case 0x02: //STX abs
943 address = address_abs();
944 if (address >= 0 && address < MEMORY_SIZE) {
945 Memory[address] = Index_Registers[REGISTER_X];
946 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
947 }
948 break;
949 case 0x12: //STX abs,X
950 address = address_absX();
951 if (address >= 0 && address < MEMORY_SIZE) {
952 Memory[address] = Index_Registers[REGISTER_X];
953 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
954 }
955 break;
956 case 0x22: //STX abs,Y
957 address = address_absY();
958 if (address >= 0 && address < MEMORY_SIZE) {
959 Memory[address] = Index_Registers[REGISTER_X];
960 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
961 }
962 break;
963 case 0x32: //STX abs,XY
964 address = address_absXY();
965 if (address >= 0 && address < MEMORY_SIZE) {
966 Memory[address] = Index_Registers[REGISTER_X];
967 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
968 }
969 break;
970 case 0x42: //STX (ind),XY
971 address = address_indXY();
972 if (address >= 0 && address < MEMORY_SIZE) {
973 Memory[address] = Index_Registers[REGISTER_X];
974 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
975 }
976 break;
977 ////////////////////////////////////////////////// MAY (transfers accumulator into register Y) //////////////////////////////////////////////////
978 case 0x0C: //MAY impl
979 Index_Registers[REGISTER_Y] = Registers[REGISTER_A];
980 set_flag_n((BYTE)Registers[REGISTER_A]);
981 break;
982 ////////////////////////////////////////////////// MYA (transfers register Y to accumulator) //////////////////////////////////////////////////
983 case 0x0D: //MYA impl
984 Registers[REGISTER_A] = Index_Registers[REGISTER_Y];
985 set_flags_nz((BYTE)Index_Registers[REGISTER_Y]);
986 break;
987 ////////////////////////////////////////////////// MAS (transfers accumulator to status register) //////////////////////////////////////////////////
988 case 0x0E: //MAS impl
989 Flags = Registers[REGISTER_A];
990 break;
991 ////////////////////////////////////////////////// INC (increment memory or accumulator) //////////////////////////////////////////////////
992 case 0x92: //INC abs
993 address = address_abs();
994 if (address >= 0 && address < MEMORY_SIZE) {
995 Memory[address]++;
996 set_flags_nz((BYTE)Memory[address]);
997 }
998 break;
999 case 0xA2: //INC abs,X
1000 address = address_absX();
1001 if (address >= 0 && address < MEMORY_SIZE) {
1002 Memory[address]++;
1003 set_flags_nz((BYTE)Memory[address]);
1004 }
1005 break;
1006 case 0xB2: //INC abs,Y
1007 address = address_absY();
1008 if (address >= 0 && address < MEMORY_SIZE) {
1009 Memory[address]++;
1010 set_flags_nz((BYTE)Memory[address]);
1011 }
1012 break;
1013 case 0xC2: //INC abs,XY
1014 address = address_absXY();
1015 if (address >= 0 && address < MEMORY_SIZE) {
1016 Memory[address]++;
1017 set_flags_nz((BYTE)Memory[address]);
1018 }
1019 break;
1020 ////////////////////////////////////////////////// DEC (decrement memory or accumulator) //////////////////////////////////////////////////
1021 case 0x93: //DEC abs
1022 address = address_abs();
1023 if (address >= 0 && address < MEMORY_SIZE) {
1024 Memory[address]--;
1025 set_flags_nz((BYTE)Memory[address]);
1026 }
1027 break;
1028 case 0xA3: //DEC abs,X
1029 address = address_absX();
1030 if (address >= 0 && address < MEMORY_SIZE) {
1031 Memory[address]--;
1032 set_flags_nz((BYTE)Memory[address]);
1033 }
1034 break;
1035 case 0xB3: //DEC abs,Y
1036 address = address_absY();
1037 if (address >= 0 && address < MEMORY_SIZE) {
1038 Memory[address]--;
1039 set_flags_nz((BYTE)Memory[address]);
1040 }
1041 break;
1042 case 0xC3: //DEC abs,XY
1043 address = address_absXY();
1044 if (address >= 0 && address < MEMORY_SIZE) {
1045 Memory[address]--;
1046 set_flags_nz((BYTE)Memory[address]);
1047 }
1048 break;
1049 ////////////////////////////////////////////////// TST (bit test memory or accumulator) //////////////////////////////////////////////////
1050 case 0x91: //TST abs
1051 address = address_abs();
1052 if (address >= 0 && address < MEMORY_SIZE) {
1053 temp_word = (WORD)Memory[address];
1054 Memory[address] = (BYTE)temp_word;
1055 set_flags_nz((BYTE)temp_word);
1056 }
1057 break;
1058 case 0xA1: //TST abs,X
1059 address = address_absX();
1060 if (address >= 0 && address < MEMORY_SIZE) {
1061 temp_word = (WORD)Memory[address];
1062 Memory[address] = (BYTE)temp_word;
1063 set_flags_nz((BYTE)temp_word);
1064 }
1065 break;
1066 case 0xB1: //TST abs,Y
1067 address = address_absY();
1068 if (address >= 0 && address < MEMORY_SIZE) {
1069 temp_word = (WORD)Memory[address];
1070 Memory[address] = (BYTE)temp_word;
1071 set_flags_nz((BYTE)temp_word);
1072 }
1073 break;
1074 case 0xC1: //TST abs,XY
1075 address = address_absXY();
1076 if (address >= 0 && address < MEMORY_SIZE) {
1077 temp_word = (WORD)Memory[address];
1078 Memory[address] = (BYTE)temp_word;
1079 set_flags_nz((BYTE)temp_word);
1080 }
1081 break;
1082 ////////////////////////////////////////////////// TSTA (bit test memory or accumulator) //////////////////////////////////////////////////
1083 case 0xD1: //TSTA A
1084 temp_word = (WORD)Registers[REGISTER_A];
1085 set_flags_nz((BYTE)temp_word);
1086 Registers[REGISTER_A] = (BYTE)temp_word;
1087 break;
1088 ////////////////////////////////////////////////// INCA (increment memory or accumulator) //////////////////////////////////////////////////
1089 case 0xD2: //INCA A
1090 Registers[REGISTER_A]++;
1091 set_flags_nz((BYTE)Registers[REGISTER_A]);
1092 break;
1093 ////////////////////////////////////////////////// DECA (decrement memory or accumulator) //////////////////////////////////////////////////
1094 case 0xD3: //DECA A
1095 Registers[REGISTER_A]--;
1096 set_flags_nz((BYTE)Registers[REGISTER_A]);
1097 break;
1098 ////////////////////////////////////////////////// INX (increment register X) //////////////////////////////////////////////////
1099 case 0xE2: //INX impl
1100 Index_Registers[REGISTER_X]++;
1101 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
1102 break;
1103 ////////////////////////////////////////////////// DEX (decrement register X) //////////////////////////////////////////////////
1104 case 0xE1: //DEX impl
1105 Index_Registers[REGISTER_X]--;
1106 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
1107 break;
1108 ////////////////////////////////////////////////// INCY (increment register Y) //////////////////////////////////////////////////
1109 case 0xE4: //INCY impl
1110 Index_Registers[REGISTER_Y]++;
1111 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
1112 break;
1113 ////////////////////////////////////////////////// DEY (decrement register Y) //////////////////////////////////////////////////
1114 case 0xE3: //DEY impl
1115 Index_Registers[REGISTER_Y]--;
1116 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
1117 break;
1118 ////////////////////////////////////////////////// ASL (arithmetic shift left memory or accumulator) //////////////////////////////////////////////////
1119 case 0x96: //ASL abs
1120 address = address_abs();
1121 if (address >= 0 && address < MEMORY_SIZE) {
1122 temp_word = Memory[address] << 1;
1123 Memory[address] = (BYTE)temp_word;
1124 set_flags_nz((BYTE)temp_word);
1125 set_flag_c((WORD)temp_word);
1126 }
1127 break;
1128 case 0xA6: //ASL abs,X
1129 address = address_absX();
1130 if (address >= 0 && address < MEMORY_SIZE) {
1131 temp_word = Memory[address] << 1;
1132 Memory[address] = (BYTE)temp_word;
1133 set_flags_nz((BYTE)temp_word);
1134 set_flag_c((WORD)temp_word);
1135 }
1136 break;
1137 case 0xB6: //ASL abs,Y
1138 address = address_absY();
1139 if (address >= 0 && address < MEMORY_SIZE) {
1140 temp_word = Memory[address] << 1;
1141 Memory[address] = (BYTE)temp_word;
1142 set_flags_nz((BYTE)temp_word);
1143 set_flag_c((WORD)temp_word);
1144 }
1145 break;
1146 case 0xC6: //ASL abs,XY
1147 address = address_absXY();
1148 if (address >= 0 && address < MEMORY_SIZE) {
1149 temp_word = Memory[address] << 1;
1150 Memory[address] = (BYTE)temp_word;
1151 set_flags_nz((BYTE)temp_word);
1152 set_flag_c((WORD)temp_word);
1153 }
1154 break;
1155 ////////////////////////////////////////////////// ASLA (arithmetic shift left memory or accumulator) //////////////////////////////////////////////////
1156 case 0xD6: //ASLA A
1157 temp_word = Registers[REGISTER_A] << 1;
1158 Registers[REGISTER_A] = (BYTE)temp_word;
1159 set_flags_nz((BYTE)temp_word);
1160 set_flag_c((WORD)temp_word);
1161 break;
1162 ////////////////////////////////////////////////// SAR (arithmetic shift right memory or accumulator) //////////////////////////////////////////////////
1163 case 0x97: //SAR abs
1164 address = address_abs();
1165 if (address >= 0 && address < MEMORY_SIZE) {
1166 temp_word = Memory[address] >> 1;
1167 Memory[address] = (BYTE)temp_word;
1168 set_flags_nz((BYTE)temp_word);
1169 set_flag_c((WORD)temp_word);
1170 }
1171 break;
1172 case 0xA7: //SAR abs,X
1173 address = address_absX();
1174 if (address >= 0 && address < MEMORY_SIZE) {
1175 temp_word = Memory[address] >> 1;
1176 Memory[address] = (BYTE)temp_word;
1177 set_flags_nz((BYTE)temp_word);
1178 set_flag_c((WORD)temp_word);
1179 }
1180 break;
1181 case 0xB7: //SAR abs,Y
1182 address = address_absY();
1183 if (address >= 0 && address < MEMORY_SIZE) {
1184 temp_word = Memory[address] >> 1;
1185 Memory[address] = (BYTE)temp_word;
1186 set_flags_nz((BYTE)temp_word);
1187 set_flag_c((WORD)temp_word);
1188 }
1189 break;
1190 case 0xC7: //SAR abs,XY
1191 address = address_absXY();
1192 if (address >= 0 && address < MEMORY_SIZE) {
1193 temp_word = Memory[address] >> 1;
1194 Memory[address] = (BYTE)temp_word;
1195 set_flags_nz((BYTE)temp_word);
1196 set_flag_c((WORD)temp_word);
1197 }
1198 break;
1199 ////////////////////////////////////////////////// SARA (arithmetic shift right memory or accumulator) //////////////////////////////////////////////////
1200 case 0xD7: //SARA A
1201 temp_word = Registers[REGISTER_A] >> 1;
1202 Registers[REGISTER_A] = (BYTE)temp_word;
1203 set_flags_nz((BYTE)temp_word);
1204 set_flag_c((WORD)temp_word);
1205 break;
1206 ////////////////////////////////////////////////// RCR (rotate right through carry memory or accumulator) //////////////////////////////////////////////////
1207 case 0x94: //RCR abs
1208 address = address_abs();
1209 if (address >= 0 && address < MEMORY_SIZE) {
1210 saved_flags = Flags;
1211 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
1212 else Flags = Flags & (0xFF - FLAG_C);
1213 Memory[address] = (Memory[address] >> 1) & 0x7F;
1214 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
1215 set_flags_nz((BYTE)Memory[address]);
1216 }
1217 break;
1218 case 0xA4: //RCR abs,X
1219 address = address_absX();
1220 if (address >= 0 && address < MEMORY_SIZE) {
1221 saved_flags = Flags;
1222 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
1223 else Flags = Flags & (0xFF - FLAG_C);
1224 Memory[address] = (Memory[address] >> 1) & 0x7F;
1225 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
1226 set_flags_nz((BYTE)Memory[address]);
1227 }
1228 break;
1229 case 0xB4: //RCR abs,Y
1230 address = address_absY();
1231 if (address >= 0 && address < MEMORY_SIZE) {
1232 saved_flags = Flags;
1233 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
1234 else Flags = Flags & (0xFF - FLAG_C);
1235 Memory[address] = (Memory[address] >> 1) & 0x7F;
1236 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
1237 set_flags_nz((BYTE)Memory[address]);
1238 }
1239 break;
1240 case 0xC4: //RCR abs,XY
1241 address = address_absXY();
1242 if (address >= 0 && address < MEMORY_SIZE) {
1243 saved_flags = Flags;
1244 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
1245 else Flags = Flags & (0xFF - FLAG_C);
1246 Memory[address] = (Memory[address] >> 1) & 0x7F;
1247 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
1248 set_flags_nz((BYTE)Memory[address]);
1249 }
1250 break;
1251 ////////////////////////////////////////////////// RCRA (rotate right through carry memory or accumulator) //////////////////////////////////////////////////
1252 case 0xD4: //RCRA A
1253 if ((Registers[REGISTER_A] & 0x01) == 0x01) Flags = Flags | FLAG_C;
1254 else Flags = Flags & (0xFF - FLAG_C);
1255 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
1256 if ((Flags & FLAG_C) == FLAG_C) Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
1257 set_flags_nz((BYTE)Registers[REGISTER_A]);
1258 break;
1259 ////////////////////////////////////////////////// RLC (rotate left through carry memory or accumulator) //////////////////////////////////////////////////
1260 case 0x95: //RLC abs
1261 address = address_abs();
1262 if (address >= 0 && address < MEMORY_SIZE) {
1263 saved_flags = Flags;
1264 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
1265 else Flags = Flags & (0xFF - FLAG_C);
1266 Memory[address] = (Memory[address] << 1) & 0xFE;
1267 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
1268 set_flags_nz((BYTE)Memory[address]);
1269 }
1270 break;
1271 case 0xA5: //RLC abs,X
1272 address = address_absX();
1273 if (address >= 0 && address < MEMORY_SIZE) {
1274 saved_flags = Flags;
1275 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
1276 else Flags = Flags & (0xFF - FLAG_C);
1277 Memory[address] = (Memory[address] << 1) & 0xFE;
1278 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
1279 set_flags_nz((BYTE)Memory[address]);
1280 }
1281 break;
1282 case 0xB5: //RLC abs,Y
1283 address = address_absY();
1284 if (address >= 0 && address < MEMORY_SIZE) {
1285 saved_flags = Flags;
1286 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
1287 else Flags = Flags & (0xFF - FLAG_C);
1288 Memory[address] = (Memory[address] << 1) & 0xFE;
1289 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
1290 set_flags_nz((BYTE)Memory[address]);
1291 }
1292 break;
1293 case 0xC5: //RLC abs,XY
1294 address = address_absXY();
1295 if (address >= 0 && address < MEMORY_SIZE) {
1296 saved_flags = Flags;
1297 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
1298 else Flags = Flags & (0xFF - FLAG_C);
1299 Memory[address] = (Memory[address] << 1) & 0xFE;
1300 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
1301 set_flags_nz((BYTE)Memory[address]);
1302 }
1303 break;
1304 ////////////////////////////////////////////////// RLCA (rotate left through carry memory or accumulator) //////////////////////////////////////////////////
1305 case 0xD5: //RLCA A
1306 if ((Registers[REGISTER_A] & 0x80) == 0x80) Flags = Flags | FLAG_C; //set carry based on MSB of A
1307 else Flags = Flags & (0xFF - FLAG_C);
1308
1309 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
1310 if ((Flags & FLAG_C) == FLAG_C) Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
1311
1312 set_flags_nz((BYTE)Registers[REGISTER_A]);
1313 break;
1314 ////////////////////////////////////////////////// RAL (rotate left without carry memory or accumulator) //////////////////////////////////////////////////
1315 case 0x99: //RAL abs
1316 address = address_abs();
1317 if (address >= 0 && address < MEMORY_SIZE) {
1318 temp_word = (Memory[address] << 1);
1319 if (temp_word >= 0x100) temp_word = temp_word | 0x01;
1320 Memory[address] = (BYTE)temp_word;
1321 set_flags_nz((BYTE)Memory[address]);
1322 }
1323 break;
1324 case 0xA9: //RAL abs,X
1325 address = address_absX();
1326 if (address >= 0 && address < MEMORY_SIZE) {
1327 temp_word = (Memory[address] << 1);
1328 if (temp_word >= 0x100) temp_word = temp_word | 0x01;
1329 Memory[address] = (BYTE)temp_word;
1330 set_flags_nz((BYTE)Memory[address]);
1331 }
1332 break;
1333 case 0xB9: //RAL abs,Y
1334 address = address_absY();
1335 if (address >= 0 && address < MEMORY_SIZE) {
1336 temp_word = (Memory[address] << 1);
1337 if (temp_word >= 0x100) temp_word = temp_word | 0x01;
1338 Memory[address] = (BYTE)temp_word;
1339 set_flags_nz((BYTE)Memory[address]);
1340 }
1341 break;
1342 case 0xC9: //RAL abs,XY
1343 address = address_absXY();
1344 if (address >= 0 && address < MEMORY_SIZE) {
1345 temp_word = (Memory[address] << 1);
1346 if (temp_word >= 0x100) temp_word = temp_word | 0x01;
1347 Memory[address] = (BYTE)temp_word;
1348 set_flags_nz((BYTE)Memory[address]);
1349 }
1350 break;
1351 ////////////////////////////////////////////////// RALA (rotate left without carry memory or accumulator) //////////////////////////////////////////////////
1352 case 0xD9: //RALA A
1353 temp_word = (Registers[REGISTER_A] << 1);
1354 if (temp_word >= 0x100) temp_word = temp_word | 0x01;
1355 Registers[REGISTER_A] = (BYTE)temp_word;
1356 set_flags_nz((BYTE)Registers[REGISTER_A]);
1357 break;
1358 ////////////////////////////////////////////////// ROR (rotate right without carry memory or accumulator) //////////////////////////////////////////////////
1359 case 0x9A: //ROR abs
1360 address = address_abs();
1361 if (address >= 0 && address < MEMORY_SIZE) {
1362 temp_word = (Memory[address] >> 1);
1363 if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
1364 Memory[address] = (BYTE)temp_word;
1365 set_flags_nz((BYTE)Memory[address]);
1366 }
1367 break;
1368 case 0xAA: //ROR abs,X
1369 address = address_absX();
1370 if (address >= 0 && address < MEMORY_SIZE) {
1371 temp_word = (Memory[address] >> 1);
1372 if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
1373 Memory[address] = (BYTE)temp_word;
1374 set_flags_nz((BYTE)Memory[address]);
1375 }
1376 break;
1377 case 0xBA: //ROR abs,Y
1378 address = address_absY();
1379 if (address >= 0 && address < MEMORY_SIZE) {
1380 temp_word = (Memory[address] >> 1);
1381 if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
1382 Memory[address] = (BYTE)temp_word;
1383 set_flags_nz((BYTE)Memory[address]);
1384 }
1385 break;
1386 case 0xCA: //ROR abs,XY
1387 address = address_absXY();
1388 if (address >= 0 && address < MEMORY_SIZE) {
1389 temp_word = (Memory[address] >> 1);
1390 if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
1391 Memory[address] = (BYTE)temp_word;
1392 set_flags_nz((BYTE)Memory[address]);
1393 }
1394 break;
1395 ////////////////////////////////////////////////// RORA (rotate right without carry memory or accumulator) //////////////////////////////////////////////////
1396 case 0xDA: //RORA A
1397 temp_word = (Registers[REGISTER_A] >> 1);
1398 if ((Registers[REGISTER_A] & 0x01) != 0) temp_word = temp_word | 0x80;
1399 Registers[REGISTER_A] = (BYTE)temp_word;
1400 set_flags_nz((BYTE)Registers[REGISTER_A]);
1401 break;
1402 ////////////////////////////////////////////////// COM (negate memory or accumulator) //////////////////////////////////////////////////
1403 case 0x98: //COM abs
1404 address = address_abs();
1405 if (address >= 0 && address < MEMORY_SIZE) {
1406 temp_word = ~Memory[address]; // ~ is the bitwise complement
1407 set_flag_c((WORD)temp_word);
1408 Memory[address] = (BYTE)temp_word;
1409 set_flags_nz((BYTE)Memory[address]);
1410 }
1411 break;
1412 case 0xA8: //COM abs,X
1413 address = address_absX();
1414 if (address >= 0 && address < MEMORY_SIZE) {
1415 temp_word = ~Memory[address];
1416 set_flag_c((WORD)temp_word);
1417 Memory[address] = (BYTE)temp_word;
1418 set_flags_nz((BYTE)Memory[address]);
1419 }
1420 break;
1421 case 0xB8: //COM abs,Y
1422 address = address_absY();
1423 if (address >= 0 && address < MEMORY_SIZE) {
1424 temp_word = ~Memory[address];
1425 set_flag_c((WORD)temp_word);
1426 Memory[address] = (BYTE)temp_word;
1427 set_flags_nz((BYTE)Memory[address]);
1428 }
1429 break;
1430 case 0xC8: //COM abs,XY
1431 address = address_absXY();
1432 if (address >= 0 && address < MEMORY_SIZE) {
1433 temp_word = ~Memory[address];
1434 set_flag_c((WORD)temp_word);
1435 Memory[address] = (BYTE)temp_word;
1436 set_flags_nz((BYTE)Memory[address]);
1437 }
1438 break;
1439 ////////////////////////////////////////////////// COMA (negate memory or accumulator) //////////////////////////////////////////////////
1440 case 0xD8: //COMA A
1441 temp_word = ~Registers[REGISTER_A];
1442 set_flags_nz((BYTE)temp_word);
1443 set_flag_c((WORD)temp_word);
1444 Registers[REGISTER_A] = (BYTE)temp_word;
1445 break;
1446 ////////////////////////////////////////////////// LX (loads memory into register pair) //////////////////////////////////////////////////
1447 case 0x9B: //LX AB,#
1448 HB = fetch();
1449 LB = fetch();
1450 Registers[REGISTER_A] = LB;
1451 Registers[REGISTER_B] = HB;
1452 temp_word = ((WORD)LB << 8) + (WORD)HB;
1453 set_flags_nz((BYTE)temp_word);
1454 break;
1455 ////////////////////////////////////////////////// JMP (loads memory into ProgramCounter) //////////////////////////////////////////////////
1456 case 0xEA: //JMP abs
1457 address = address_abs();
1458 ProgramCounter = address;
1459 break;
1460 ////////////////////////////////////////////////// JSR (jump to subroutine) //////////////////////////////////////////////////
1461 case 0xE9: //JSR abs
1462 address = address_abs();
1463 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1464 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1465 StackPointer--;
1466 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1467 StackPointer--;
1468 }
1469 ProgramCounter = address;
1470 break;
1471 ////////////////////////////////////////////////// RTN (return from subroutine) //////////////////////////////////////////////////
1472 case 0xDB: //RTN impl
1473 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
1474 StackPointer++;
1475 HB = Memory[StackPointer];
1476 StackPointer++;
1477 LB = Memory[StackPointer];
1478 }
1479 ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
1480 break;
1481 ////////////////////////////////////////////////// BRA (branch always) //////////////////////////////////////////////////
1482 case 0xF0: //BRA rel
1483 LB = fetch();
1484 offset = (WORD)LB;
1485 if ((offset & 0x80) != 0) offset += 0xFF00;
1486 address = ProgramCounter + offset;
1487 ProgramCounter = address;
1488 break;
1489 ////////////////////////////////////////////////// BCC (branch on carry clear) //////////////////////////////////////////////////
1490 case 0xF1: //BCC rel
1491 LB = fetch();
1492 if (FLAG_C == 0x00) {
1493 offset = (WORD)LB;
1494 if ((offset & 0x80) != 0) offset += 0xFF00;
1495 address = ProgramCounter + offset;
1496 ProgramCounter = address;
1497 } else fetch();
1498 break;
1499 ////////////////////////////////////////////////// BCS (branch on carry set) //////////////////////////////////////////////////
1500 case 0xF2: //BCS rel
1501 LB = fetch();
1502 if (FLAG_C == 0x01) {
1503 offset = (WORD)LB;
1504 if ((offset & 0x80) != 0) offset += 0xFF00;
1505 address = ProgramCounter + offset;
1506 ProgramCounter = address;
1507 } else fetch();
1508 break;
1509 ////////////////////////////////////////////////// BNE (branch on result not zero) //////////////////////////////////////////////////
1510 case 0xF3: //BNE rel
1511 LB = fetch();
1512 if (FLAG_Z == 0x00) {
1513 offset = (WORD)LB;
1514 if ((offset & 0x80) != 0) offset += 0xFF00;
1515 address = ProgramCounter + offset;
1516 ProgramCounter = address;
1517 } else fetch();
1518 break;
1519 ////////////////////////////////////////////////// BEQ (branch on result equal to zero) //////////////////////////////////////////////////
1520 case 0xF4: //BEQ rel
1521 LB = fetch();
1522 if (FLAG_Z == 0x01) {
1523 offset = (WORD)LB;
1524 if ((offset & 0x80) != 0) offset += 0xFF00;
1525 address = ProgramCounter + offset;
1526 ProgramCounter = address;
1527 } else fetch();
1528 break;
1529 ////////////////////////////////////////////////// BVC (branch on overflow clear) //////////////////////////////////////////////////
1530 case 0xF5: //BVC rel
1531 LB = fetch();
1532 if (FLAG_V == 0x00) {
1533 offset = (WORD)LB;
1534 if ((offset & 0x80) != 0) offset += 0xFF00;
1535 address = ProgramCounter + offset;
1536 ProgramCounter = address;
1537 } else fetch();
1538 break;
1539 ////////////////////////////////////////////////// BVS (branch on overflow set) //////////////////////////////////////////////////
1540 case 0xF6: //BVS rel
1541 LB = fetch();
1542 if (FLAG_V == 0x01) {
1543 offset = (WORD)LB;
1544 if ((offset & 0x80) != 0) offset += 0xFF00;
1545 address = ProgramCounter + offset;
1546 ProgramCounter = address;
1547 } else fetch();
1548 break;
1549 ////////////////////////////////////////////////// BMI (branch on negative result) //////////////////////////////////////////////////
1550 case 0xF7: //BMI rel
1551 LB = fetch();
1552 if (FLAG_N == 0x01) {
1553 offset = (WORD)LB;
1554 if ((offset & 0x80) != 0) offset += 0xFF00;
1555 address = ProgramCounter + offset;
1556 ProgramCounter = address;
1557 } else fetch();
1558 break;
1559 ////////////////////////////////////////////////// BPL (branch on positive result) //////////////////////////////////////////////////
1560 case 0xF8: //BPL rel
1561 LB = fetch();
1562 if (FLAG_N == 0x00) {
1563 offset = (WORD)LB;
1564 if ((offset & 0x80) != 0) offset += 0xFF00;
1565 address = ProgramCounter + offset;
1566 ProgramCounter = address;
1567 } else fetch();
1568 break;
1569 ////////////////////////////////////////////////// BGE (branch on result <= 0) //////////////////////////////////////////////////
1570 case 0xF9: //BGE rel
1571 LB = fetch();
1572 if ((FLAG_N ^ FLAG_V) == 0x00) {
1573 offset = (WORD)LB;
1574 if ((offset & 0x80) != 0) offset += 0xFF00;
1575 address = ProgramCounter + offset;
1576 ProgramCounter = address;
1577 } else fetch();
1578 break;
1579 ////////////////////////////////////////////////// BLE (branch on result >= 0) //////////////////////////////////////////////////
1580 case 0xFA: //BLE rel
1581 LB = fetch();
1582 if ((FLAG_Z | FLAG_N ^ FLAG_V) == 0x01) {
1583 offset = (WORD)LB;
1584 if ((offset & 0x80) != 0) offset += 0xFF00;
1585 address = ProgramCounter + offset;
1586 ProgramCounter = address;
1587 } else fetch();
1588 break;
1589 ////////////////////////////////////////////////// BGT (branch on result < 0) //////////////////////////////////////////////////
1590 case 0xFB: //BGT rel
1591 LB = fetch();
1592 if ((FLAG_Z | FLAG_N ^ FLAG_V) == 0x00) {
1593 offset = (WORD)LB;
1594 if ((offset & 0x80) != 0) offset += 0xFF00;
1595 address = ProgramCounter + offset;
1596 ProgramCounter = address;
1597 } else fetch();
1598 break;
1599 ////////////////////////////////////////////////// BLT (branch on result > 0) //////////////////////////////////////////////////
1600 case 0xFC: //BLT rel
1601 LB = fetch();
1602 if ((FLAG_N ^ FLAG_V) == 0x01) {
1603 offset = (WORD)LB;
1604 if ((offset & 0x80) != 0) offset += 0xFF00;
1605 address = ProgramCounter + offset;
1606 ProgramCounter = address;
1607 } else fetch();
1608 break;
1609 ////////////////////////////////////////////////// PUSH (pushes register onto stack) //////////////////////////////////////////////////
1610 case 0x9E: //PUSH A
1611 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1612 Memory[StackPointer] = Registers[REGISTER_A];
1613 StackPointer--;
1614 }
1615 break;
1616 case 0xAE: //PUSH FL
1617 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1618 Memory[StackPointer] = Flags;
1619 StackPointer--;
1620 }
1621 break;
1622 case 0xBE: //PUSH B
1623 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1624 Memory[StackPointer] = Registers[REGISTER_B];
1625 StackPointer--;
1626 }
1627 break;
1628 case 0xCE: //PUSH C
1629 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1630 Memory[StackPointer] = Registers[REGISTER_C];
1631 StackPointer--;
1632 }
1633 break;
1634 case 0xDE: //PUSH D
1635 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1636 Memory[StackPointer] = Registers[REGISTER_D];
1637 StackPointer--;
1638 }
1639 break;
1640 case 0xEE: //PUSH E
1641 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1642 Memory[StackPointer] = Registers[REGISTER_E];
1643 StackPointer--;
1644 }
1645 break;
1646 case 0xFE: //PUSH F
1647 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1648 Memory[StackPointer] = Registers[REGISTER_F];
1649 StackPointer--;
1650 }
1651 break;
1652 ////////////////////////////////////////////////// POP (pop top of stack into register) //////////////////////////////////////////////////
1653 case 0x9F: //POP A
1654 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1655 StackPointer++;
1656 Registers[REGISTER_A] = Memory[StackPointer];
1657 }
1658 break;
1659 case 0xAF: //POP FL
1660 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1661 StackPointer++;
1662 Flags = Memory[StackPointer];
1663 }
1664 break;
1665 case 0xBF: //POP B
1666 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1667 StackPointer++;
1668 Registers[REGISTER_B] = Memory[StackPointer];
1669 }
1670 break;
1671 case 0xCF: //POP C
1672 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1673 StackPointer++;
1674 Registers[REGISTER_C] = Memory[StackPointer];
1675 }
1676 break;
1677 case 0xDF: //POP D
1678 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1679 StackPointer++;
1680 Registers[REGISTER_D] = Memory[StackPointer];
1681 }
1682 break;
1683 case 0xEF: //POP E
1684 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE -1 )) {
1685 StackPointer++;
1686 Registers[REGISTER_E] = Memory[StackPointer];
1687 }
1688 break;
1689 case 0xFF: //POP F
1690 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1691 StackPointer++;
1692 Registers[REGISTER_F] = Memory[StackPointer];
1693 }
1694 break;
1695 ////////////////////////////////////////////////// SWI (software interrupt) //////////////////////////////////////////////////
1696 case 0x16: //SWI impl
1697
1698 break;
1699 ////////////////////////////////////////////////// RTN (return from software interrupt) //////////////////////////////////////////////////
1700 case 0x17: //RTN impl
1701
1702 break;
1703 ////////////////////////////////////////////////// SEC (set carry flag) //////////////////////////////////////////////////
1704 case 0x19: //SEC impl
1705 Flags = Flags | FLAG_C;
1706 break;
1707 ////////////////////////////////////////////////// CLC (clear carry flag) //////////////////////////////////////////////////
1708 case 0x18: //CLC impl
1709 Flags = Flags & (0xFF - FLAG_C);
1710 break;
1711 ////////////////////////////////////////////////// STI (set interrupt flag) //////////////////////////////////////////////////
1712 case 0x1B: //STI impl
1713 Flags = Flags | FLAG_I;
1714 break;
1715 ////////////////////////////////////////////////// CLI (clear interrupt flag) //////////////////////////////////////////////////
1716 case 0x1A: //CLI impl
1717 Flags = Flags & (0xFF - FLAG_I);
1718 break;
1719 ////////////////////////////////////////////////// STV (set overflow flag) //////////////////////////////////////////////////
1720 case 0x1C: //STV impl
1721 Flags = Flags | FLAG_V;
1722 break;
1723 ////////////////////////////////////////////////// CLV (clear overflow flag) //////////////////////////////////////////////////
1724 case 0x1D: //CLV impl
1725 Flags = Flags & (0xFF - FLAG_V);
1726 break;
1727 }
1728}
1729
1730//LD function
1731void Group_2_Move(BYTE opcode) {
1732 BYTE destination = opcode >> 4; //top four bits point at one register....shift right to keep only top four
1733 BYTE source = opcode & 0x0F;//takes bottom four bits
1734 int destReg = 0, sourceReg = 0;
1735
1736 switch (destination) { //COMBO OF DEST AND SOURCE GIVE REGISTERS ADDRESSES TO FOR MEMORY ADRESSER AT BOTTOM
1737 case 0x02://top four bits from op code
1738 destReg = REGISTER_A;
1739 break;
1740 case 0x03:
1741 destReg = REGISTER_B;
1742 break;
1743 case 0x04:
1744 destReg = REGISTER_C;
1745 break;
1746 case 0x05:
1747 destReg = REGISTER_D;
1748 break;
1749 case 0x06:
1750 destReg = REGISTER_E;
1751 break;
1752 case 0x07:
1753 destReg = REGISTER_F;
1754 break;
1755 }
1756
1757 switch (source) {
1758 case 0x0A:
1759 sourceReg = REGISTER_A;
1760 break;
1761 case 0x0B:
1762 sourceReg = REGISTER_B;
1763 break;
1764 case 0x0C:
1765 sourceReg = REGISTER_C;
1766 break;
1767 case 0x0D:
1768 sourceReg = REGISTER_D;
1769 break;
1770 case 0x0E:
1771 sourceReg = REGISTER_E;
1772 break;
1773 case 0x0F:
1774 sourceReg = REGISTER_F;
1775 break;
1776 }
1777
1778 Registers[sourceReg] = Registers[destReg]; //code to assign sourcereg to dest reg
1779}
1780
1781void execute(BYTE opcode) {
1782 if (((opcode >= 0x2A) && (opcode <= 0x2F))
1783 || ((opcode >= 0x3A) && (opcode <= 0x3F))
1784 || ((opcode >= 0x4A) && (opcode <= 0x4F))
1785 || ((opcode >= 0x5A) && (opcode <= 0x5F))
1786 || ((opcode >= 0x6A) && (opcode <= 0x6F))
1787 || ((opcode >= 0x7A) && (opcode <= 0x7F)))
1788 {
1789 Group_2_Move(opcode);
1790 }
1791 else Group_1(opcode);
1792}
1793
1794void emulate() {
1795 BYTE opcode;
1796 int sanity = 0;
1797
1798 ProgramCounter = 0;
1799 halt = false;
1800 memory_in_range = true;
1801
1802 printf(" A B C D E F X Y SP\n");
1803
1804 while ((!halt) && (memory_in_range)) {
1805 sanity++;
1806 if (sanity > 500) halt = true;
1807 printf("%04X ", ProgramCounter); // Print current address
1808 opcode = fetch();
1809 execute(opcode);
1810
1811 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
1812 printf("%02X ", Registers[REGISTER_A]);
1813 printf("%02X ", Registers[REGISTER_B]);
1814 printf("%02X ", Registers[REGISTER_C]);
1815 printf("%02X ", Registers[REGISTER_D]);
1816 printf("%02X ", Registers[REGISTER_E]);
1817 printf("%02X ", Registers[REGISTER_F]);
1818 printf("%02X ", Index_Registers[REGISTER_X]);
1819 printf("%02X ", Index_Registers[REGISTER_Y]);
1820 printf("%04X ", StackPointer); // Print Stack Pointer
1821
1822 if ((Flags & FLAG_I) == FLAG_I) printf("I = 1, ");
1823 else printf("I = 0, ");
1824
1825 if ((Flags & FLAG_V) == FLAG_V) printf("V = 1, ");
1826 else printf("V = 0, ");
1827
1828 if ((Flags & FLAG_N) == FLAG_N) printf("N = 1, ");
1829 else printf("N = 0, ");
1830
1831 if ((Flags & FLAG_Z) == FLAG_Z) printf("Z = 1, ");
1832 else printf("Z = 0, ");
1833
1834 if ((Flags & FLAG_C) == FLAG_C) printf("C = 1 ");
1835 else printf("C = 0 ");
1836
1837 printf("\n");
1838 }
1839 printf("\n");
1840}
1841
1842
1843////////////////////////////////////////////////////////////////////////////////
1844// Emulator (End) //
1845////////////////////////////////////////////////////////////////////////////////
1846
1847void initialise_filenames() {
1848 int i;
1849
1850 for (i=0; i<MAX_FILENAME_SIZE; i++) {
1851 hex_file [i] = '\0';
1852 trc_file [i] = '\0';
1853 }
1854}
1855
1856int find_dot_position(char *filename) {
1857 int dot_position;
1858 int i;
1859 char chr;
1860
1861 dot_position = 0;
1862 i = 0;
1863 chr = filename[i];
1864
1865 while (chr != '\0') {
1866 if (chr == '.') dot_position = i;
1867
1868 i++;
1869 chr = filename[i];
1870 }
1871
1872 return dot_position;
1873}
1874
1875int find_end_position(char *filename) {
1876 int end_position;
1877 int i;
1878 char chr;
1879
1880 end_position = 0;
1881 i = 0;
1882 chr = filename[i];
1883
1884 while (chr != '\0') {
1885 end_position = i;
1886 i++;
1887 chr = filename[i];
1888 }
1889
1890 return end_position;
1891}
1892
1893bool file_exists(char *filename) {
1894 bool exists;
1895 FILE *ifp;
1896
1897 exists = false;
1898
1899 if ((ifp = fopen(filename, "r")) != NULL) {
1900 exists = true;
1901
1902 fclose(ifp);
1903 }
1904
1905 return exists;
1906}
1907
1908void create_file(char *filename) {
1909 FILE *ofp;
1910
1911 if ((ofp = fopen(filename, "w")) != NULL) fclose(ofp);
1912}
1913
1914bool getline(FILE *fp, char *buffer) {
1915 bool rc;
1916 bool collect;
1917 char c;
1918 int i;
1919
1920 rc = false;
1921 collect = true;
1922
1923 i = 0;
1924 while (collect) {
1925 c = getc(fp);
1926
1927 switch (c) {
1928 case EOF:
1929 if (i > 0) rc = true;
1930
1931 collect = false;
1932 break;
1933 case '\n':
1934 if (i > 0) {
1935 rc = true;
1936 collect = false;
1937 buffer[i] = '\0';
1938 }
1939 break;
1940 default:
1941 buffer[i] = c;
1942 i++;
1943 }
1944 }
1945
1946 return rc;
1947}
1948
1949void load_and_run(int args,_TCHAR** argv) {
1950 char chr;
1951 int ln;
1952 int dot_position;
1953 int end_position;
1954 long i;
1955 FILE *ifp;
1956 long address;
1957 long load_at;
1958 int code;
1959
1960 // Prompt for the .hex file
1961
1962 printf("\n");
1963 printf("Enter the hex filename (.hex): ");
1964
1965 if(args == 2) {
1966 ln = 0;
1967 chr = argv[1][ln];
1968 while (chr != '\0') {
1969 if (ln < MAX_FILENAME_SIZE) {
1970 hex_file [ln] = chr;
1971 trc_file [ln] = chr;
1972 ln++;
1973 }
1974 chr = argv[1][ln];
1975 }
1976 } else {
1977 ln = 0;
1978 chr = '\0';
1979 while (chr != '\n') {
1980 chr = getchar();
1981
1982 switch(chr) {
1983 case '\n':
1984 break;
1985 default:
1986 if (ln < MAX_FILENAME_SIZE) {
1987 hex_file [ln] = chr;
1988 trc_file [ln] = chr;
1989 ln++;
1990 }
1991 break;
1992 }
1993 }
1994 }
1995 // Tidy up the file names
1996
1997 dot_position = find_dot_position(hex_file);
1998 if (dot_position == 0) {
1999 end_position = find_end_position(hex_file);
2000
2001 hex_file[end_position + 1] = '.';
2002 hex_file[end_position + 2] = 'h';
2003 hex_file[end_position + 3] = 'e';
2004 hex_file[end_position + 4] = 'x';
2005 hex_file[end_position + 5] = '\0';
2006 } else {
2007 hex_file[dot_position + 0] = '.';
2008 hex_file[dot_position + 1] = 'h';
2009 hex_file[dot_position + 2] = 'e';
2010 hex_file[dot_position + 3] = 'x';
2011 hex_file[dot_position + 4] = '\0';
2012 }
2013
2014 dot_position = find_dot_position(trc_file);
2015 if (dot_position == 0) {
2016 end_position = find_end_position(trc_file);
2017
2018 trc_file[end_position + 1] = '.';
2019 trc_file[end_position + 2] = 't';
2020 trc_file[end_position + 3] = 'r';
2021 trc_file[end_position + 4] = 'c';
2022 trc_file[end_position + 5] = '\0';
2023 } else {
2024 trc_file[dot_position + 0] = '.';
2025 trc_file[dot_position + 1] = 't';
2026 trc_file[dot_position + 2] = 'r';
2027 trc_file[dot_position + 3] = 'c';
2028 trc_file[dot_position + 4] = '\0';
2029 }
2030
2031 if (file_exists(hex_file)) {
2032 // Clear Registers and Memory
2033 Registers[REGISTER_A] = 0;
2034 Registers[REGISTER_B] = 0;
2035 Registers[REGISTER_C] = 0;
2036 Registers[REGISTER_D] = 0;
2037 Registers[REGISTER_E] = 0;
2038 Registers[REGISTER_F] = 0;
2039 Index_Registers[REGISTER_X] = 0;
2040 Index_Registers[REGISTER_Y] = 0;
2041 Flags = 0;
2042 ProgramCounter = 0;
2043 StackPointer = 0;
2044
2045 for (i = 0; i < MEMORY_SIZE; i++) Memory[i] = 0x00;
2046
2047 // Load hex file
2048 if ((ifp = fopen(hex_file, "r")) != NULL) {
2049 printf("Loading file...\n\n");
2050
2051 load_at = 0;
2052
2053 while (getline(ifp, InputBuffer)) {
2054 if (sscanf(InputBuffer, "L=%x", &address) == 1) load_at = address;
2055 else if (sscanf(InputBuffer, "%x", &code) == 1) {
2056 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) Memory[load_at] = (BYTE)code;
2057
2058 load_at++;
2059 } else printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
2060 }
2061
2062 fclose(ifp);
2063 }
2064
2065 emulate();
2066 } else {
2067 printf("\n");
2068 printf("ERROR> Input file %s does not exist!\n", hex_file);
2069 printf("\n");
2070 }
2071}
2072
2073void building(int args,_TCHAR** argv){
2074 char buffer[1024];
2075 load_and_run(args,argv);
2076 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",
2077 Memory[TEST_ADDRESS_1],
2078 Memory[TEST_ADDRESS_2],
2079 Memory[TEST_ADDRESS_3],
2080 Memory[TEST_ADDRESS_4],
2081 Memory[TEST_ADDRESS_5],
2082 Memory[TEST_ADDRESS_6],
2083 Memory[TEST_ADDRESS_7],
2084 Memory[TEST_ADDRESS_8],
2085 Memory[TEST_ADDRESS_9],
2086 Memory[TEST_ADDRESS_10],
2087 Memory[TEST_ADDRESS_11],
2088 Memory[TEST_ADDRESS_12]
2089 );
2090 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2091}
2092
2093void test_and_mark() {
2094 char buffer[1024];
2095 bool testing_complete;
2096 int len = sizeof(SOCKADDR);
2097 char chr;
2098 int i;
2099 int j;
2100 bool end_of_program;
2101 long address;
2102 long load_at;
2103 int code;
2104 int mark;
2105 int passed;
2106
2107 printf("Automatic Testing and Marking\n");
2108 printf("\n");
2109
2110 testing_complete = false;
2111
2112 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
2113 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2114
2115 while (!testing_complete) {
2116 memset(buffer, '\0', sizeof(buffer));
2117
2118 if (recvfrom(sock, buffer, sizeof(buffer)-1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
2119 printf("Incoming Data: %s \n", buffer);
2120
2121 //if (strcmp(buffer, "Testing complete") == 1)
2122 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
2123 testing_complete = true;
2124 printf("Current mark = %d\n", mark);
2125 }else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
2126 //testing_complete = true;
2127 printf("Passed = %d\n", passed);
2128 } else if (strcmp(buffer, "Error") == 0) {
2129 printf("ERROR> Testing abnormally terminated\n");
2130 testing_complete = true;
2131 } else {
2132 // Clear Registers and Memory
2133 Registers[REGISTER_A] = 0;
2134 Registers[REGISTER_B] = 0;
2135 Registers[REGISTER_C] = 0;
2136 Registers[REGISTER_D] = 0;
2137 Registers[REGISTER_E] = 0;
2138 Registers[REGISTER_F] = 0;
2139 Index_Registers[REGISTER_X] = 0;
2140 Index_Registers[REGISTER_Y] = 0;
2141 Flags = 0;
2142 ProgramCounter = 0;
2143 StackPointer = 0;
2144 for (i = 0; i < MEMORY_SIZE; i++) Memory[i] = 0;
2145
2146 // Load hex file
2147 i = 0;
2148 j = 0;
2149 load_at = 0;
2150 end_of_program = false;
2151 FILE *ofp;
2152 fopen_s(&ofp ,"branch.txt", "a");
2153
2154 while (!end_of_program) {
2155 chr = buffer[i];
2156 switch (chr) {
2157 case '\0':
2158 end_of_program = true;
2159 case ',':
2160 if (sscanf(InputBuffer, "L=%x", &address) == 1) load_at = address;
2161 else if (sscanf(InputBuffer, "%x", &code) == 1) {
2162 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
2163 Memory[load_at] = (BYTE)code;
2164 fprintf(ofp, "%02X\n", (BYTE)code);
2165 }
2166 load_at++;
2167 } else printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
2168
2169 j = 0;
2170 break;
2171 default:
2172 InputBuffer[j] = chr;
2173 j++;
2174 break;
2175 }
2176 i++;
2177 }
2178 fclose(ofp);
2179 // Emulate
2180
2181 if (load_at > 1) {
2182 emulate();
2183 // Send and store results
2184 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
2185 Memory[TEST_ADDRESS_1],
2186 Memory[TEST_ADDRESS_2],
2187 Memory[TEST_ADDRESS_3],
2188 Memory[TEST_ADDRESS_4],
2189 Memory[TEST_ADDRESS_5],
2190 Memory[TEST_ADDRESS_6],
2191 Memory[TEST_ADDRESS_7],
2192 Memory[TEST_ADDRESS_8],
2193 Memory[TEST_ADDRESS_9],
2194 Memory[TEST_ADDRESS_10],
2195 Memory[TEST_ADDRESS_11],
2196 Memory[TEST_ADDRESS_12]
2197 );
2198 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2199 }
2200 }
2201 }
2202 }
2203}
2204
2205int _tmain(int argc, _TCHAR* argv[]) {
2206 char chr;
2207 char dummy;
2208
2209 printf("Microprocessor Emulator\n");
2210 printf("UWE Computer and Network Systems Assignment 1\n");
2211 printf("\n");
2212
2213 initialise_filenames();
2214
2215 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
2216
2217 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
2218 if (!sock) {
2219 //Creation failed!
2220 }
2221
2222 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
2223 server_addr.sin_family = AF_INET;
2224 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
2225 server_addr.sin_port = htons(PORT_SERVER);
2226
2227 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
2228 client_addr.sin_family = AF_INET;
2229 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
2230 client_addr.sin_port = htons(PORT_CLIENT);
2231
2232 chr = '\0';
2233 while ((chr != 'e') && (chr != 'E')) {
2234 printf("\nPlease select option\n");
2235 printf("L - Load and run a hex file\n");
2236 printf("T - Have the server test and mark your emulator\n");
2237 printf("E - Exit\n");
2238 if(argc == 2){ building(argc,argv); exit(0);}
2239 printf("Enter option: ");
2240 chr = getchar();
2241 if (chr != 0x0A) dummy = getchar(); // read in the <CR>
2242
2243 printf("\n");
2244
2245 switch (chr) {
2246 case 'L': case 'l':
2247 load_and_run(argc,argv);
2248 break;
2249 case 'T': case 't':
2250 test_and_mark();
2251 break;
2252 }
2253 }
2254
2255 closesocket(sock);
2256 WSACleanup();
2257
2258 return 0;
2259}