Advertisement
Guest User

Untitled

a guest
Feb 24th, 2020
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 95.67 KB | None | 0 0
  1. #include "stdafx.h"
  2.  
  3. #include <winsock2.h>
  4.  
  5. /*
  6. * Author: George Gao (18043234)
  7. * Created : 24 / 01 / 20
  8. * Revised : 21 / 02 / 20
  9. * Description : Chimera - 2018 - J Emulator
  10. * User advice : None
  11. * Notes : Line 52, 62 added extra register
  12. * Test Passed:176 Marks:47,
  13. */
  14.  
  15. /*
  16. Week 01: LD, ST, MOVE, MVI, LODS, LDX, STOX
  17.  
  18. Week 02: ADC, CMP, TSA, TAS, CLC, SEC, CLI, STI, SEV, CLV
  19.  
  20. Week 03: PSH, POP, JMP, JPR, RTN, BRA, BCC, BCS, BNE, BEQ, BVC,
  21. BVS, BMI, BPL, BGE, BLE, BLS, BHI, CCC, CCS, CNE, CEQ,
  22. CVC, CVS, CMI, CPL, CHI, CLE
  23.  
  24. Week 04: INC, INCA, INX, DEX, AND, BT
  25.  
  26. Week 05: SBC, IOR, XOR, NOT, NOTA, DEC, DECA, SAL, SALA,
  27. ADI, SBI, CPI, ANI, XRI,, SWI, RTI, NOP, WAI
  28.  
  29. Week 06: RCL, RCLA, RCR, RCRA, ROL, ROLA, ROR, RORA
  30.  
  31. */
  32.  
  33. # pragma comment(lib, "wsock32.lib")
  34.  
  35. # define STUDENT_NUMBER "18043234"
  36.  
  37. # define IP_ADDRESS_SERVER "127.0.0.1"
  38.  
  39. # define PORT_SERVER 0x1984 //We define a port that we are going to use.
  40. # define PORT_CLIENT 0x1985 //We define a port that we are going to use.
  41.  
  42. # define WORD unsigned short
  43. # define DWORD unsigned long
  44. # define BYTE unsigned char
  45.  
  46. # define MAX_FILENAME_SIZE 500
  47. # define MAX_BUFFER_SIZE 500
  48.  
  49. SOCKADDR_IN server_addr;
  50. SOCKADDR_IN client_addr;
  51.  
  52. SOCKET sock; //This is our socket, it is the handle to the IO address to read/write packets
  53.  
  54. WSADATA data;
  55.  
  56. char InputBuffer[MAX_BUFFER_SIZE];
  57.  
  58. char hex_file[MAX_BUFFER_SIZE];
  59. char trc_file[MAX_BUFFER_SIZE];
  60.  
  61. //////////////////////////
  62. // Registers //
  63. //////////////////////////
  64.  
  65. # define FLAG_I 0x80
  66. # define FLAG_N 0x20
  67. # define FLAG_V 0x10
  68. # define FLAG_Z 0x08
  69. # define FLAG_C 0x01
  70.  
  71. # define REGISTER_M 7 //ADDED EXTRA REGISTER
  72. # define REGISTER_A 6
  73. # define REGISTER_H 5
  74. # define REGISTER_L 4
  75. # define REGISTER_E 3
  76. # define REGISTER_D 2
  77. # define REGISTER_C 1
  78. # define REGISTER_B 0
  79.  
  80. WORD IndexRegister;
  81.  
  82. BYTE Registers[8]; //CHANGED FROM 7 T0 8
  83. BYTE Flags;
  84. WORD ProgramCounter;
  85. WORD StackPointer;
  86.  
  87. ////////////
  88. // Memory //
  89. ////////////
  90.  
  91. # define MEMORY_SIZE 65536
  92.  
  93. BYTE Memory[MEMORY_SIZE];
  94.  
  95. # define TEST_ADDRESS_1 0x01FA
  96. # define TEST_ADDRESS_2 0x01FB
  97. # define TEST_ADDRESS_3 0x01FC
  98. # define TEST_ADDRESS_4 0x01FD
  99. # define TEST_ADDRESS_5 0x01FE
  100. # define TEST_ADDRESS_6 0x01FF
  101. # define TEST_ADDRESS_7 0x0200
  102. # define TEST_ADDRESS_8 0x0201
  103. # define TEST_ADDRESS_9 0x0202
  104. # define TEST_ADDRESS_10 0x0203
  105. # define TEST_ADDRESS_11 0x0204
  106. # define TEST_ADDRESS_12 0x0205
  107.  
  108. ///////////////////////
  109. // Control variables //
  110. ///////////////////////
  111.  
  112. bool memory_in_range = true;
  113. bool halt = false;
  114.  
  115. ///////////////////////
  116. // Disassembly table //
  117. ///////////////////////
  118.  
  119. char opcode_mneumonics[][14] = {
  120. "BRA rel ",
  121. "BCC rel ",
  122. "BCS rel ",
  123. "BNE rel ",
  124. "BEQ rel ",
  125. "BVC rel ",
  126. "BVS rel ",
  127. "BMI rel ",
  128. "BPL rel ",
  129. "BGE rel ",
  130. "BLE rel ",
  131. "BLS rel ",
  132. "BHI rel ",
  133. "ILLEGAL ",
  134. "RTN impl ",
  135. "ILLEGAL ",
  136.  
  137. "ST abs ",
  138. "PSH ,A ",
  139. "POP A, ",
  140. "ILLEGAL ",
  141. "ILLEGAL ",
  142. "CLC impl ",
  143. "SEC impl ",
  144. "CLI impl ",
  145. "STI impl ",
  146. "SEV impl ",
  147. "CLV impl ",
  148. "DEX impl ",
  149. "INX impl ",
  150. "NOP impl ",
  151. "WAI impl ",
  152. "ILLEGAL ",
  153.  
  154. "ST abs,X ",
  155. "PSH ,s ",
  156. "POP s, ",
  157. "ILLEGAL ",
  158. "ILLEGAL ",
  159. "ADI # ",
  160. "SBI # ",
  161. "CPI # ",
  162. "ANI # ",
  163. "XRI # ",
  164. "MVI #,B ",
  165. "MVI #,C ",
  166. "MVI #,D ",
  167. "MVI #,E ",
  168. "MVI #,L ",
  169. "MVI #,H ",
  170.  
  171. "ILLEGAL ",
  172. "PSH ,B ",
  173. "POP B, ",
  174. "JPR abs ",
  175. "CCC abs ",
  176. "CCS abs ",
  177. "CNE abs ",
  178. "CEQ abs ",
  179. "CVC abs ",
  180. "CVS abs ",
  181. "CMI abs ",
  182. "CPL abs ",
  183. "CHI abs ",
  184. "CLE abs ",
  185. "ILLEGAL ",
  186. "ILLEGAL ",
  187.  
  188. "ILLEGAL ",
  189. "PSH ,C ",
  190. "POP C, ",
  191. "TST abs ",
  192. "INC abs ",
  193. "DEC abs ",
  194. "RCR abs ",
  195. "RCL abs ",
  196. "SAL abs ",
  197. "ASR abs ",
  198. "NOT abs ",
  199. "ROL abs ",
  200. "ROR abs ",
  201. "ILLEGAL ",
  202. "LDX # ",
  203. "LODS # ",
  204.  
  205. "STOX abs ",
  206. "PSH ,D ",
  207. "POP D, ",
  208. "TST abs,X ",
  209. "INC abs,X ",
  210. "DEC abs,X ",
  211. "RCR abs,X ",
  212. "RCL abs,X ",
  213. "SAL abs,X ",
  214. "ASR abs,X ",
  215. "NOT abs,X ",
  216. "ROL abs,X ",
  217. "ROR abs,X ",
  218. "ILLEGAL ",
  219. "LDX abs ",
  220. "LODS abs ",
  221.  
  222. "STOX abs,X ",
  223. "PSH ,E ",
  224. "POP E, ",
  225. "TSTA A,A ",
  226. "INCA A,A ",
  227. "DECA A,A ",
  228. "RCRA A,A ",
  229. "RCLA A,A ",
  230. "SALA A,A ",
  231. "ASRA A,A ",
  232. "NOTA A,A ",
  233. "ROLA A,A ",
  234. "RORA A,A ",
  235. "ILLEGAL ",
  236. "LDX abs,X ",
  237. "LODS abs,X ",
  238.  
  239. "ILLEGAL ",
  240. "PSH ,L ",
  241. "POP L, ",
  242. "ILLEGAL ",
  243. "TAS impl ",
  244. "TSA impl ",
  245. "ILLEGAL ",
  246. "ILLEGAL ",
  247. "MOVE A,A ",
  248. "MOVE B,A ",
  249. "MOVE C,A ",
  250. "MOVE D,A ",
  251. "MOVE E,A ",
  252. "MOVE L,A ",
  253. "MOVE H,A ",
  254. "MOVE M,A ",
  255.  
  256. "ILLEGAL ",
  257. "PSH ,H ",
  258. "POP H, ",
  259. "ILLEGAL ",
  260. "ILLEGAL ",
  261. "SWI impl ",
  262. "RTI impl ",
  263. "ILLEGAL ",
  264. "MOVE A,B ",
  265. "MOVE B,B ",
  266. "MOVE C,B ",
  267. "MOVE D,B ",
  268. "MOVE E,B ",
  269. "MOVE L,B ",
  270. "MOVE H,B ",
  271. "MOVE M,B ",
  272.  
  273. "ADC A,B ",
  274. "SBC A,B ",
  275. "CMP A,B ",
  276. "IOR A,B ",
  277. "AND A,B ",
  278. "XOR A,B ",
  279. "BT A,B ",
  280. "ILLEGAL ",
  281. "MOVE A,C ",
  282. "MOVE B,C ",
  283. "MOVE C,C ",
  284. "MOVE D,C ",
  285. "MOVE E,C ",
  286. "MOVE L,C ",
  287. "MOVE H,C ",
  288. "MOVE M,C ",
  289.  
  290. "ADC A,C ",
  291. "SBC A,C ",
  292. "CMP A,C ",
  293. "IOR A,C ",
  294. "AND A,C ",
  295. "XOR A,C ",
  296. "BT A,C ",
  297. "ILLEGAL ",
  298. "MOVE A,D ",
  299. "MOVE B,D ",
  300. "MOVE C,D ",
  301. "MOVE D,D ",
  302. "MOVE E,D ",
  303. "MOVE L,D ",
  304. "MOVE H,D ",
  305. "MOVE M,D ",
  306.  
  307. "ADC A,D ",
  308. "SBC A,D ",
  309. "CMP A,D ",
  310. "IOR A,D ",
  311. "AND A,D ",
  312. "XOR A,D ",
  313. "BT A,D ",
  314. "LD # ",
  315. "MOVE A,E ",
  316. "MOVE B,E ",
  317. "MOVE C,E ",
  318. "MOVE D,E ",
  319. "MOVE E,E ",
  320. "MOVE L,E ",
  321. "MOVE H,E ",
  322. "MOVE M,E ",
  323.  
  324. "ADC A,E ",
  325. "SBC A,E ",
  326. "CMP A,E ",
  327. "IOR A,E ",
  328. "AND A,E ",
  329. "XOR A,E ",
  330. "BT A,E ",
  331. "LD abs ",
  332. "MOVE A,L ",
  333. "MOVE B,L ",
  334. "MOVE C,L ",
  335. "MOVE D,L ",
  336. "MOVE E,L ",
  337. "MOVE L,L ",
  338. "MOVE H,L ",
  339. "MOVE M,L ",
  340.  
  341. "ADC A,L ",
  342. "SBC A,L ",
  343. "CMP A,L ",
  344. "IOR A,L ",
  345. "AND A,L ",
  346. "XOR A,L ",
  347. "BT A,L ",
  348. "LD abs,X ",
  349. "MOVE A,H ",
  350. "MOVE B,H ",
  351. "MOVE C,H ",
  352. "MOVE D,H ",
  353. "MOVE E,H ",
  354. "MOVE L,H ",
  355. "MOVE H,H ",
  356. "MOVE M,H ",
  357.  
  358. "ADC A,H ",
  359. "SBC A,H ",
  360. "CMP A,H ",
  361. "IOR A,H ",
  362. "AND A,H ",
  363. "XOR A,H ",
  364. "BT A,H ",
  365. "ILLEGAL ",
  366. "MOVE A,M ",
  367. "MOVE B,M ",
  368. "MOVE C,M ",
  369. "MOVE D,M ",
  370. "MOVE E,M ",
  371. "MOVE L,M ",
  372. "MOVE H,M ",
  373. "MOVE -,- ",
  374.  
  375. "ADC A,M ",
  376. "SBC A,M ",
  377. "CMP A,M ",
  378. "IOR A,M ",
  379. "AND A,M ",
  380. "XOR A,M ",
  381. "BT A,M ",
  382. "ILLEGAL ",
  383. "ILLEGAL ",
  384. "ILLEGAL ",
  385. "JMP abs ",
  386. "ILLEGAL ",
  387. "ILLEGAL ",
  388. "ILLEGAL ",
  389. "ILLEGAL ",
  390. "ILLEGAL ",
  391. };
  392.  
  393. ////////////////////////////////////////////////////////////////////////////////
  394. // Simulator/Emulator (Start) //
  395. ////////////////////////////////////////////////////////////////////////////////
  396. BYTE fetch() {
  397. BYTE byte = 0;
  398.  
  399. if ((ProgramCounter >= 0) && (ProgramCounter <= MEMORY_SIZE)) {
  400. memory_in_range = true;
  401. byte = Memory[ProgramCounter];
  402. ProgramCounter++;
  403. }
  404. else {
  405. memory_in_range = false;
  406. }
  407. return byte;
  408. }
  409.  
  410. /*---------------------------------------------------------------------------*/
  411. void set_flag_n(BYTE inReg) {
  412. BYTE reg;
  413. reg = inReg;
  414.  
  415. if ((reg & 0x80) != 0) //msbit set
  416. {
  417. Flags = Flags | FLAG_N;
  418. }
  419. else {
  420. Flags = Flags & (0xFF - FLAG_N);
  421. }
  422. }
  423.  
  424. void set_flag_v(BYTE in1, BYTE in2, BYTE out1) {
  425. BYTE reg1in;
  426. BYTE reg2in;
  427. BYTE regOut;
  428.  
  429. reg1in = in1;
  430. reg2in = in2;
  431. regOut = out1;
  432.  
  433. if ((((reg1in & 0x80) == 0x80) && ((reg2in & 0x80) == 0x80) && ((regOut & 0x80) != 0x80)) ||
  434. (((reg1in & 0x80) != 0x80) && ((reg2in & 0x80) != 0x80) && ((regOut & 0x80) == 0x80))) {
  435. Flags = Flags | FLAG_V;
  436. }
  437. else {
  438. Flags = Flags & (0xFF - FLAG_V);
  439. }
  440. }
  441.  
  442. void set_flag_z(BYTE inReg) {
  443. BYTE reg;
  444. reg = inReg;
  445.  
  446. if (reg == 0) //zero set
  447. {
  448. Flags = Flags | FLAG_Z;
  449. }
  450. else {
  451. Flags = Flags & (0xFF - FLAG_Z);
  452. }
  453. }
  454.  
  455. /*-----------------------------CUSTOM FUNCTIONS------------------------------*/
  456.  
  457.  
  458. /*---------------------------------------------------------------------------*/
  459. void Group_1(BYTE opcode) {
  460. BYTE LB = 0;
  461. BYTE HB = 0;
  462. WORD address = 0;
  463. WORD data = 0;
  464.  
  465. WORD temp_word;
  466. WORD param1;
  467. WORD param2;
  468. WORD offset;
  469. WORD saved_flags;
  470.  
  471. BYTE CF;
  472. if ((Flags & FLAG_C) == FLAG_C) {
  473. CF = 1;
  474. }
  475. else {
  476. CF = 0;
  477. }
  478.  
  479. BYTE NF;
  480. if ((Flags & FLAG_N) == FLAG_N) {
  481. NF = 1;
  482. }
  483. else {
  484. NF = 0;
  485. }
  486.  
  487. BYTE ZF;
  488. if ((Flags & FLAG_Z) == FLAG_Z) {
  489. ZF = 1;
  490. }
  491. else {
  492. ZF = 0;
  493. }
  494.  
  495. BYTE VF;
  496. if ((Flags & FLAG_V) == FLAG_V) {
  497. VF = 1;
  498. }
  499. else {
  500. VF = 0;
  501. }
  502.  
  503. switch (opcode) {
  504. /*----------------------------LOADING AND STORING----------------------------*/
  505. /*
  506. * Opcode: LD
  507. * Description: Loads Memory into Accumulator
  508. * Flags: I - N V Z - - C
  509. * Flags: - - T - T - - 0
  510. * Notes: None
  511. */
  512. case 0xB7: //LD IMMEDIATE ADDRESSING (#)
  513. data = fetch();
  514. Registers[REGISTER_A] = data;
  515.  
  516. set_flag_n(Registers[REGISTER_A]);
  517. set_flag_z(Registers[REGISTER_A]);
  518. Flags = Flags & (0xFF - FLAG_C);
  519. break;
  520.  
  521. case 0xC7: //LD ABSOLUTE ADDRESSING (abs)
  522. HB = fetch();
  523. LB = fetch();
  524. address += (WORD)((WORD)HB << 8) + LB;
  525.  
  526. if (address >= 0 && address < MEMORY_SIZE) {
  527. Registers[REGISTER_A] = Memory[address];
  528. }
  529.  
  530. set_flag_n(Registers[REGISTER_A]);
  531. set_flag_z(Registers[REGISTER_A]);
  532. Flags = Flags & (0xFF - FLAG_C);
  533. break;
  534.  
  535. case 0xD7: //LD INDEXED ABSOLUTE ADDRESSING (abs,X)
  536. address += IndexRegister;
  537. HB = fetch();
  538. LB = fetch();
  539. address += (WORD)((WORD)HB << 8) + LB;
  540.  
  541. if (address >= 0 && address < MEMORY_SIZE) {
  542. Registers[REGISTER_A] = Memory[address];
  543. }
  544.  
  545. set_flag_n(Registers[REGISTER_A]);
  546. set_flag_z(Registers[REGISTER_A]);
  547. Flags = Flags & (0xFF - FLAG_C);
  548. break;
  549.  
  550. /*
  551. * Opcode: ST
  552. * Description: Stores Accumulator into Memory
  553. * Flags: I - N V Z - - C
  554. * Flags: - - T - T - - 0
  555. * Notes: None
  556. */
  557. case 0x10: //ST ABSOLUTE ADDRESSING (abs)
  558. HB = fetch();
  559. LB = fetch();
  560. address += (WORD)((WORD)HB << 8) + LB;
  561.  
  562. if (address >= 0 && address < MEMORY_SIZE) {
  563. Memory[address] = Registers[REGISTER_A];
  564. }
  565.  
  566. set_flag_n(Registers[REGISTER_A]);
  567. set_flag_z(Registers[REGISTER_A]);
  568. Flags = Flags & (0xFF - FLAG_C);
  569. break;
  570.  
  571. case 0x20: //ST INDEXED ABSOLUTE ADDRESSING (abs,X)
  572. address += IndexRegister;
  573. HB = fetch();
  574. LB = fetch();
  575. address += (WORD)((WORD)HB << 8) + LB;
  576.  
  577. if (address >= 0 && address < MEMORY_SIZE) {
  578. Memory[address] = Registers[REGISTER_A];
  579. }
  580.  
  581. set_flag_n(Registers[REGISTER_A]);
  582. set_flag_z(Registers[REGISTER_A]);
  583. Flags = Flags & (0xFF - FLAG_C);
  584. break;
  585.  
  586. /*
  587. * Opcode: MVI
  588. * Description: Loads Memory into register
  589. * Flags: I - N V Z - - C
  590. * Flags: - - T - T - - 0
  591. * Notes: None
  592. */
  593. case 0x2A: //MVI IMMEDIATE ADDRESSING (#); B
  594. data = fetch();
  595. Registers[REGISTER_B] = data;
  596.  
  597. set_flag_n(Registers[REGISTER_B]);
  598. set_flag_z(Registers[REGISTER_B]);
  599. Flags = Flags & (0xFF - FLAG_C);
  600. break;
  601.  
  602. case 0x2B: //MVI IMMEDIATE ADDRESSING (#); C
  603. data = fetch();
  604. Registers[REGISTER_C] = data;
  605.  
  606. set_flag_n(Registers[REGISTER_C]);
  607. set_flag_z(Registers[REGISTER_C]);
  608. Flags = Flags & (0xFF - FLAG_C);
  609. break;
  610.  
  611. case 0x2C: //MVI IMMEDIATE ADDRESSING (#); D
  612. data = fetch();
  613. Registers[REGISTER_D] = data;
  614.  
  615. set_flag_n(Registers[REGISTER_D]);
  616. set_flag_z(Registers[REGISTER_D]);
  617. Flags = Flags & (0xFF - FLAG_C);
  618. break;
  619.  
  620. case 0x2D: //MVI IMMEDIATE ADDRESSING (#); E
  621. data = fetch();
  622. Registers[REGISTER_E] = data;
  623.  
  624. set_flag_n(Registers[REGISTER_E]);
  625. set_flag_z(Registers[REGISTER_E]);
  626. Flags = Flags & (0xFF - FLAG_C);
  627. break;
  628.  
  629. case 0x2E: //MVI IMMEDIATE ADDRESSING (#); L
  630. data = fetch();
  631. Registers[REGISTER_L] = data;
  632.  
  633. set_flag_n(Registers[REGISTER_L]);
  634. set_flag_z(Registers[REGISTER_L]);
  635. Flags = Flags & (0xFF - FLAG_C);
  636. break;
  637.  
  638. case 0x2F: //MVI IMMEDIATE ADDRESSING (#); H
  639. data = fetch();
  640. Registers[REGISTER_H] = data;
  641.  
  642. set_flag_n(Registers[REGISTER_H]);
  643. set_flag_z(Registers[REGISTER_H]);
  644. Flags = Flags & (0xFF - FLAG_C);
  645. break;
  646.  
  647. /*
  648. * Opcode: LODS
  649. * Description: Loads Memory into Stackpointer
  650. * Flags: I - N V Z - - C
  651. * Flags: - - T - T - - 0
  652. * Notes: None
  653. */
  654. case 0x4F: //LODS IMMEDIATE ADDRESSING (#)
  655. data = fetch();
  656.  
  657. StackPointer = data << 8;
  658. StackPointer += fetch();
  659.  
  660. set_flag_n(Registers[REGISTER_A]);
  661. set_flag_z(Registers[REGISTER_A]);
  662. Flags = Flags & (0xFF - FLAG_C);
  663. break;
  664.  
  665. case 0x5F: //LODS ABSOLUTE ADDRESSING (abs)
  666. HB = fetch();
  667. LB = fetch();
  668. address += (WORD)((WORD)HB << 8) + LB;
  669.  
  670. if (address >= 0 && address < MEMORY_SIZE - 1) {
  671. StackPointer = (WORD)Memory[address] << 8;
  672. StackPointer += Memory[address + 1];
  673. }
  674.  
  675. set_flag_n(Registers[REGISTER_A]);
  676. set_flag_z(Registers[REGISTER_A]);
  677. Flags = Flags & (0xFF - FLAG_C);
  678. break;
  679.  
  680. case 0x6F: //LODS INDEXED ABSOLUTE ADDRESSING (abs, X)
  681. address += IndexRegister;
  682. HB = fetch();
  683. LB = fetch();
  684. address += (WORD)((WORD)HB << 8) + LB;
  685.  
  686. if (address >= 0 && address < MEMORY_SIZE - 1) {
  687. StackPointer = (WORD)Memory[address] << 8;
  688. StackPointer += Memory[address + 1];
  689. }
  690.  
  691. set_flag_n(Registers[REGISTER_A]);
  692. set_flag_z(Registers[REGISTER_A]);
  693. Flags = Flags & (0xFF - FLAG_C);
  694. break;
  695.  
  696. /*
  697. * Opcode: LDX
  698. * Description: Loads Memory into register X
  699. * Flags: I - N V Z - - C
  700. * Flags: - - T - T - - 0
  701. * Notes: None
  702. */
  703. case 0x4E: //LDX IMMEDIATE ADDRESSING (#)
  704. data = fetch();
  705. Registers[IndexRegister] = data;
  706.  
  707. set_flag_n(Registers[IndexRegister]);
  708. set_flag_z(Registers[IndexRegister]);
  709. Flags = Flags & (0xFF - FLAG_C);
  710. break;
  711.  
  712. case 0x5E: //LDX ABSOLUTE ADDRESSING (abs)
  713. HB = fetch();
  714. LB = fetch();
  715. address += (WORD)((WORD)HB << 8) + LB;
  716.  
  717. if (address >= 0 && address < MEMORY_SIZE) {
  718. Registers[IndexRegister] = Memory[address];
  719. }
  720.  
  721. set_flag_n(Registers[IndexRegister]);
  722. set_flag_z(Registers[IndexRegister]);
  723. Flags = Flags & (0xFF - FLAG_C);
  724. break;
  725.  
  726. case 0x6E: //LDX INDEXED ABSOLUTE ADDRESSING (abs,X)
  727. address += IndexRegister;
  728. HB = fetch();
  729. LB = fetch();
  730. address += (WORD)((WORD)HB << 8) + LB;
  731.  
  732. if (address >= 0 && address < MEMORY_SIZE) {
  733. Registers[IndexRegister] = Memory[address];
  734. }
  735.  
  736. set_flag_n(Registers[IndexRegister]);
  737. set_flag_z(Registers[IndexRegister]);
  738. Flags = Flags & (0xFF - FLAG_C);
  739. break;
  740.  
  741. /*
  742. * Opcode: STOX
  743. * Description: Stores register X into Memory
  744. * Flags: I - N V Z - - C
  745. * Flags: - - T - T - - 0
  746. * Notes: None
  747. */
  748. case 0x50: //STOX ABSOLUTE ADDRESSING (abs)
  749. address += IndexRegister;
  750. HB = fetch();
  751. LB = fetch();
  752. address += (WORD)((WORD)HB << 8) + LB;
  753.  
  754. if (address >= 0 && address < MEMORY_SIZE) {
  755. Memory[address] = Registers[IndexRegister];
  756. }
  757.  
  758. set_flag_n(Registers[IndexRegister]);
  759. set_flag_z(Registers[IndexRegister]);
  760. Flags = Flags & (0xFF - FLAG_C);
  761. break;
  762.  
  763. case 0x60: //STOX INDEXED ABSOLUTE ADDRESSING (abs, X)
  764. address += IndexRegister;
  765. HB = fetch();
  766. LB = fetch();
  767. address += (WORD)((WORD)HB << 8) + LB;
  768.  
  769. if (address >= 0 && address < MEMORY_SIZE) {
  770. Memory[address] = Registers[IndexRegister];
  771. }
  772.  
  773. set_flag_n(Registers[IndexRegister]);
  774. set_flag_z(Registers[IndexRegister]);
  775. Flags = Flags & (0xFF - FLAG_C);
  776. break;
  777.  
  778. /*-----------------------------------FLAGS-----------------------------------*/
  779. /*
  780. * Opcode: ADC
  781. * Description: Register added to Accumulator with Carry
  782. * Flags: I - N V Z - - C
  783. * Flags: - - T T T - - T
  784. * Notes: None
  785. */
  786. case 0x90: //ADC A-B
  787. temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
  788.  
  789. if ((Flags & FLAG_C) != 0) {
  790. temp_word++;
  791. }
  792.  
  793. if (temp_word >= 0x100) {
  794. Flags = Flags | FLAG_C; //Set carry flag
  795. }
  796. else {
  797. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  798. }
  799.  
  800. set_flag_n((BYTE)temp_word);
  801. set_flag_z((BYTE)temp_word);
  802. set_flag_v(Registers[REGISTER_A], Registers[REGISTER_B], (BYTE)temp_word);
  803. Registers[REGISTER_A] = (BYTE)temp_word;
  804. break;
  805.  
  806. case 0xA0: //ADC A-C
  807. temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
  808.  
  809. if ((Flags & FLAG_C) != 0) {
  810. temp_word++;
  811. }
  812.  
  813. if (temp_word >= 0x100) {
  814. Flags = Flags | FLAG_C; //Set carry flag
  815. }
  816. else {
  817. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  818. }
  819.  
  820. set_flag_n((BYTE)temp_word);
  821. set_flag_z((BYTE)temp_word);
  822. set_flag_v(Registers[REGISTER_A], Registers[REGISTER_C], (BYTE)temp_word);
  823. Registers[REGISTER_A] = (BYTE)temp_word;
  824. break;
  825.  
  826. case 0xB0: //ADC A-D
  827. temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_D];
  828.  
  829. if ((Flags & FLAG_C) != 0) {
  830. temp_word++;
  831. }
  832.  
  833. if (temp_word >= 0x100) {
  834. Flags = Flags | FLAG_C; //Set carry flag
  835. }
  836. else {
  837. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  838. }
  839.  
  840. set_flag_n((BYTE)temp_word);
  841. set_flag_z((BYTE)temp_word);
  842. set_flag_v(Registers[REGISTER_A], Registers[REGISTER_D], (BYTE)temp_word);
  843. Registers[REGISTER_A] = (BYTE)temp_word;
  844. break;
  845.  
  846. case 0xC0: //ADC A-E
  847. temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_E];
  848.  
  849. if ((Flags & FLAG_C) != 0) {
  850. temp_word++;
  851. }
  852.  
  853. if (temp_word >= 0x100) {
  854. Flags = Flags | FLAG_C; //Set carry flag
  855. }
  856. else {
  857. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  858. }
  859.  
  860. set_flag_n((BYTE)temp_word);
  861. set_flag_z((BYTE)temp_word);
  862. set_flag_v(Registers[REGISTER_A], Registers[REGISTER_E], (BYTE)temp_word);
  863. Registers[REGISTER_A] = (BYTE)temp_word;
  864. break;
  865.  
  866. case 0xD0: //ADC A-L
  867. temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
  868.  
  869. if ((Flags & FLAG_C) != 0) {
  870. temp_word++;
  871. }
  872.  
  873. if (temp_word >= 0x100) {
  874. Flags = Flags | FLAG_C; //Set carry flag
  875. }
  876. else {
  877. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  878. }
  879.  
  880. set_flag_n((BYTE)temp_word);
  881. set_flag_z((BYTE)temp_word);
  882. set_flag_v(Registers[REGISTER_A], Registers[REGISTER_L], (BYTE)temp_word);
  883. Registers[REGISTER_A] = (BYTE)temp_word;
  884. break;
  885.  
  886. case 0xE0: //ADC A-H
  887. temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
  888.  
  889. if ((Flags & FLAG_C) != 0) {
  890. temp_word++;
  891. }
  892.  
  893. if (temp_word >= 0x100) {
  894. Flags = Flags | FLAG_C; //Set carry flag
  895. }
  896. else {
  897. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  898. }
  899.  
  900. set_flag_n((BYTE)temp_word);
  901. set_flag_z((BYTE)temp_word);
  902. set_flag_v(Registers[REGISTER_A], Registers[REGISTER_H], (BYTE)temp_word);
  903. Registers[REGISTER_A] = (BYTE)temp_word;
  904. break;
  905.  
  906. case 0xF0: //ADC A-M
  907. temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_M];
  908.  
  909. if ((Flags & FLAG_C) != 0) {
  910. temp_word++;
  911. }
  912.  
  913. if (temp_word >= 0x100) {
  914. Flags = Flags | FLAG_C; //Set carry flag
  915. }
  916. else {
  917. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  918. }
  919.  
  920. set_flag_n((BYTE)temp_word);
  921. set_flag_z((BYTE)temp_word);
  922. set_flag_v(Registers[REGISTER_A], Registers[REGISTER_M], (BYTE)temp_word);
  923. Registers[REGISTER_A] = (BYTE)temp_word;
  924. break;
  925.  
  926. /*
  927. * Opcode: CMP
  928. * Description: Register compared to Accumulator
  929. * Flags: I - N V Z - - C
  930. * Flags: - - T T T - - T
  931. * Notes: None
  932. */
  933. case 0x92: //CMP A-B
  934. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
  935.  
  936. if (temp_word >= 0x100) {
  937. Flags = Flags | FLAG_C; //Set carry flag
  938. }
  939. else {
  940. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  941. }
  942.  
  943. set_flag_n((BYTE)temp_word);
  944. set_flag_z((BYTE)temp_word);
  945. set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_B], (BYTE)temp_word);
  946. break;
  947.  
  948. case 0xA2: //CMP A-C
  949. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
  950.  
  951. if (temp_word >= 0x100) {
  952. Flags = Flags | FLAG_C; //Set carry flag
  953. }
  954. else {
  955. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  956. }
  957.  
  958. set_flag_n((BYTE)temp_word);
  959. set_flag_z((BYTE)temp_word);
  960. set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_C], (BYTE)temp_word);
  961. break;
  962.  
  963. case 0xB2: //CMP A-D
  964. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
  965.  
  966. if (temp_word >= 0x100) {
  967. Flags = Flags | FLAG_C; //Set carry flag
  968. }
  969. else {
  970. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  971. }
  972.  
  973. set_flag_n((BYTE)temp_word);
  974. set_flag_z((BYTE)temp_word);
  975. set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_D], (BYTE)temp_word);
  976. break;
  977.  
  978. case 0xC2: //CMP A-E
  979. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
  980.  
  981. if (temp_word >= 0x100) {
  982. Flags = Flags | FLAG_C; //Set carry flag
  983. }
  984. else {
  985. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  986. }
  987.  
  988. set_flag_n((BYTE)temp_word);
  989. set_flag_z((BYTE)temp_word);
  990. set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_E], (BYTE)temp_word);
  991. break;
  992.  
  993. case 0xD2: //CMP A-L
  994. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
  995.  
  996. if (temp_word >= 0x100) {
  997. Flags = Flags | FLAG_C; //Set carry flag
  998. }
  999. else {
  1000. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  1001. }
  1002.  
  1003. set_flag_n((BYTE)temp_word);
  1004. set_flag_z((BYTE)temp_word);
  1005. set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_L], (BYTE)temp_word);
  1006. break;
  1007.  
  1008. case 0xE2: //CMP A-H
  1009. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
  1010.  
  1011. if (temp_word >= 0x100) {
  1012. Flags = Flags | FLAG_C; //Set carry flag
  1013. }
  1014. else {
  1015. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  1016. }
  1017.  
  1018. set_flag_n((BYTE)temp_word);
  1019. set_flag_z((BYTE)temp_word);
  1020. set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_H], (BYTE)temp_word);
  1021. break;
  1022.  
  1023. case 0xF2: //CMP A-M
  1024. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
  1025.  
  1026. if (temp_word >= 0x100) {
  1027. Flags = Flags | FLAG_C; //Set carry flag
  1028. }
  1029. else {
  1030. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  1031. }
  1032.  
  1033. set_flag_n((BYTE)temp_word);
  1034. set_flag_z((BYTE)temp_word);
  1035. set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_M], (BYTE)temp_word);
  1036. break;
  1037.  
  1038. /*
  1039. * Opcode: TSA
  1040. * Description: Transfers Status register to Accumulator
  1041. * Flags: I - N V Z - - C
  1042. * Flags: - - - - - - - -
  1043. * Notes: None
  1044. */
  1045. case 0x75: //TSA IMPLIED ADDRESSING(impl)
  1046. Registers[REGISTER_A] = Flags;
  1047. break;
  1048.  
  1049. /*
  1050. * Opcode: TAS
  1051. * Description: Transfers Accumulator to Status register
  1052. * Flags: I - N V Z - - C
  1053. * Flags: - - - - - - - -
  1054. * Notes: None
  1055. */
  1056. case 0x74: //TAS IMPLIED ADDRESSING(impl)
  1057. Flags = Registers[REGISTER_A];
  1058. break;
  1059.  
  1060. /*
  1061. * Opcode: CLC
  1062. * Description: Clear Carry flag
  1063. * Flags: I - N V Z - - C
  1064. * Flags: - - - - - - - 0
  1065. * Notes: None
  1066. */
  1067. case 0x15: //CLC IMPLIED ADDRESSING(impl)
  1068. Flags = Flags & (0xFF - FLAG_C);
  1069. break;
  1070.  
  1071. /*
  1072. * Opcode: SEC
  1073. * Description: Set Carry flag
  1074. * Flags: I - N V Z - - C
  1075. * Flags: - - - - - - - 1
  1076. * Notes: None
  1077. */
  1078. case 0x16: //SEC IMPLIED ADDRESSING(impl)
  1079. Flags = Flags | FLAG_C;
  1080. break;
  1081.  
  1082. /*
  1083. * Opcode: CLI
  1084. * Description: Clear Interrupt flag
  1085. * Flags: I - N V Z - - C
  1086. * Flags: 0 - - - - - - -
  1087. * Notes: None
  1088. */
  1089. case 0x17: //CLI IMPLIED ADDRESSING(impl)
  1090. Flags = Flags & (0xFF - FLAG_I);
  1091. break;
  1092.  
  1093. /*
  1094. * Opcode: STI
  1095. * Description: Set Interrupt flag
  1096. * Flags: I - N V Z - - C
  1097. * Flags: 1 - - - - - - -
  1098. * Notes: None
  1099. */
  1100. case 0x18: //STI IMPLIED ADDRESSING(impl)
  1101. Flags = Flags | FLAG_I;
  1102. break;
  1103.  
  1104. /*
  1105. * Opcode: SEV
  1106. * Description: Set Overflow flag
  1107. * Flags: I - N V Z - - C
  1108. * Flags: - - - 1 - - - -
  1109. * Notes: None
  1110. */
  1111. case 0x19: //SEV IMPLIED ADDRESSING(impl)
  1112. Flags = Flags | FLAG_V;
  1113. break;
  1114.  
  1115. /*
  1116. * Opcode: CLV
  1117. * Description: Clear Overflow flag
  1118. * Flags: I - N V Z - - C
  1119. * Flags: - - - 0 - - - -
  1120. * Notes: None
  1121. */
  1122. case 0x1A: //CLV IMPLIED ADDRESSING(impl)
  1123. Flags = Flags & (0xFF - FLAG_V);
  1124. break;
  1125.  
  1126. /*-----------------------------------STACK-----------------------------------*/
  1127. /*
  1128. * Opcode: PSH
  1129. * Description: Pushes Register onto the Stack
  1130. * Flags: I - N V Z - - C
  1131. * Flags: - - - - - - - -
  1132. * Notes: None
  1133. */
  1134. case 0x11: //PSH A
  1135. if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1136. Memory[StackPointer] = Registers[REGISTER_A];
  1137. StackPointer--;
  1138. }
  1139. break;
  1140.  
  1141. case 0x21: //PSH FL
  1142. if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1143. Memory[StackPointer] = Flags;
  1144. StackPointer--;
  1145. }
  1146. break;
  1147.  
  1148. case 0x31: //PSH B
  1149. if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1150. Memory[StackPointer] = Registers[REGISTER_B];
  1151. StackPointer--;
  1152. }
  1153. break;
  1154.  
  1155. case 0x41: //PSH C
  1156. if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1157. Memory[StackPointer] = Registers[REGISTER_C];
  1158. StackPointer--;
  1159. }
  1160. break;
  1161.  
  1162. case 0x51: //PSH D
  1163. if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1164. Memory[StackPointer] = Registers[REGISTER_D];
  1165. StackPointer--;
  1166. }
  1167. break;
  1168.  
  1169. case 0x61: //PSH E
  1170. if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1171. Memory[StackPointer] = Registers[REGISTER_E];
  1172. StackPointer--;
  1173. }
  1174. break;
  1175.  
  1176. case 0x71: //PSH L
  1177. if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1178. Memory[StackPointer] = Registers[REGISTER_L];
  1179. StackPointer--;
  1180. }
  1181. break;
  1182.  
  1183. case 0x81: //PSH H
  1184. if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1185. Memory[StackPointer] = Registers[REGISTER_H];
  1186. StackPointer--;
  1187. }
  1188. break;
  1189.  
  1190. /*
  1191. * Opcode: POP
  1192. * Description: Pop the top of the Stack into the Register
  1193. * Flags: I - N V Z - - C
  1194. * Flags: - - - - - - - -
  1195. * Notes: None
  1196. */
  1197. case 0x12: //POP A
  1198. if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1199. StackPointer++;
  1200. Registers[REGISTER_A] = Memory[StackPointer];
  1201. }
  1202. break;
  1203.  
  1204. case 0x22: //POP FL
  1205. if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1206. StackPointer++;
  1207. Flags = Memory[StackPointer];
  1208. }
  1209. break;
  1210.  
  1211. case 0x32: //POP B
  1212. if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1213. StackPointer++;
  1214. Registers[REGISTER_B] = Memory[StackPointer];
  1215. }
  1216. break;
  1217.  
  1218. case 0x42: //POP C
  1219. if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1220. StackPointer++;
  1221. Registers[REGISTER_C] = Memory[StackPointer];
  1222. }
  1223. break;
  1224.  
  1225. case 0x52: //POP D
  1226. if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1227. StackPointer++;
  1228. Registers[REGISTER_D] = Memory[StackPointer];
  1229. }
  1230. break;
  1231.  
  1232. case 0x62: //POP E
  1233. if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1234. StackPointer++;
  1235. Registers[REGISTER_E] = Memory[StackPointer];
  1236. }
  1237. break;
  1238.  
  1239. case 0x72: //POP L
  1240. if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1241. StackPointer++;
  1242. Registers[REGISTER_L] = Memory[StackPointer];
  1243. }
  1244. break;
  1245.  
  1246. case 0x82: //POP H
  1247. if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1248. StackPointer++;
  1249. Registers[REGISTER_H] = Memory[StackPointer];
  1250. }
  1251. break;
  1252.  
  1253. /*
  1254. * Opcode: JMP
  1255. * Description: Load Memory into ProgramCounter
  1256. * Flags: I - N V Z - - C
  1257. * Flags: - - - - - - - -
  1258. * Notes: None
  1259. */
  1260. case 0xFA: //JMP ABSOLUTE ADDRESSING (abs)
  1261. HB = fetch();
  1262. LB = fetch();
  1263. address = ((WORD)HB << 8) + (WORD)LB;
  1264.  
  1265. if (address >= 0 && address < MEMORY_SIZE) {
  1266. ProgramCounter = address;
  1267. }
  1268. break;
  1269.  
  1270. /*
  1271. * Opcode: JPR
  1272. * Description: Jump to subroutine
  1273. * Flags: I - N V Z - - C
  1274. * Flags: - - - - - - - -
  1275. * Notes: None
  1276. */
  1277. case 0x33: //JPR ABSOLUTE ADDRESSING (abs)
  1278. HB = fetch();
  1279. LB = fetch();
  1280. address = ((WORD)HB << 8) + (WORD)LB;
  1281.  
  1282. if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1283. Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1284. StackPointer--;
  1285. Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1286. StackPointer--;
  1287. }
  1288. ProgramCounter = address;
  1289. break;
  1290.  
  1291. /*
  1292. * Opcode: RTN
  1293. * Description: Return from subroutine
  1294. * Flags: I - N V Z - - C
  1295. * Flags: - - - - - - - -
  1296. * Notes: None
  1297. */
  1298. case 0x0E: //RTN IMPLIED ADDRESSING (impl)
  1299. if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
  1300. StackPointer++;
  1301. HB = Memory[StackPointer];
  1302. StackPointer++;
  1303. }
  1304. ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
  1305. break;
  1306.  
  1307. /*
  1308. * Opcode: BRA
  1309. * Description: Branch always
  1310. * Flags: I - N V Z - - C
  1311. * Flags: - - - - - - - -
  1312. * Notes: None
  1313. */
  1314. case 0x00: //BRA OFFSET ADDRESSING (rel)
  1315. LB = fetch();
  1316.  
  1317. offset = (WORD)LB;
  1318. if ((offset & 0x80) != 0) {
  1319. offset = offset + 0xFF00;
  1320. }
  1321. address = ProgramCounter + offset;
  1322. break;
  1323.  
  1324. /*
  1325. * Opcode: BCC
  1326. * Description: Branch on Carry clear
  1327. * Flags: I - N V Z - - C
  1328. * Flags: - - - - - - - -
  1329. * Notes: None
  1330. */
  1331. case 0x01: //BCC OFFSET ADDRESSING (rel)
  1332. LB = fetch();
  1333.  
  1334. if (CF == 0) {
  1335. offset = (WORD)LB;
  1336. if ((offset & 0x80) != 0) {
  1337. offset = offset + 0xFF00;
  1338. }
  1339. address = ProgramCounter + offset;
  1340. ProgramCounter = address;
  1341. }
  1342. break;
  1343.  
  1344. /*
  1345. * Opcode: BCS
  1346. * Description: Branch on Carry set
  1347. * Flags: I - N V Z - - C
  1348. * Flags: - - - - - - - -
  1349. * Notes: None
  1350. */
  1351. case 0x02: //BCS OFFSET ADDRESSING (rel)
  1352. LB = fetch();
  1353.  
  1354. if (CF == 1) {
  1355. offset = (WORD)LB;
  1356. if ((offset & 0x80) != 0) {
  1357. offset = offset + 0xFF00;
  1358. }
  1359. address = ProgramCounter + offset;
  1360. ProgramCounter = address;
  1361. }
  1362. break;
  1363.  
  1364. /*
  1365. * Opcode: BNE
  1366. * Description: Branch on Result not Zero
  1367. * Flags: I - N V Z - - C
  1368. * Flags: - - - - - - - -
  1369. * Notes: None
  1370. */
  1371. case 0x03: //BNE OFFSET ADDRESSING (rel)
  1372. LB = fetch();
  1373.  
  1374. if (ZF == 0) {
  1375. offset = (WORD)LB;
  1376. if ((offset & 0x80) != 0) {
  1377. offset = offset + 0xFF00;
  1378. }
  1379. address = ProgramCounter + offset;
  1380. ProgramCounter = address;
  1381. }
  1382. break;
  1383.  
  1384. /*
  1385. * Opcode: BEQ
  1386. * Description: Branch on Result equal to Zero
  1387. * Flags: I - N V Z - - C
  1388. * Flags: - - - - - - - -
  1389. * Notes: None
  1390. */
  1391. case 0x04: //BEQ OFFSET ADDRESSING (rel)
  1392. LB = fetch();
  1393.  
  1394. if (ZF == 1) {
  1395. offset = (WORD)LB;
  1396. if ((offset & 0x80) != 0) {
  1397. offset = offset + 0xFF00;
  1398. }
  1399. address = ProgramCounter + offset;
  1400. ProgramCounter = address;
  1401. }
  1402. break;
  1403.  
  1404. /*
  1405. * Opcode: BVC
  1406. * Description: Branch on Overflow clear
  1407. * Flags: I - N V Z - - C
  1408. * Flags: - - - - - - - -
  1409. * Notes: None
  1410. */
  1411. case 0x05: //BVC OFFSET ADDRESSING (rel)
  1412. LB = fetch();
  1413.  
  1414. if (VF == 0) {
  1415. offset = (WORD)LB;
  1416. if ((offset & 0x80) != 0) {
  1417. offset = offset + 0xFF00;
  1418. }
  1419. address = ProgramCounter + offset;
  1420. ProgramCounter = address;
  1421. }
  1422. break;
  1423.  
  1424. /*
  1425. * Opcode: BVS
  1426. * Description: Branch on Overflow set
  1427. * Flags: I - N V Z - - C
  1428. * Flags: - - - - - - - -
  1429. * Notes: None
  1430. */
  1431. case 0x06: //BVS OFFSET ADDRESSING (rel)
  1432. LB = fetch();
  1433.  
  1434. if (VF == 1) {
  1435. offset = (WORD)LB;
  1436. if ((offset & 0x80) != 0) {
  1437. offset = offset + 0xFF00;
  1438. }
  1439. address = ProgramCounter + offset;
  1440. ProgramCounter = address;
  1441. }
  1442. break;
  1443.  
  1444. /*
  1445. * Opcode: BMI
  1446. * Description: Branch on negative result
  1447. * Flags: I - N V Z - - C
  1448. * Flags: - - - - - - - -
  1449. * Notes: None
  1450. */
  1451. case 0x07: //BMI OFFSET ADDRESSING (rel)
  1452. LB = fetch();
  1453.  
  1454. if (NF == 1) {
  1455. offset = (WORD)LB;
  1456. if ((offset & 0x80) != 0) {
  1457. offset = offset + 0xFF00;
  1458. }
  1459. address = ProgramCounter + offset;
  1460. ProgramCounter = address;
  1461. }
  1462. break;
  1463.  
  1464. /*
  1465. * Opcode: BPL
  1466. * Description: Branch on positive result
  1467. * Flags: I - N V Z - - C
  1468. * Flags: - - - - - - - -
  1469. * Notes: None
  1470. */
  1471. case 0x08: //BPL OFFSET ADDRESSING (rel)
  1472. LB = fetch();
  1473.  
  1474. if (NF == 0) {
  1475. offset = (WORD)LB;
  1476. if ((offset & 0x80) != 0) {
  1477. offset = offset + 0xFF00;
  1478. }
  1479. address = ProgramCounter + offset;
  1480. ProgramCounter = address;
  1481. }
  1482. break;
  1483.  
  1484. /*
  1485. * Opcode: BGE
  1486. * Description: Branch on result less than or equal to zero
  1487. * Flags: I - N V Z - - C
  1488. * Flags: - - - - - - - -
  1489. * Notes: None
  1490. */
  1491. case 0x09: //BGE OFFSET ADDRESSING (rel)
  1492. LB = fetch();
  1493.  
  1494. if ((NF ^ VF) == 0) {
  1495. offset = (WORD)LB;
  1496. if ((offset & 0x80) != 0) {
  1497. offset = offset + 0xFF00;
  1498. }
  1499. address = ProgramCounter + offset;
  1500. ProgramCounter = address;
  1501. }
  1502. break;
  1503.  
  1504. /*
  1505. * Opcode: BLE
  1506. * Description: Branch on result greater than or equal to zero
  1507. * Flags: I - N V Z - - C
  1508. * Flags: - - - - - - - -
  1509. * Notes: None
  1510. */
  1511. case 0x0A: //BLE OFFSET ADDRESSING (rel)
  1512. LB = fetch();
  1513.  
  1514. if ((ZF | NF ^ VF) == 1) {
  1515. offset = (WORD)LB;
  1516. if ((offset & 0x80) != 0) {
  1517. offset = offset + 0xFF00;
  1518. }
  1519. address = ProgramCounter + offset;
  1520. ProgramCounter = address;
  1521. }
  1522. break;
  1523.  
  1524. /*
  1525. * Opcode: BLS
  1526. * Description: Branch on result same or lower
  1527. * Flags: I - N V Z - - C
  1528. * Flags: - - - - - - - -
  1529. * Notes: None
  1530. */
  1531. case 0x0B: //BLS OFFSET ADDRESSING (rel)
  1532. LB = fetch();
  1533.  
  1534. if ((CF | ZF) == 1) {
  1535. offset = (WORD)LB;
  1536. if ((offset & 0x80) != 0) {
  1537. offset = offset + 0xFF00;
  1538. }
  1539. address = ProgramCounter + offset;
  1540. ProgramCounter = address;
  1541. }
  1542. break;
  1543.  
  1544. /*
  1545. * Opcode: BHI
  1546. * Description: Branch on result higher
  1547. * Flags: I - N V Z - - C
  1548. * Flags: - - - - - - - -
  1549. * Notes: None
  1550. */
  1551. case 0x0C: //BHI OFFSET ADDRESSING (rel)
  1552. LB = fetch();
  1553.  
  1554. if ((CF | ZF) == 0) {
  1555. offset = (WORD)LB;
  1556. if ((offset & 0x80) != 0) {
  1557. offset = offset + 0xFF00;
  1558. }
  1559. address = ProgramCounter + offset;
  1560. ProgramCounter = address;
  1561. }
  1562. break;
  1563.  
  1564. /*
  1565. * Opcode: CCC
  1566. * Description: Call on Carry clear
  1567. * Flags: I - N V Z - - C
  1568. * Flags: - - - - - - - -
  1569. * Notes: None
  1570. */
  1571. case 0x34: //CCC ABSOLUTE ADDRESSING (abs)
  1572. HB = fetch();
  1573. LB = fetch();
  1574.  
  1575. if (CF == 0) {
  1576. address += (WORD)((WORD)HB << 8) + LB;
  1577. if (address >= 0 && address < MEMORY_SIZE) {
  1578. if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1579. Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1580. StackPointer--;
  1581. Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1582. StackPointer--;
  1583. }
  1584. ProgramCounter = (WORD)address;
  1585. }
  1586. }
  1587. break;
  1588.  
  1589. /*
  1590. * Opcode: CCS
  1591. * Description: Call on Carry set
  1592. * Flags: I - N V Z - - C
  1593. * Flags: - - - - - - - -
  1594. * Notes: None
  1595. */
  1596. case 0x35: //CCS ABSOLUTE ADDRESSING (abs)
  1597. HB = fetch();
  1598. LB = fetch();
  1599.  
  1600. if (CF == 1) {
  1601. address += (WORD)((WORD)HB << 8) + LB;
  1602. if (address >= 0 && address < MEMORY_SIZE) {
  1603. if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1604. Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1605. StackPointer--;
  1606. Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1607. StackPointer--;
  1608. }
  1609. ProgramCounter = (WORD)address;
  1610. }
  1611. }
  1612. break;
  1613.  
  1614. /*
  1615. * Opcode: CNE
  1616. * Description: Call on result not Zero
  1617. * Flags: I - N V Z - - C
  1618. * Flags: - - - - - - - -
  1619. * Notes: None
  1620. */
  1621. case 0x36: //CNE ABSOLUTE ADDRESSING (abs)
  1622. HB = fetch();
  1623. LB = fetch();
  1624.  
  1625. if (ZF == 0) {
  1626. address += (WORD)((WORD)HB << 8) + LB;
  1627. if (address >= 0 && address < MEMORY_SIZE) {
  1628. if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1629. Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1630. StackPointer--;
  1631. Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1632. StackPointer--;
  1633. }
  1634. ProgramCounter = (WORD)address;
  1635. }
  1636. }
  1637. break;
  1638.  
  1639. /*
  1640. * Opcode: CEQ
  1641. * Description: Call on result equal to Zero
  1642. * Flags: I - N V Z - - C
  1643. * Flags: - - - - - - - -
  1644. * Notes: None
  1645. */
  1646. case 0x37: //CEQ ABSOLUTE ADDRESSING (abs)
  1647. HB = fetch();
  1648. LB = fetch();
  1649.  
  1650. if (ZF == 1) {
  1651. address += (WORD)((WORD)HB << 8) + LB;
  1652. if (address >= 0 && address < MEMORY_SIZE) {
  1653. if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1654. Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1655. StackPointer--;
  1656. Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1657. StackPointer--;
  1658. }
  1659. ProgramCounter = (WORD)address;
  1660. }
  1661. }
  1662. break;
  1663.  
  1664. /*
  1665. * Opcode: CVC
  1666. * Description: Call on Overflow clear
  1667. * Flags: I - N V Z - - C
  1668. * Flags: - - - - - - - -
  1669. * Notes: None
  1670. */
  1671. case 0x38: //CVC ABSOLUTE ADDRESSING (abs)
  1672. HB = fetch();
  1673. LB = fetch();
  1674.  
  1675. if (VF == 0) {
  1676. address += (WORD)((WORD)HB << 8) + LB;
  1677. if (address >= 0 && address < MEMORY_SIZE) {
  1678. if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1679. Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1680. StackPointer--;
  1681. Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1682. StackPointer--;
  1683. }
  1684. ProgramCounter = (WORD)address;
  1685. }
  1686. }
  1687. break;
  1688.  
  1689. /*
  1690. * Opcode: CVS
  1691. * Description: Call on Overflow set
  1692. * Flags: I - N V Z - - C
  1693. * Flags: - - - - - - - -
  1694. * Notes: None
  1695. */
  1696. case 0x39: //CVS ABSOLUTE ADDRESSING (abs)
  1697. HB = fetch();
  1698. LB = fetch();
  1699.  
  1700. if (VF == 1) {
  1701. address += (WORD)((WORD)HB << 8) + LB;
  1702. if (address >= 0 && address < MEMORY_SIZE) {
  1703. if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1704. Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1705. StackPointer--;
  1706. Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1707. StackPointer--;
  1708. }
  1709. ProgramCounter = (WORD)address;
  1710. }
  1711. }
  1712. break;
  1713.  
  1714. /*
  1715. * Opcode: CMI
  1716. * Description: Call on negative result
  1717. * Flags: I - N V Z - - C
  1718. * Flags: - - - - - - - -
  1719. * Notes: None
  1720. */
  1721. case 0x3A: //CMI ABSOLUTE ADDRESSING (abs)
  1722. HB = fetch();
  1723. LB = fetch();
  1724.  
  1725. if (NF == 1) {
  1726. address += (WORD)((WORD)HB << 8) + LB;
  1727. if (address >= 0 && address < MEMORY_SIZE) {
  1728. if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1729. Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1730. StackPointer--;
  1731. Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1732. StackPointer--;
  1733. }
  1734. ProgramCounter = (WORD)address;
  1735. }
  1736. }
  1737. break;
  1738.  
  1739. /*
  1740. * Opcode: CPL
  1741. * Description: Call on positive result
  1742. * Flags: I - N V Z - - C
  1743. * Flags: - - - - - - - -
  1744. * Notes: None
  1745. */
  1746. case 0x3B: //CPL ABSOLUTE ADDRESSING (abs)
  1747. HB = fetch();
  1748. LB = fetch();
  1749.  
  1750. if (NF == 0) {
  1751. address += (WORD)((WORD)HB << 8) + LB;
  1752. if (address >= 0 && address < MEMORY_SIZE) {
  1753. if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1754. Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1755. StackPointer--;
  1756. Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1757. StackPointer--;
  1758. }
  1759. ProgramCounter = (WORD)address;
  1760. }
  1761. }
  1762. break;
  1763.  
  1764. /*
  1765. * Opcode: CHI
  1766. * Description: Call on result same or lower
  1767. * Flags: I - N V Z - - C
  1768. * Flags: - - - - - - - -
  1769. * Notes: None
  1770. */
  1771. case 0x3C: //CHI ABSOLUTE ADDRESSING (abs)
  1772. HB = fetch();
  1773. LB = fetch();
  1774.  
  1775. if ((CF | ZF) == 1) {
  1776. address += (WORD)((WORD)HB << 8) + LB;
  1777. if (address >= 0 && address < MEMORY_SIZE) {
  1778. if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1779. Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1780. StackPointer--;
  1781. Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1782. StackPointer--;
  1783. }
  1784. ProgramCounter = (WORD)address;
  1785. }
  1786. }
  1787. break;
  1788.  
  1789. /*
  1790. * Opcode: CLE
  1791. * Description: Call on result higher
  1792. * Flags: I - N V Z - - C
  1793. * Flags: - - - - - - - -
  1794. * Notes: None
  1795. */
  1796. case 0x3D: //CLE ABSOLUTE ADDRESSING (abs)
  1797. HB = fetch();
  1798. LB = fetch();
  1799.  
  1800. if ((CF | ZF) == 0) {
  1801. address += (WORD)((WORD)HB << 8) + LB;
  1802. if (address >= 0 && address < MEMORY_SIZE) {
  1803. if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1804. Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1805. StackPointer--;
  1806. Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1807. StackPointer--;
  1808. }
  1809. ProgramCounter = (WORD)address;
  1810. }
  1811. }
  1812. break;
  1813.  
  1814. /*-------------------------------INC AND LOGIC-------------------------------*/
  1815. /*
  1816. * Opcode: INC
  1817. * Description: Increment Memory or Accumulator
  1818. * Flags: I - N V Z - - C
  1819. * Flags: - - T - T - - -
  1820. * Notes: None
  1821. */
  1822. case 0x44: //INC ABSOLUTE ADDRESSING (abs)
  1823. HB = fetch();
  1824. LB = fetch();
  1825. address += (WORD)((WORD)HB << 8) + LB;
  1826.  
  1827. if (address >= 0 && address < MEMORY_SIZE) {
  1828. Memory[address]++;
  1829. }
  1830. set_flag_n(Memory[address]);
  1831. set_flag_z(Memory[address]);
  1832. break;
  1833.  
  1834. case 0x54: //INC INDEXED ABSOLUTE ADDRESSING (abs, X)
  1835. address += IndexRegister;
  1836. HB = fetch();
  1837. LB = fetch();
  1838. address += (WORD)((WORD)HB << 8) + LB;
  1839.  
  1840. if (address >= 0 && address < MEMORY_SIZE) {
  1841. Memory[address]++;
  1842. }
  1843.  
  1844. set_flag_n(Memory[address]);
  1845. set_flag_z(Memory[address]);
  1846. break;
  1847.  
  1848. /*
  1849. * Opcode: INCA
  1850. * Description: Increment Memory or Accumulator
  1851. * Flags: I - N V Z - - C
  1852. * Flags: - - T - T - - -
  1853. * Notes: None
  1854. */
  1855. case 0x64: //INCA
  1856. Registers[REGISTER_A]++;
  1857.  
  1858. set_flag_n(Registers[REGISTER_A]);
  1859. set_flag_z(Registers[REGISTER_A]);
  1860. break;
  1861.  
  1862. /*
  1863. * Opcode: INX
  1864. * Description: Increments register X
  1865. * Flags: I - N V Z - - C
  1866. * Flags: - - - - T - - -
  1867. * Notes: None
  1868. */
  1869. case 0x1C: //INX
  1870. IndexRegister++;
  1871. set_flag_z(IndexRegister);
  1872. break;
  1873.  
  1874. /*
  1875. * Opcode: DEX
  1876. * Description: Decrements register X
  1877. * Flags: I - N V Z - - C
  1878. * Flags: - - - - T - - -
  1879. * Notes: None
  1880. */
  1881. case 0x1B: //DEX
  1882. IndexRegister--;
  1883. set_flag_z(IndexRegister);
  1884. break;
  1885.  
  1886. /*
  1887. * Opcode: AND
  1888. * Description: Register bitwise and with Accumulator
  1889. * Flags: I - N V Z - - C
  1890. * Flags: - - T - T - - -
  1891. * Notes: None
  1892. */
  1893. case 0x94: //AND A-B
  1894. Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_B];
  1895. set_flag_n(Registers[REGISTER_A]);
  1896. set_flag_z(Registers[REGISTER_A]);
  1897. break;
  1898.  
  1899. case 0xA4: //AND A-C
  1900. Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_C];
  1901. set_flag_n(Registers[REGISTER_A]);
  1902. set_flag_z(Registers[REGISTER_A]);
  1903. break;
  1904.  
  1905. case 0xB4: //AND A-D
  1906. Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_D];
  1907. set_flag_n(Registers[REGISTER_A]);
  1908. set_flag_z(Registers[REGISTER_A]);
  1909. break;
  1910.  
  1911. case 0xC4: //AND A-E
  1912. Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_E];
  1913. set_flag_n(Registers[REGISTER_A]);
  1914. set_flag_z(Registers[REGISTER_A]);
  1915. break;
  1916.  
  1917. case 0xD4: //AND A-L
  1918. Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_L];
  1919. set_flag_n(Registers[REGISTER_A]);
  1920. set_flag_z(Registers[REGISTER_A]);
  1921. break;
  1922.  
  1923. case 0xE4: //AND A-H
  1924. Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_H];
  1925. set_flag_n(Registers[REGISTER_A]);
  1926. set_flag_z(Registers[REGISTER_A]);
  1927. break;
  1928.  
  1929. case 0xF4: //AND A-M
  1930. Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_M];
  1931. set_flag_n(Registers[REGISTER_A]);
  1932. set_flag_z(Registers[REGISTER_A]);
  1933. break;
  1934.  
  1935. /*
  1936. * Opcode: BT
  1937. * Description: Register Bit tested with Accumulator
  1938. * Flags: I - N V Z - - C
  1939. * Flags: - - T - T - - -
  1940. * Notes: None
  1941. */
  1942. case 0x96: //BT A-B
  1943. data = Registers[REGISTER_A] & Registers[REGISTER_B];
  1944. set_flag_n(data);
  1945. set_flag_z(data);
  1946. break;
  1947.  
  1948. case 0xA6: //BT A-C
  1949. data = Registers[REGISTER_A] & Registers[REGISTER_C];
  1950. set_flag_n(data);
  1951. set_flag_z(data);
  1952. break;
  1953.  
  1954. case 0xB6: //BT A-D
  1955. data = Registers[REGISTER_A] & Registers[REGISTER_D];
  1956. set_flag_n(data);
  1957. set_flag_z(data);
  1958. break;
  1959.  
  1960. case 0xC6: //BT A-E
  1961. data = Registers[REGISTER_A] & Registers[REGISTER_E];
  1962. set_flag_n(data);
  1963. set_flag_z(data);
  1964. break;
  1965.  
  1966. case 0xD6: //BT A-L
  1967. data = Registers[REGISTER_A] & Registers[REGISTER_L];
  1968. set_flag_n(data);
  1969. set_flag_z(data);
  1970. break;
  1971.  
  1972. case 0xE6: //BT A-H
  1973. data = Registers[REGISTER_A] & Registers[REGISTER_H];
  1974. set_flag_n(data);
  1975. set_flag_z(data);
  1976. break;
  1977.  
  1978. case 0xF6: //BT A-M
  1979. data = Registers[REGISTER_A] & Registers[REGISTER_M];
  1980. set_flag_n(data);
  1981. set_flag_z(data);
  1982. break;
  1983.  
  1984. /*---------------------------------ARITHMATIC--------------------------------*/
  1985. /*
  1986. * Opcode: SBC
  1987. * Description: Register subtracted to Accumulator with Carry
  1988. * Flags: I - N V Z - - C
  1989. * Flags: - - T T T - - T
  1990. * Notes: None
  1991. */
  1992. case 0x91: //SBC A-B
  1993. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
  1994.  
  1995. if ((Flags & FLAG_C) != 0) {
  1996. temp_word--;
  1997. }
  1998.  
  1999. if (temp_word >= 0x100) {
  2000. Flags = Flags | FLAG_C; //Set carry flag
  2001. }
  2002. else {
  2003. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2004. }
  2005.  
  2006. set_flag_n((BYTE)temp_word);
  2007. set_flag_z((BYTE)temp_word);
  2008. set_flag_v(REGISTER_A, -REGISTER_B, (BYTE)temp_word);
  2009. Registers[REGISTER_A] = (BYTE)temp_word;
  2010. break;
  2011.  
  2012. case 0xA1: //SBC A-C
  2013. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
  2014.  
  2015. if ((Flags & FLAG_C) != 0) {
  2016. temp_word--;
  2017. }
  2018.  
  2019. if (temp_word >= 0x100) {
  2020. Flags = Flags | FLAG_C; //Set carry flag
  2021. }
  2022. else {
  2023. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2024. }
  2025.  
  2026. set_flag_n((BYTE)temp_word);
  2027. set_flag_z((BYTE)temp_word);
  2028. set_flag_v(REGISTER_A, -REGISTER_C, (BYTE)temp_word);
  2029. Registers[REGISTER_A] = (BYTE)temp_word;
  2030. break;
  2031.  
  2032. case 0xB1: //SBC A-D
  2033. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
  2034.  
  2035. if ((Flags & FLAG_C) != 0) {
  2036. temp_word--;
  2037. }
  2038.  
  2039. if (temp_word >= 0x100) {
  2040. Flags = Flags | FLAG_C; //Set carry flag
  2041. }
  2042. else {
  2043. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2044. }
  2045.  
  2046. set_flag_n((BYTE)temp_word);
  2047. set_flag_z((BYTE)temp_word);
  2048. set_flag_v(REGISTER_A, -REGISTER_D, (BYTE)temp_word);
  2049. Registers[REGISTER_A] = (BYTE)temp_word;
  2050. break;
  2051.  
  2052. case 0xC1: //SBC A-E
  2053. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
  2054.  
  2055. if ((Flags & FLAG_C) != 0) {
  2056. temp_word--;
  2057. }
  2058.  
  2059. if (temp_word >= 0x100) {
  2060. Flags = Flags | FLAG_C; //Set carry flag
  2061. }
  2062. else {
  2063. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2064. }
  2065.  
  2066. set_flag_n((BYTE)temp_word);
  2067. set_flag_z((BYTE)temp_word);
  2068. set_flag_v(REGISTER_A, -REGISTER_E, (BYTE)temp_word);
  2069. Registers[REGISTER_A] = (BYTE)temp_word;
  2070. break;
  2071.  
  2072. case 0xD1: //SBC A-L
  2073. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
  2074.  
  2075. if ((Flags & FLAG_C) != 0) {
  2076. temp_word--;
  2077. }
  2078.  
  2079. if (temp_word >= 0x100) {
  2080. Flags = Flags | FLAG_C; //Set carry flag
  2081. }
  2082. else {
  2083. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2084. }
  2085.  
  2086. set_flag_n((BYTE)temp_word);
  2087. set_flag_z((BYTE)temp_word);
  2088. set_flag_v(REGISTER_A, -REGISTER_L, (BYTE)temp_word);
  2089. Registers[REGISTER_A] = (BYTE)temp_word;
  2090. break;
  2091.  
  2092. case 0xE1: //SBC A-H
  2093. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
  2094.  
  2095. if ((Flags & FLAG_C) != 0) {
  2096. temp_word--;
  2097. }
  2098.  
  2099. if (temp_word >= 0x100) {
  2100. Flags = Flags | FLAG_C; //Set carry flag
  2101. }
  2102. else {
  2103. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2104. }
  2105.  
  2106. set_flag_n((BYTE)temp_word);
  2107. set_flag_z((BYTE)temp_word);
  2108. set_flag_v(REGISTER_A, -REGISTER_H, (BYTE)temp_word);
  2109. Registers[REGISTER_A] = (BYTE)temp_word;
  2110. break;
  2111.  
  2112. case 0xF1: //SBC A-M
  2113. address = (WORD)Registers[REGISTER_H] << 8 + Registers[REGISTER_L];
  2114. Registers[REGISTER_M] = Memory[address];
  2115.  
  2116. temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
  2117.  
  2118. if ((Flags & FLAG_C) != 0) {
  2119. temp_word--;
  2120. }
  2121.  
  2122. if (temp_word >= 0x100) {
  2123. Flags = Flags | FLAG_C; //Set carry flag
  2124. }
  2125. else {
  2126. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2127. }
  2128.  
  2129. set_flag_n((BYTE)temp_word);
  2130. set_flag_z((BYTE)temp_word);
  2131. set_flag_v(REGISTER_A, -REGISTER_M, (BYTE)temp_word);
  2132. Registers[REGISTER_A] = (BYTE)temp_word;
  2133. break;
  2134.  
  2135. /*
  2136. * Opcode: IOR
  2137. * Description: Register bitwise inclusive or with Accumulator
  2138. * Flags: I - N V Z - - C
  2139. * Flags: - - T - T - - -
  2140. * Notes: None
  2141. */
  2142. case 0x93: //IOR A-B
  2143. Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_B];
  2144. set_flag_n(Registers[REGISTER_A]);
  2145. set_flag_z(Registers[REGISTER_A]);
  2146. break;
  2147.  
  2148. case 0xA3: //IOR A-C
  2149. Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_C];
  2150. set_flag_n(Registers[REGISTER_A]);
  2151. set_flag_z(Registers[REGISTER_A]);
  2152. break;
  2153.  
  2154. case 0xB3: //IOR A-D
  2155. Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_D];
  2156. set_flag_n(Registers[REGISTER_A]);
  2157. set_flag_z(Registers[REGISTER_A]);
  2158. break;
  2159.  
  2160. case 0xC3: //IOR A-E
  2161. Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_E];
  2162. set_flag_n(Registers[REGISTER_A]);
  2163. set_flag_z(Registers[REGISTER_A]);
  2164. break;
  2165.  
  2166. case 0xD3: //IOR A-L
  2167. Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_L];
  2168. set_flag_n(Registers[REGISTER_A]);
  2169. set_flag_z(Registers[REGISTER_A]);
  2170. break;
  2171.  
  2172. case 0xE3: //IOR A-H
  2173. Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_H];
  2174. set_flag_n(Registers[REGISTER_A]);
  2175. set_flag_z(Registers[REGISTER_A]);
  2176. break;
  2177.  
  2178. case 0xF3: //IOR A-M
  2179. Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_M];
  2180. set_flag_n(Registers[REGISTER_A]);
  2181. set_flag_z(Registers[REGISTER_A]);
  2182. break;
  2183.  
  2184. /*
  2185. * Opcode: XOR
  2186. * Description: Register bitwise exclusive or with Accumulator
  2187. * Flags: I - N V Z - - C
  2188. * Flags: - - T - T - - -
  2189. * Notes: None
  2190. */
  2191. case 0x95: //XOR A-B
  2192. Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_B];
  2193. set_flag_n(Registers[REGISTER_A]);
  2194. set_flag_z(Registers[REGISTER_A]);
  2195. break;
  2196.  
  2197. case 0xA5: //XOR A-C
  2198. Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_C];
  2199. set_flag_n(Registers[REGISTER_A]);
  2200. set_flag_z(Registers[REGISTER_A]);
  2201. break;
  2202.  
  2203. case 0xB5: //XOR A-D
  2204. Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_D];
  2205. set_flag_n(Registers[REGISTER_A]);
  2206. set_flag_z(Registers[REGISTER_A]);
  2207. break;
  2208.  
  2209. case 0xC5: //XOR A-E
  2210. Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_E];
  2211. set_flag_n(Registers[REGISTER_A]);
  2212. set_flag_z(Registers[REGISTER_A]);
  2213. break;
  2214.  
  2215. case 0xD5: //XOR A-L
  2216. Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_L];
  2217. set_flag_n(Registers[REGISTER_A]);
  2218. set_flag_z(Registers[REGISTER_A]);
  2219. break;
  2220.  
  2221. case 0xE5: //XOR A-H
  2222. Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_H];
  2223. set_flag_n(Registers[REGISTER_A]);
  2224. set_flag_z(Registers[REGISTER_A]);
  2225. break;
  2226.  
  2227. case 0xF5: //XOR A-M
  2228. Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_M];
  2229. set_flag_n(Registers[REGISTER_A]);
  2230. set_flag_z(Registers[REGISTER_A]);
  2231. break;
  2232.  
  2233. /*
  2234. * Opcode: NOT
  2235. * Description: Negate Memory or Accumulator
  2236. * Flags: I - N V Z - - C
  2237. * Flags: - - T - T - - T
  2238. * Notes: None
  2239. */
  2240. case 0x4A: //NOT ABSOLUTE ADDRESSING (abs)
  2241. HB = fetch();
  2242. LB = fetch();
  2243.  
  2244. if (address >= 0 && address < MEMORY_SIZE) {
  2245. Registers[REGISTER_A] = ~Memory[address];
  2246. }
  2247.  
  2248. if (Memory[address] >= 0x100) {
  2249. Flags = Flags | FLAG_C; //Set carry flag
  2250. }
  2251. else {
  2252. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2253. }
  2254.  
  2255. set_flag_z(Memory[address]);
  2256. set_flag_n(Memory[address]);
  2257. break;
  2258.  
  2259. case 0x5A: //NOT INEDXED ABSOLUTE ADDRESSING (abs, X)
  2260. address += IndexRegister;
  2261. HB = fetch();
  2262. LB = fetch();
  2263.  
  2264. if (address >= 0 && address < MEMORY_SIZE) {
  2265. Registers[REGISTER_A] = ~Memory[address];
  2266. }
  2267.  
  2268. if (Memory[address] >= 0x100) {
  2269. Flags = Flags | FLAG_C; //Set carry flag
  2270. }
  2271. else {
  2272. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2273. }
  2274.  
  2275. set_flag_z(Memory[address]);
  2276. set_flag_n(Memory[address]);
  2277. break;
  2278.  
  2279. /*
  2280. * Opcode: NOTA
  2281. * Description: Negate Memory or Accumulator
  2282. * Flags: I - N V Z - - C
  2283. * Flags: - - T - T - - T
  2284. * Notes: None
  2285. */
  2286. case 0x6A: //NOTA
  2287. Registers[REGISTER_A] = ~Registers[REGISTER_A];
  2288.  
  2289. if (Registers[REGISTER_A] >= 0x100) {
  2290. Flags = Flags | FLAG_C; //Set carry flag
  2291. }
  2292. else {
  2293. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2294. }
  2295.  
  2296. set_flag_z(Registers[REGISTER_A]);
  2297. set_flag_n(Registers[REGISTER_A]);
  2298. break;
  2299.  
  2300. /*
  2301. * Opcode: DEC
  2302. * Description: Decrement Memory or Accumulator
  2303. * Flags: I - N V Z - - C
  2304. * Flags: - - T - T - - -
  2305. * Notes: None
  2306. */
  2307. case 0x45: //DEC ABSOLUTE ADDRESSING (abs)
  2308. HB = fetch();
  2309. LB = fetch();
  2310. address += (WORD)((WORD)HB << 8) + LB;
  2311.  
  2312. if (address >= 0 && address < MEMORY_SIZE) {
  2313. Memory[address]--;
  2314. }
  2315.  
  2316. set_flag_n(Memory[address]);
  2317. set_flag_z(Memory[address]);
  2318. break;
  2319.  
  2320. case 0x55: //DEC INDEXED ABSOLUTE ADDRESSING (abs, X)
  2321. address += IndexRegister;
  2322. HB = fetch();
  2323. LB = fetch();
  2324. address += (WORD)((WORD)HB << 8) + LB;
  2325.  
  2326. if (address >= 0 && address < MEMORY_SIZE) {
  2327. Memory[address]--;
  2328. }
  2329.  
  2330. set_flag_n(Memory[address]);
  2331. set_flag_z(Memory[address]);
  2332. break;
  2333.  
  2334. /*
  2335. * Opcode: DECA
  2336. * Description: Decrement Memory or Accumulator
  2337. * Flags: I - N V Z - - C
  2338. * Flags: - - T - T - - -
  2339. * Notes: None
  2340. */
  2341. case 0x65: //DECA
  2342. Registers[REGISTER_A]--;
  2343. set_flag_z(Registers[REGISTER_A]);
  2344. set_flag_n(Registers[REGISTER_A]);
  2345. break;
  2346.  
  2347. /*
  2348. * Opcode: SAL
  2349. * Description: Arithmetic shift left Memory or Accumulator
  2350. * Flags: I - N V Z - - C
  2351. * Flags: - - T - T - - -
  2352. * Notes: None
  2353. */
  2354. case 0x48: //SAL ABSOLUTE ADDRESSING (abs)
  2355. HB = fetch();
  2356. LB = fetch();
  2357. address += (WORD)((WORD)HB << 8) + LB;
  2358.  
  2359. if (address >= 0 && address < MEMORY_SIZE) {
  2360. if ((Memory[address] & 0x01) == 0x01) {
  2361. Flags = Flags | FLAG_C;
  2362. }
  2363. else {
  2364. Flags = Flags & (0xFF - FLAG_C);
  2365. }
  2366.  
  2367. Memory[address] = (Memory[address] << 1) & 0x7F;
  2368.  
  2369. if ((Flags & FLAG_N) == FLAG_N) {
  2370. Memory[address] = Memory[address] | 0x80;
  2371. }
  2372. }
  2373.  
  2374. set_flag_z(Memory[address]);
  2375. set_flag_n(Memory[address]);
  2376. break;
  2377.  
  2378. case 0x58: //SAL INDEXED ABSOLUTE ADDRESSING (abs, X)
  2379. address += IndexRegister;
  2380. HB = fetch();
  2381. LB = fetch();
  2382. address += (WORD)((WORD)HB << 8) + LB;
  2383.  
  2384. if (address >= 0 && address < MEMORY_SIZE) {
  2385. if ((Memory[address] & 0x01) == 0x01) {
  2386. Flags = Flags | FLAG_C;
  2387. }
  2388. else {
  2389. Flags = Flags & (0xFF - FLAG_C);
  2390. }
  2391.  
  2392. Memory[address] = (Memory[address] << 1) & 0x7F;
  2393.  
  2394. if ((Flags & FLAG_N) == FLAG_N) {
  2395. Memory[address] = Memory[address] | 0x80;
  2396. }
  2397. }
  2398.  
  2399. set_flag_z(Memory[address]);
  2400. set_flag_n(Memory[address]);
  2401. break;
  2402.  
  2403. /*
  2404. * Opcode: SALA
  2405. * Description: Arithmetic shift left Memory or Accumulator
  2406. * Flags: I - N V Z - - C
  2407. * Flags: - - T - T - - T
  2408. * Notes: None
  2409. */
  2410. case 0x68: // SALA
  2411. if ((Registers[REGISTER_A] & 0x01) == 0x01) {
  2412. Flags = Flags | FLAG_C;
  2413. }
  2414. else {
  2415. Flags = Flags & (0xFF - FLAG_C);
  2416. }
  2417.  
  2418. Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0x7F;
  2419.  
  2420. if ((Flags & FLAG_N) == FLAG_N) {
  2421. Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
  2422. }
  2423.  
  2424. if (Registers[REGISTER_A] >= 0x100) {
  2425. Flags = Flags | FLAG_C; //Set carry flag
  2426. }
  2427. else {
  2428. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2429. }
  2430.  
  2431. set_flag_z(Registers[REGISTER_A]);
  2432. set_flag_n(Registers[REGISTER_A]);
  2433. break;
  2434.  
  2435. /*
  2436. * Opcode: ASR
  2437. * Description: Arithmetic shift right Memory or Accumulator
  2438. * Flags: I - N V Z - - C
  2439. * Flags: - - T - T - - -
  2440. * Notes: None
  2441. */
  2442. case 0x49: //ASR ABSOLUTE ADDRESSING (abs)
  2443. HB = fetch();
  2444. LB = fetch();
  2445. address += (WORD)((WORD)HB << 8) + LB;
  2446.  
  2447. if (address >= 0 && address < MEMORY_SIZE) {
  2448. if ((Memory[address] & 0x01) == 0x01) {
  2449. Flags = Flags | FLAG_C;
  2450. }
  2451. else {
  2452. Flags = Flags & (0xFF - FLAG_C);
  2453. }
  2454.  
  2455. Memory[address] = (Memory[address] >> 1) & 0x7F;
  2456.  
  2457. if ((Flags & FLAG_N) == FLAG_N) {
  2458. Memory[address] = Memory[address] | 0x80;
  2459. }
  2460. }
  2461. set_flag_n(Memory[address]);
  2462. set_flag_z(Memory[address]);
  2463. break;
  2464.  
  2465. case 0x59: //ASR INDEXED ABSOLUTE ADDRESSING (abs, X)
  2466. address += IndexRegister;
  2467. HB = fetch();
  2468. LB = fetch();
  2469. address += (WORD)((WORD)HB << 8) + LB;
  2470.  
  2471. if (address >= 0 && address < MEMORY_SIZE) {
  2472. if ((Memory[address] & 0x01) == 0x01) {
  2473. Flags = Flags | FLAG_C;
  2474. }
  2475. else {
  2476. Flags = Flags & (0xFF - FLAG_C);
  2477. }
  2478.  
  2479. Memory[address] = (Memory[address] >> 1) & 0x7F;
  2480.  
  2481. if ((Flags & FLAG_N) == FLAG_N) {
  2482. Memory[address] = Memory[address] | 0x80;
  2483. }
  2484. }
  2485. set_flag_n(Memory[address]);
  2486. set_flag_z(Memory[address]);
  2487. break;
  2488.  
  2489. /*
  2490. * Opcode: ASRA
  2491. * Description: Arithmetic shift right Memory or Accumulator
  2492. * Flags: I - N V Z - - C
  2493. * Flags: - - T - T - - T
  2494. * Notes: None
  2495. */
  2496. case 0x69: //ASRA
  2497. if ((Registers[REGISTER_A] & 0x01) == 0x01) {
  2498. Flags = Flags | FLAG_C;
  2499. }
  2500. else {
  2501. Flags = Flags & (0xFF - FLAG_C);
  2502. }
  2503.  
  2504. Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
  2505.  
  2506. if ((Flags & FLAG_N) == FLAG_N) {
  2507. Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
  2508. }
  2509.  
  2510. set_flag_n(Registers[REGISTER_A]);
  2511. set_flag_z(Registers[REGISTER_A]);
  2512. break;
  2513.  
  2514. //TST
  2515.  
  2516. //SWI
  2517. case 0x85:
  2518. Flags = Flags | FLAG_I;
  2519. if ((StackPointer >= 7) && (StackPointer < MEMORY_SIZE)) {
  2520. Memory[StackPointer] = Registers[REGISTER_A];
  2521. StackPointer--;
  2522.  
  2523. Memory[StackPointer] = Registers[REGISTER_B];
  2524. StackPointer--;
  2525.  
  2526. Memory[StackPointer] = Registers[REGISTER_C];
  2527. StackPointer--;
  2528.  
  2529. Memory[StackPointer] = Registers[REGISTER_D];
  2530. StackPointer--;
  2531.  
  2532. Memory[StackPointer] = Registers[REGISTER_E];
  2533. StackPointer--;
  2534.  
  2535. Memory[StackPointer] = Registers[REGISTER_L];
  2536. StackPointer--;
  2537.  
  2538. Memory[StackPointer] = Registers[REGISTER_H];
  2539. StackPointer--;
  2540.  
  2541. Memory[StackPointer] = Registers[REGISTER_M];
  2542. StackPointer--;
  2543.  
  2544. Memory[StackPointer] = Flags;
  2545. StackPointer--;
  2546. }
  2547. break;
  2548.  
  2549. //RTI
  2550. case 0x86:
  2551. if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE)) {
  2552. StackPointer++;
  2553. Flags = Memory[StackPointer];
  2554.  
  2555. StackPointer++;
  2556. Registers[REGISTER_M] = Memory[StackPointer];
  2557.  
  2558. StackPointer++;
  2559. Registers[REGISTER_H] = Memory[StackPointer];
  2560.  
  2561. StackPointer++;
  2562. Registers[REGISTER_L] = Memory[StackPointer];
  2563.  
  2564. StackPointer++;
  2565. Registers[REGISTER_E] = Memory[StackPointer];
  2566.  
  2567. StackPointer++;
  2568. Registers[REGISTER_D] = Memory[StackPointer];
  2569.  
  2570. StackPointer++;
  2571. Registers[REGISTER_C] = Memory[StackPointer];
  2572.  
  2573. StackPointer++;
  2574. Registers[REGISTER_B] = Memory[StackPointer];
  2575.  
  2576. StackPointer++;
  2577. Registers[REGISTER_A] = Memory[StackPointer];
  2578. }
  2579. break;
  2580.  
  2581. //ADI
  2582. case 0x25:
  2583. data = fetch();
  2584.  
  2585. temp_word = (WORD)data + (WORD)Registers[REGISTER_A];
  2586.  
  2587. if ((Flags & FLAG_C) != 0) {
  2588. temp_word++;
  2589. }
  2590.  
  2591. if (temp_word >= 0x100) {
  2592. Flags = Flags | FLAG_C; //Set carry flag
  2593. }
  2594. else {
  2595. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2596. }
  2597.  
  2598. set_flag_z((WORD)temp_word);
  2599. set_flag_n((WORD)temp_word);
  2600. set_flag_v((BYTE)data, REGISTER_A, (BYTE)temp_word);
  2601. data = (BYTE)temp_word;
  2602. break;
  2603.  
  2604. //SBI
  2605. case 0x26:
  2606. data = fetch();
  2607.  
  2608. temp_word = (WORD)data - (WORD)Registers[REGISTER_A];
  2609.  
  2610. if ((Flags & FLAG_C) != 0) {
  2611. temp_word--;
  2612. }
  2613.  
  2614. if (temp_word >= 0x100) {
  2615. Flags = Flags | FLAG_C; //Set carry flag
  2616. }
  2617. else {
  2618. Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2619. }
  2620.  
  2621. set_flag_z((WORD)temp_word);
  2622. set_flag_n((WORD)temp_word);
  2623. set_flag_v((BYTE)data, -REGISTER_A, (BYTE)temp_word);
  2624. data = (BYTE)temp_word;
  2625.  
  2626.  
  2627. //CPI
  2628. case 0x27:
  2629. param1 = Registers[REGISTER_A];
  2630. param2 = fetch();
  2631. temp_word = (WORD)param1 - (WORD)param2;
  2632. if (temp_word >= 0x100) {
  2633. Flags = Flags | FLAG_C;
  2634. }
  2635. else {
  2636. Flags = Flags & (0xFF - FLAG_C);
  2637. }
  2638. set_flag_n((BYTE)temp_word);
  2639. set_flag_z((BYTE)temp_word);
  2640. set_flag_v(param1, -param2, (BYTE)temp_word);
  2641. break;
  2642.  
  2643. //ANI
  2644. case 0x28:
  2645. Registers[REGISTER_A] = Registers[REGISTER_A] & fetch();
  2646. set_flag_n(Registers[REGISTER_A]);
  2647. set_flag_z(Registers[REGISTER_A]);
  2648. break;
  2649.  
  2650. //XRI
  2651. case 0x29:
  2652. Registers[REGISTER_A] = Registers[REGISTER_A] ^ fetch();
  2653. set_flag_n(Registers[REGISTER_A]);
  2654. set_flag_z(Registers[REGISTER_A]);
  2655. break;
  2656.  
  2657. //NOP
  2658. case 0x1D:
  2659. break;
  2660.  
  2661. //WAI
  2662. case 0x1E:
  2663. halt = true;
  2664. break;
  2665.  
  2666. /*-----------------------------------ROTATE----------------------------------*/
  2667. //RCL
  2668. case 0x47:
  2669. HB = fetch();
  2670. LB = fetch();
  2671. address += (WORD)((WORD)HB << 8) + LB;
  2672.  
  2673. saved_flags = Flags;
  2674.  
  2675. if ((Memory[address] & 0x80) == 0x80) {
  2676. Flags = Flags | FLAG_C;
  2677. }
  2678. else {
  2679. Flags = Flags & (0xFF - FLAG_C);
  2680. }
  2681.  
  2682. Memory[address] = (Memory[address] << 1) & 0xFE;
  2683.  
  2684. if ((saved_flags & FLAG_C) == FLAG_C) {
  2685. Memory[address] = Memory[address] | 0x01;
  2686. }
  2687.  
  2688. set_flag_n(Memory[address]);
  2689. set_flag_z(Memory[address]);
  2690. break;
  2691.  
  2692. case 0x57:
  2693. address += IndexRegister;
  2694. HB = fetch();
  2695. LB = fetch();
  2696. address += (WORD)((WORD)HB << 8) + LB;
  2697.  
  2698. saved_flags = Flags;
  2699.  
  2700. if ((Memory[address] & 0x80) == 0x80) {
  2701. Flags = Flags | FLAG_C;
  2702. }
  2703. else {
  2704. Flags = Flags & (0xFF - FLAG_C);
  2705. }
  2706.  
  2707. Memory[address] = (Memory[address] << 1) & 0xFE;
  2708.  
  2709. if ((saved_flags & FLAG_C) == FLAG_C) {
  2710. Memory[address] = Memory[address] | 0x01;
  2711. }
  2712.  
  2713. set_flag_n(Memory[address]);
  2714. set_flag_z(Memory[address]);
  2715. break;
  2716.  
  2717.  
  2718. /*
  2719. * Opcode: RCLA
  2720. * Description: Rotate left through carry Memory or Accumulator
  2721. * Flags: - - T - T - - T
  2722. * Notes: None
  2723. */
  2724. case 0x67: // RCLA
  2725. saved_flags = Flags;
  2726.  
  2727. if ((Registers[REGISTER_A] & 0x80) == 0x80) {
  2728. Flags = Flags | FLAG_C;
  2729. }
  2730. else {
  2731. Flags = Flags & (0xFF - FLAG_C);
  2732. }
  2733.  
  2734. Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
  2735.  
  2736. if ((saved_flags & FLAG_C) == FLAG_C) {
  2737. Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
  2738. }
  2739.  
  2740. set_flag_n(Registers[REGISTER_A]);
  2741. set_flag_z(Registers[REGISTER_A]);
  2742. break;
  2743.  
  2744.  
  2745. //RCR
  2746. case 0x46:
  2747. HB = fetch();
  2748. LB = fetch();
  2749. address += (WORD)((WORD)HB << 8) + LB;
  2750.  
  2751. saved_flags = Flags;
  2752.  
  2753. if ((Memory[address] & 0x80) == 0x80) {
  2754. Flags = Flags | FLAG_C;
  2755. }
  2756. else {
  2757. Flags = Flags & (0xFF - FLAG_C);
  2758. }
  2759.  
  2760. Memory[address] = (Memory[address] >> 1) & 0xFE;
  2761.  
  2762. if ((saved_flags & FLAG_C) == FLAG_C) {
  2763. Memory[address] = Memory[address] | 0x01;
  2764. }
  2765.  
  2766. set_flag_n(Memory[address]);
  2767. set_flag_z(Memory[address]);
  2768. break;
  2769.  
  2770. case 0x56:
  2771. address += IndexRegister;
  2772. HB = fetch();
  2773. LB = fetch();
  2774. address += (WORD)((WORD)HB << 8) + LB;
  2775.  
  2776. saved_flags = Flags;
  2777.  
  2778. if ((Memory[address] & 0x80) == 0x80) {
  2779. Flags = Flags | FLAG_C;
  2780. }
  2781. else {
  2782. Flags = Flags & (0xFF - FLAG_C);
  2783. }
  2784.  
  2785. Memory[address] = (Memory[address] >> 1) & 0xFE;
  2786.  
  2787. if ((saved_flags & FLAG_C) == FLAG_C) {
  2788. Memory[address] = Memory[address] | 0x01;
  2789. }
  2790.  
  2791. set_flag_n(Memory[address]);
  2792. set_flag_z(Memory[address]);
  2793. break;
  2794. /*
  2795. * Opcode: RCRA
  2796. * Description: Rotate right through carry Memory or Accumulator
  2797. * Flags: - - T - T - - T
  2798. * Notes: None
  2799. */
  2800. case 0x66: // RCRA
  2801. saved_flags = Flags;
  2802.  
  2803. if ((Registers[REGISTER_A] & 0x80) == 0x80) {
  2804. Flags = Flags | FLAG_C;
  2805. }
  2806. else {
  2807. Flags = Flags & (0xFF - FLAG_C);
  2808. }
  2809.  
  2810. Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0xFE;
  2811.  
  2812. if ((saved_flags & FLAG_C) == FLAG_C) {
  2813. Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
  2814. }
  2815.  
  2816. set_flag_n(Registers[REGISTER_A]);
  2817. set_flag_z(Registers[REGISTER_A]);
  2818. break;
  2819.  
  2820.  
  2821.  
  2822.  
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831. case 0x4B: //ROL
  2832. HB = fetch();
  2833. LB = fetch();
  2834. address += (WORD)((WORD)HB << 8) + LB;
  2835.  
  2836. if (address >= 0 && address < MEMORY_SIZE) {
  2837. if ((Memory[address] & 0x80) == 0x80)
  2838. {
  2839. Memory[address] = (Memory[address] << 1) + 0x01;
  2840. }
  2841. else {
  2842. Memory[address] = (Memory[address] << 1);
  2843. }
  2844. }
  2845.  
  2846. set_flag_z((BYTE)Memory[address]);
  2847. set_flag_n((BYTE)Memory[address]);
  2848. Memory[address] = Memory[address];
  2849. break;
  2850.  
  2851.  
  2852. case 0x5B:
  2853. address += IndexRegister;
  2854. HB = fetch();
  2855. LB = fetch();
  2856. address += (WORD)((WORD)HB << 8) + LB;
  2857.  
  2858. if (address >= 0 && address < MEMORY_SIZE)
  2859. {
  2860.  
  2861. if ((Memory[address] & 0x80) == 0x80) {
  2862. Memory[address] = (Memory[address] << 1) + 0x01;
  2863. }
  2864. else {
  2865. Memory[address] = (Memory[address] << 1);
  2866. }
  2867. }
  2868.  
  2869. set_flag_z((BYTE)Memory[address]);
  2870. set_flag_n((BYTE)Memory[address]);
  2871. Memory[address] = Memory[address];
  2872. break;
  2873.  
  2874. /*
  2875. * Opcode: ROLA
  2876. * Description: Rotate left through carry Memory or Accumulator
  2877. * Flags: - - T - T - - T
  2878. * Notes: None
  2879. */
  2880. case 0x6B:
  2881. if ((Registers[REGISTER_A] & 0x80) == 0x80) {
  2882. Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) + 0x01;
  2883. }
  2884. else {
  2885. Registers[REGISTER_A] = (Registers[REGISTER_A] << 1);
  2886. }
  2887.  
  2888. set_flag_n((BYTE)Registers[REGISTER_A]);
  2889. set_flag_z((BYTE)Registers[REGISTER_A]);
  2890. Registers[REGISTER_A] = (BYTE)Registers[REGISTER_A];
  2891. break;
  2892.  
  2893.  
  2894.  
  2895. case 0x4C: //ROR
  2896. HB = fetch();
  2897. LB = fetch();
  2898. address += (WORD)((WORD)HB << 8) + LB;
  2899.  
  2900. if (address >= 0 && address < MEMORY_SIZE)
  2901. {
  2902. if ((Memory[address] & 0x80) == 0x80)
  2903. {
  2904. Memory[address] = (Memory[address] >> 1) + 0x01;
  2905. }
  2906. else {
  2907. Memory[address] = (Memory[address] >> 1);
  2908. }
  2909. }
  2910. set_flag_z((BYTE)Memory[address]);
  2911. set_flag_n((BYTE)Memory[address]);
  2912. Memory[address] = Memory[address];
  2913.  
  2914. break;
  2915.  
  2916. case 0x5C:
  2917. address += IndexRegister;
  2918. HB = fetch();
  2919. LB = fetch();
  2920. address += (WORD)((WORD)HB << 8) + LB;
  2921.  
  2922. if (address >= 0 && address < MEMORY_SIZE)
  2923. {
  2924.  
  2925. if ((Memory[address] & 0x80) == 0x80)
  2926. {
  2927. Memory[address] = (Memory[address] >> 1) + 0x01;
  2928. }
  2929. else {
  2930. Memory[address] = (Memory[address] >> 1);
  2931. }
  2932.  
  2933. }
  2934. set_flag_z((BYTE)Memory[address]);
  2935. set_flag_n((BYTE)Memory[address]);
  2936. Memory[address] = Memory[address];
  2937.  
  2938. break;
  2939.  
  2940. /*
  2941. * Opcode: RORA
  2942. * Description: Rotate left through carry Memory or Accumulator
  2943. * Flags: - - T - T - - T
  2944. * Notes: None
  2945. */
  2946. case 0x6C:
  2947. if ((Registers[REGISTER_A] & 0x80) == 0x80) {
  2948. Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) + 0x01;
  2949. }
  2950. else {
  2951. Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1);
  2952. }
  2953.  
  2954. set_flag_n((BYTE)Registers[REGISTER_A]);
  2955. set_flag_z((BYTE)Registers[REGISTER_A]);
  2956. Registers[REGISTER_A] = (BYTE)Registers[REGISTER_A];
  2957. break;
  2958. }
  2959. }
  2960.  
  2961. /*---------------------------------------------------------------------------*/
  2962. void Group_2_Move(BYTE opcode) {
  2963. WORD address = 0;
  2964.  
  2965. BYTE source = opcode >> 4;
  2966. BYTE dest = opcode & 0x0F;
  2967. int destReg = 0;
  2968. int sourceReg = 0;
  2969. /*---------------------------------MOVE DEST---------------------------------*/
  2970. switch (dest) {
  2971. case 0x08:
  2972. destReg = REGISTER_A;
  2973. break;
  2974.  
  2975. case 0x09:
  2976. destReg = REGISTER_B;
  2977. break;
  2978.  
  2979. case 0x0A:
  2980. destReg = REGISTER_C;
  2981. break;
  2982.  
  2983. case 0x0B:
  2984. destReg = REGISTER_D;
  2985. break;
  2986.  
  2987. case 0x0C:
  2988. destReg = REGISTER_E;
  2989. break;
  2990.  
  2991. case 0x0D:
  2992. destReg = REGISTER_L;
  2993. break;
  2994.  
  2995. case 0x0E:
  2996. destReg = REGISTER_H;
  2997. break;
  2998.  
  2999. case 0x0F:
  3000. destReg = REGISTER_M;
  3001. break;
  3002. }
  3003.  
  3004. /*--------------------------------MOVE SOURCE--------------------------------*/
  3005. switch (source) {
  3006. case 0x07:
  3007. sourceReg = REGISTER_A;
  3008. break;
  3009.  
  3010. case 0x08:
  3011. sourceReg = REGISTER_B;
  3012. break;
  3013.  
  3014. case 0x09:
  3015. sourceReg = REGISTER_C;
  3016. break;
  3017.  
  3018. case 0x0A:
  3019. sourceReg = REGISTER_D;
  3020. break;
  3021.  
  3022. case 0x0B:
  3023. sourceReg = REGISTER_E;
  3024. break;
  3025.  
  3026. case 0x0C:
  3027. sourceReg = REGISTER_L;
  3028. break;
  3029.  
  3030. case 0x0D:
  3031. sourceReg = REGISTER_H;
  3032. break;
  3033.  
  3034. case 0x0E:
  3035. sourceReg = REGISTER_M;
  3036. break;
  3037. }
  3038.  
  3039. if (sourceReg == REGISTER_M) {
  3040. address = Registers[REGISTER_L];
  3041. address += (WORD)Registers[REGISTER_H] << 8;
  3042. Registers[destReg] = Memory[address];
  3043. }
  3044. Registers[destReg] = Registers[sourceReg];
  3045.  
  3046. if (destReg == REGISTER_M) {
  3047. address = Registers[REGISTER_L];
  3048. address += (WORD)Registers[REGISTER_H] << 8;
  3049. Memory[address] = Registers[REGISTER_M];
  3050. }
  3051. }
  3052.  
  3053. void execute(BYTE opcode) {
  3054. if (((opcode >= 0x78) && (opcode <= 0x7F)) ||
  3055. ((opcode >= 0x88) && (opcode <= 0x8F)) ||
  3056. ((opcode >= 0x98) && (opcode <= 0x9F)) ||
  3057. ((opcode >= 0xA8) && (opcode <= 0xAF)) ||
  3058. ((opcode >= 0xB8) && (opcode <= 0xBF)) ||
  3059. ((opcode >= 0xC8) && (opcode <= 0xCF)) ||
  3060. ((opcode >= 0xD8) && (opcode <= 0xDF)) ||
  3061. ((opcode >= 0xE8) && (opcode <= 0xEF))) {
  3062. Group_2_Move(opcode);
  3063. }
  3064. else {
  3065. Group_1(opcode);
  3066. }
  3067. }
  3068.  
  3069. void emulate() {
  3070. BYTE opcode;
  3071.  
  3072. ProgramCounter = 0;
  3073. halt = false;
  3074. memory_in_range = true;
  3075.  
  3076. int sanity = 0;
  3077.  
  3078. printf(" A B C D E L H X SP\n");
  3079.  
  3080. while ((!halt) && (memory_in_range)) {
  3081. printf("%04X ", ProgramCounter); // Print current address
  3082. opcode = fetch();
  3083. execute(opcode);
  3084.  
  3085. sanity++;
  3086. if (sanity > 500) halt = true;
  3087.  
  3088. printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
  3089.  
  3090. printf("%02X ", Registers[REGISTER_A]);
  3091. printf("%02X ", Registers[REGISTER_B]);
  3092. printf("%02X ", Registers[REGISTER_C]);
  3093. printf("%02X ", Registers[REGISTER_D]);
  3094. printf("%02X ", Registers[REGISTER_E]);
  3095. printf("%02X ", Registers[REGISTER_L]);
  3096. printf("%02X ", Registers[REGISTER_H]);
  3097. printf("%04X ", IndexRegister);
  3098. printf("%04X ", StackPointer); // Print Stack Pointer
  3099.  
  3100. if ((Flags & FLAG_I) == FLAG_I) {
  3101. printf("I=1 ");
  3102. }
  3103. else {
  3104. printf("I=0 ");
  3105. }
  3106. if ((Flags & FLAG_N) == FLAG_N) {
  3107. printf("N=1 ");
  3108. }
  3109. else {
  3110. printf("N=0 ");
  3111. }
  3112. if ((Flags & FLAG_V) == FLAG_V) {
  3113. printf("V=1 ");
  3114. }
  3115. else {
  3116. printf("V=0 ");
  3117. }
  3118. if ((Flags & FLAG_Z) == FLAG_Z) {
  3119. printf("Z=1 ");
  3120. }
  3121. else {
  3122. printf("Z=0 ");
  3123. }
  3124. if ((Flags & FLAG_C) == FLAG_C) {
  3125. printf("C=1 ");
  3126. }
  3127. else {
  3128. printf("C=0 ");
  3129. }
  3130.  
  3131. printf("\n"); // New line
  3132. }
  3133.  
  3134. printf("\n"); // New line
  3135. }
  3136.  
  3137. ////////////////////////////////////////////////////////////////////////////////
  3138. // Simulator/Emulator (End) //
  3139. ////////////////////////////////////////////////////////////////////////////////
  3140.  
  3141. void initialise_filenames() {
  3142. int i;
  3143.  
  3144. for (i = 0; i < MAX_FILENAME_SIZE; i++) {
  3145. hex_file[i] = '\0';
  3146. trc_file[i] = '\0';
  3147. }
  3148. }
  3149.  
  3150. int find_dot_position(char* filename) {
  3151. int dot_position;
  3152. int i;
  3153. char chr;
  3154.  
  3155. dot_position = 0;
  3156. i = 0;
  3157. chr = filename[i];
  3158.  
  3159. while (chr != '\0') {
  3160. if (chr == '.') {
  3161. dot_position = i;
  3162. }
  3163. i++;
  3164. chr = filename[i];
  3165. }
  3166.  
  3167. return (dot_position);
  3168. }
  3169.  
  3170. int find_end_position(char* filename) {
  3171. int end_position;
  3172. int i;
  3173. char chr;
  3174.  
  3175. end_position = 0;
  3176. i = 0;
  3177. chr = filename[i];
  3178.  
  3179. while (chr != '\0') {
  3180. end_position = i;
  3181. i++;
  3182. chr = filename[i];
  3183. }
  3184.  
  3185. return (end_position);
  3186. }
  3187.  
  3188. bool file_exists(char* filename) {
  3189. bool exists;
  3190. FILE* ifp;
  3191.  
  3192. exists = false;
  3193.  
  3194. if ((ifp = fopen(filename, "r")) != NULL) {
  3195. exists = true;
  3196.  
  3197. fclose(ifp);
  3198. }
  3199.  
  3200. return (exists);
  3201. }
  3202.  
  3203. void create_file(char* filename) {
  3204. FILE* ofp;
  3205.  
  3206. if ((ofp = fopen(filename, "w")) != NULL) {
  3207. fclose(ofp);
  3208. }
  3209. }
  3210.  
  3211. bool getline(FILE* fp, char* buffer) {
  3212. bool rc;
  3213. bool collect;
  3214. char c;
  3215. int i;
  3216.  
  3217. rc = false;
  3218. collect = true;
  3219.  
  3220. i = 0;
  3221. while (collect) {
  3222. c = getc(fp);
  3223.  
  3224. switch (c) {
  3225. case EOF:
  3226. if (i > 0) {
  3227. rc = true;
  3228. }
  3229. collect = false;
  3230. break;
  3231.  
  3232. case '\n':
  3233. if (i > 0) {
  3234. rc = true;
  3235. collect = false;
  3236. buffer[i] = '\0';
  3237. }
  3238. break;
  3239.  
  3240. default:
  3241. buffer[i] = c;
  3242. i++;
  3243. break;
  3244. }
  3245. }
  3246.  
  3247. return (rc);
  3248. }
  3249.  
  3250. void load_and_run(int args, _TCHAR** argv) {
  3251. char chr;
  3252. int ln;
  3253. int dot_position;
  3254. int end_position;
  3255. long i;
  3256. FILE* ifp;
  3257. long address;
  3258. long load_at;
  3259. int code;
  3260.  
  3261. // Prompt for the .hex file
  3262.  
  3263. printf("\n");
  3264. printf("Enter the hex filename (.hex): ");
  3265.  
  3266. if (args == 2) {
  3267. ln = 0;
  3268. chr = argv[1][ln];
  3269. while (chr != '\0') {
  3270. if (ln < MAX_FILENAME_SIZE) {
  3271. hex_file[ln] = chr;
  3272. trc_file[ln] = chr;
  3273. ln++;
  3274. }
  3275. chr = argv[1][ln];
  3276. }
  3277. }
  3278. else {
  3279. ln = 0;
  3280. chr = '\0';
  3281. while (chr != '\n') {
  3282. chr = getchar();
  3283.  
  3284. switch (chr) {
  3285. case '\n':
  3286. break;
  3287. default:
  3288. if (ln < MAX_FILENAME_SIZE) {
  3289. hex_file[ln] = chr;
  3290. trc_file[ln] = chr;
  3291. ln++;
  3292. }
  3293. break;
  3294. }
  3295. }
  3296.  
  3297. }
  3298. // Tidy up the file names
  3299.  
  3300. dot_position = find_dot_position(hex_file);
  3301. if (dot_position == 0) {
  3302. end_position = find_end_position(hex_file);
  3303.  
  3304. hex_file[end_position + 1] = '.';
  3305. hex_file[end_position + 2] = 'h';
  3306. hex_file[end_position + 3] = 'e';
  3307. hex_file[end_position + 4] = 'x';
  3308. hex_file[end_position + 5] = '\0';
  3309. }
  3310. else {
  3311. hex_file[dot_position + 0] = '.';
  3312. hex_file[dot_position + 1] = 'h';
  3313. hex_file[dot_position + 2] = 'e';
  3314. hex_file[dot_position + 3] = 'x';
  3315. hex_file[dot_position + 4] = '\0';
  3316. }
  3317.  
  3318. dot_position = find_dot_position(trc_file);
  3319. if (dot_position == 0) {
  3320. end_position = find_end_position(trc_file);
  3321.  
  3322. trc_file[end_position + 1] = '.';
  3323. trc_file[end_position + 2] = 't';
  3324. trc_file[end_position + 3] = 'r';
  3325. trc_file[end_position + 4] = 'c';
  3326. trc_file[end_position + 5] = '\0';
  3327. }
  3328. else {
  3329. trc_file[dot_position + 0] = '.';
  3330. trc_file[dot_position + 1] = 't';
  3331. trc_file[dot_position + 2] = 'r';
  3332. trc_file[dot_position + 3] = 'c';
  3333. trc_file[dot_position + 4] = '\0';
  3334. }
  3335.  
  3336. if (file_exists(hex_file)) {
  3337. // Clear Registers and Memory
  3338.  
  3339. Registers[REGISTER_A] = 0;
  3340. Registers[REGISTER_B] = 0;
  3341. Registers[REGISTER_C] = 0;
  3342. Registers[REGISTER_D] = 0;
  3343. Registers[REGISTER_E] = 0;
  3344. Registers[REGISTER_L] = 0;
  3345. Registers[REGISTER_H] = 0;
  3346. IndexRegister = 0;
  3347. Flags = 0;
  3348. ProgramCounter = 0;
  3349. StackPointer = 0;
  3350.  
  3351. for (i = 0; i < MEMORY_SIZE; i++) {
  3352. Memory[i] = 0x00;
  3353. }
  3354.  
  3355. // Load hex file
  3356.  
  3357. if ((ifp = fopen(hex_file, "r")) != NULL) {
  3358. printf("Loading file...\n\n");
  3359.  
  3360. load_at = 0;
  3361.  
  3362. while (getline(ifp, InputBuffer)) {
  3363. if (sscanf(InputBuffer, "L=%x", &address) == 1) {
  3364. load_at = address;
  3365. }
  3366. else if (sscanf(InputBuffer, "%x", &code) == 1) {
  3367. if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
  3368. Memory[load_at] = (BYTE)code;
  3369. }
  3370. load_at++;
  3371. }
  3372. else {
  3373. printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
  3374. }
  3375. }
  3376.  
  3377. fclose(ifp);
  3378. }
  3379.  
  3380. // Emulate
  3381.  
  3382. emulate();
  3383. }
  3384. else {
  3385. printf("\n");
  3386. printf("ERROR> Input file %s does not exist!\n", hex_file);
  3387. printf("\n");
  3388. }
  3389. }
  3390.  
  3391. void building(int args, _TCHAR** argv) {
  3392. char buffer[1024];
  3393. load_and_run(args, argv);
  3394. 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",
  3395. Memory[TEST_ADDRESS_1],
  3396. Memory[TEST_ADDRESS_2],
  3397. Memory[TEST_ADDRESS_3],
  3398. Memory[TEST_ADDRESS_4],
  3399. Memory[TEST_ADDRESS_5],
  3400. Memory[TEST_ADDRESS_6],
  3401. Memory[TEST_ADDRESS_7],
  3402. Memory[TEST_ADDRESS_8],
  3403. Memory[TEST_ADDRESS_9],
  3404. Memory[TEST_ADDRESS_10],
  3405. Memory[TEST_ADDRESS_11],
  3406. Memory[TEST_ADDRESS_12]
  3407. );
  3408. sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR*)&server_addr, sizeof(SOCKADDR));
  3409. }
  3410.  
  3411. void test_and_mark() {
  3412. char buffer[1024];
  3413. bool testing_complete;
  3414. int len = sizeof(SOCKADDR);
  3415. char chr;
  3416. int i;
  3417. int j;
  3418. bool end_of_program;
  3419. long address;
  3420. long load_at;
  3421. int code;
  3422. int mark;
  3423. int passed;
  3424.  
  3425. printf("\n");
  3426. printf("Automatic Testing and Marking\n");
  3427. printf("\n");
  3428.  
  3429. testing_complete = false;
  3430.  
  3431. sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
  3432. sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR*)&server_addr, sizeof(SOCKADDR));
  3433.  
  3434. while (!testing_complete) {
  3435. memset(buffer, '\0', sizeof(buffer));
  3436.  
  3437. if (recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (SOCKADDR*)&client_addr, &len) != SOCKET_ERROR) {
  3438. printf("Incoming Data: %s \n", buffer);
  3439.  
  3440. //if (strcmp(buffer, "Testing complete") == 1)
  3441. if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
  3442. testing_complete = true;
  3443. printf("Current mark = %d\n", mark, "%d\n/60");
  3444.  
  3445. }
  3446. else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
  3447. //testing_complete = true;
  3448. printf("Passed = %d\n", passed);
  3449.  
  3450. }
  3451. else if (strcmp(buffer, "Error") == 0) {
  3452. printf("ERROR> Testing abnormally terminated\n");
  3453. testing_complete = true;
  3454. }
  3455. else {
  3456.  
  3457. // Clear Registers and Memory
  3458. Registers[REGISTER_A] = 0;
  3459. Registers[REGISTER_B] = 0;
  3460. Registers[REGISTER_C] = 0;
  3461. Registers[REGISTER_D] = 0;
  3462. Registers[REGISTER_E] = 0;
  3463. Registers[REGISTER_L] = 0;
  3464. Registers[REGISTER_H] = 0;
  3465. IndexRegister = 0;
  3466. Flags = 0;
  3467. ProgramCounter = 0;
  3468. StackPointer = 0;
  3469. for (i = 0; i < MEMORY_SIZE; i++) {
  3470. Memory[i] = 0;
  3471. }
  3472.  
  3473. // Load hex file
  3474.  
  3475. i = 0;
  3476. j = 0;
  3477. load_at = 0;
  3478. end_of_program = false;
  3479. FILE* ofp;
  3480. fopen_s(&ofp, "branch.txt", "a");
  3481.  
  3482. while (!end_of_program) {
  3483. chr = buffer[i];
  3484. switch (chr) {
  3485. case '\0':
  3486. end_of_program = true;
  3487.  
  3488. case ',':
  3489. if (sscanf(InputBuffer, "L=%x", &address) == 1) {
  3490. load_at = address;
  3491. }
  3492. else if (sscanf(InputBuffer, "%x", &code) == 1) {
  3493. if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
  3494. Memory[load_at] = (BYTE)code;
  3495. fprintf(ofp, "%02X\n", (BYTE)code);
  3496. }
  3497. load_at++;
  3498. }
  3499. else {
  3500. printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
  3501. }
  3502. j = 0;
  3503. break;
  3504.  
  3505. default:
  3506. InputBuffer[j] = chr;
  3507. j++;
  3508. break;
  3509. }
  3510. i++;
  3511. }
  3512. fclose(ofp);
  3513. // Emulate
  3514.  
  3515. if (load_at > 1) {
  3516. emulate();
  3517. // Send and store results
  3518. sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
  3519. Memory[TEST_ADDRESS_1],
  3520. Memory[TEST_ADDRESS_2],
  3521. Memory[TEST_ADDRESS_3],
  3522. Memory[TEST_ADDRESS_4],
  3523. Memory[TEST_ADDRESS_5],
  3524. Memory[TEST_ADDRESS_6],
  3525. Memory[TEST_ADDRESS_7],
  3526. Memory[TEST_ADDRESS_8],
  3527. Memory[TEST_ADDRESS_9],
  3528. Memory[TEST_ADDRESS_10],
  3529. Memory[TEST_ADDRESS_11],
  3530. Memory[TEST_ADDRESS_12]
  3531. );
  3532. sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR*)&server_addr, sizeof(SOCKADDR));
  3533. }
  3534. }
  3535. }
  3536. }
  3537. }
  3538.  
  3539. int _tmain(int argc, _TCHAR* argv[]) {
  3540. char chr;
  3541. char dummy;
  3542.  
  3543. printf("\n");
  3544. printf("Microprocessor Emulator\n");
  3545. printf("UWE Computer and Network Systems Assignment 1\n");
  3546. printf("\n");
  3547.  
  3548. initialise_filenames();
  3549.  
  3550. if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return (0);
  3551.  
  3552. sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
  3553. if (!sock) {
  3554. // Creation failed!
  3555. }
  3556.  
  3557. memset(&server_addr, 0, sizeof(SOCKADDR_IN));
  3558. server_addr.sin_family = AF_INET;
  3559. server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
  3560. server_addr.sin_port = htons(PORT_SERVER);
  3561.  
  3562. memset(&client_addr, 0, sizeof(SOCKADDR_IN));
  3563. client_addr.sin_family = AF_INET;
  3564. client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
  3565. client_addr.sin_port = htons(PORT_CLIENT);
  3566.  
  3567. chr = '\0';
  3568. while ((chr != 'e') && (chr != 'E')) {
  3569. printf("\n");
  3570. printf("Please select option\n");
  3571. printf("L - Load and run a hex file\n");
  3572. printf("T - Have the server test and mark your emulator\n");
  3573. printf("E - Exit\n");
  3574. if (argc == 2) {
  3575. building(argc, argv);
  3576. exit(0);
  3577. }
  3578. printf("Enter option: ");
  3579. chr = getchar();
  3580. if (chr != 0x0A) {
  3581. dummy = getchar(); // read in the <CR>
  3582. }
  3583. printf("\n");
  3584.  
  3585. switch (chr) {
  3586. case 'L':
  3587. case 'l':
  3588. load_and_run(argc, argv);
  3589. break;
  3590.  
  3591. case 'T':
  3592. case 't':
  3593. test_and_mark();
  3594. break;
  3595.  
  3596. default:
  3597. break;
  3598. }
  3599. }
  3600.  
  3601. closesocket(sock);
  3602. WSACleanup();
  3603.  
  3604. return 0;
  3605. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement