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