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