#include <assert.h> #define NOTUSED FALSE #define return_or_continue_or_break "break" /* INP_A is inputs, INP B is switches */ CINESTATE opINP_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opINP_A_AA (%02x) */\n", cur_tabs, opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); fprintf(codefile, "%scmp_old = flag_C = acc_a0 = register_A;\n", cur_tabs); if ((opcode&0x0F) == 1) { fprintf(codefile, "%sregister_A = cmp_new = get_io_moveright();\n", cur_tabs); } else if ((opcode&0x0F) == 2) { fprintf(codefile, "%sregister_A = cmp_new = get_io_moveleft();\n", cur_tabs); } else if ((opcode&0x0F) == 3) { fprintf(codefile, "%sregister_A = cmp_new = get_io_moveup();\n", cur_tabs); } else if ((opcode&0x0F) == 4) { fprintf(codefile, "%sregister_A = cmp_new = get_io_movedown();\n", cur_tabs); } else if ((opcode&0x0F) == 5) { fprintf(codefile, "%sregister_A = cmp_new = get_io_fire();\n", cur_tabs); } else if ((opcode&0x0F) == 6) { fprintf(codefile, "%sregister_A = cmp_new = get_io_shields();\n", cur_tabs); } else if ((opcode&0x0F) == 7) { fprintf(codefile, "%sregister_A = cmp_new = get_io_startbutton();\n", cur_tabs); } else { fprintf(codefile, "%sregister_A = cmp_new = get_io_bit(0x%01x);\n", cur_tabs, opcode & 0x0F); } register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opINP_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opINP_B_AA (%02x) */\n", cur_tabs, opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); fprintf(codefile, "%s%s", cur_tabs, "flag_C = acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = register_B; /* save old accB */\n"); if ((opcode&7) == 7 /*docs say 7 on input, 5 on output? */) { fprintf(codefile, "%sregister_B = cmp_new = get_coin_state(); /* apparently not used in tailgunner??? */\n", cur_tabs); } else if ((opcode&7) == 0) { fprintf(codefile, "%sregister_B = cmp_new = get_quarters_per_game(); /* 1 => 1q/game, 0 => 2q/game */ \n", cur_tabs); } else if ((opcode&7) == 1) { fprintf(codefile, "%sregister_B = cmp_new = get_shield_bit2();\n", cur_tabs); } else if ((opcode&7) == 4) { fprintf(codefile, "%sregister_B = cmp_new = get_shield_bit1();\n", cur_tabs); } else if ((opcode&7) == 5) { fprintf(codefile, "%sregister_B = cmp_new = get_shield_bit0();\n", cur_tabs); } else { fprintf(codefile, "%sregister_B = cmp_new = get_switch_bit(0x%01x);\n", cur_tabs, opcode&7); } register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opOUTsnd_A (int opcode) { internal_test(opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); if (disp_opcodes) fprintf(codefile, "%s/* opOUTsnd_A (%02x) */\n", cur_tabs, opcode); if (register_A != 0xDEADBEEFUL) { if ((opcode & 0x07) == 5) { fprintf(codefile, "%sreset_coin_counter(%0d);\n", cur_tabs, register_A&1); } else if ((opcode & 0x07) == 3) { fprintf(codefile, "%sset_sound_data(%0d);\n", cur_tabs, register_A&1); } else if ((opcode & 0x07) == 0) { fprintf(codefile, "%sset_sound_addr_A(%0d);\n", cur_tabs, register_A&1); } else if ((opcode & 0x07) == 1) { fprintf(codefile, "%sset_sound_addr_B(%0d);\n", cur_tabs, register_A&1); } else if ((opcode & 0x07) == 2) { fprintf(codefile, "%sset_sound_addr_C(%0d);\n", cur_tabs, register_A&1); } else if ((opcode & 0x07) == 4) { if (register_A&1) { fprintf(codefile, "%sstrobe_sound_on();\n", cur_tabs); } else { fprintf(codefile, "%sstrobe_sound_off();\n", cur_tabs); } } else { fprintf(codefile, "%sput_io_bit(/*bitno*/0x%01x, /*set or clr*/0x%01x);\n", cur_tabs, opcode & 0x07, register_A&1); } } else { if ((opcode & 0x07) == 5) { fprintf(codefile, "%s%s", cur_tabs, "reset_coin_counter(register_A&1);\n"); } else if ((opcode & 0x07) == 3) { fprintf(codefile, "%sset_sound_data(register_A&1);\n", cur_tabs); } else if ((opcode & 0x07) == 0) { fprintf(codefile, "%sset_sound_addr_A(register_A&1);\n", cur_tabs); } else if ((opcode & 0x07) == 1) { fprintf(codefile, "%sset_sound_addr_B(register_A&1);\n", cur_tabs); } else if ((opcode & 0x07) == 2) { fprintf(codefile, "%sset_sound_addr_C(register_A&1);\n", cur_tabs); } else if ((opcode & 0x07) == 4) { fprintf(codefile, "%sif ((register_A&1) != 0) strobe_sound_on(); else strobe_sound_off();\n", cur_tabs); } else { fprintf(codefile, "%sput_io_bit(/*bitno*/0x%01x, /*set or clr*/register_A&1);\n", cur_tabs, opcode & 0x07); } } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opOUTbi_A_A (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opOUTbi_A_A (%02x) */\n", cur_tabs, opcode); if ((opcode & 0x07) != 6) { return state = opOUTsnd_A (opcode); /* Macro expand */ } if (register_A != 0xDEADBEEFUL) { fprintf(codefile, "%svgColour = 0x%02x;\n", cur_tabs, ((register_A & 0x01) != 0 ? 0x0f: 0x07)); } else { fprintf(codefile, "%s%s", cur_tabs, "vgColour = (register_A & 0x01) != 0 ? 0x0f: 0x07;\n"); } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opOUT16_A_A (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opOUT16_A_A (%02x) */\n", cur_tabs, opcode); if ((opcode & 0x07) != 6) return opOUTsnd_A (opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); fprintf(codefile, "%s%s", cur_tabs, "if ((register_A & 0x1) != 1)\n"); fprintf(codefile, "%s%s", cur_tabs, "{\n"); fprintf(codefile, "%s%s", cur_tabs, " vgColour = FromX & 0x0F;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, " if (!vgColour)\n"); fprintf(codefile, "%s%s", cur_tabs, " vgColour = 1;\n"); fprintf(codefile, "%s%s", cur_tabs, "}\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opOUT64_A_A (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opOUT64_A_A (%02x) */\n", cur_tabs, opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opOUTWW_A_A (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opOUTWW_A_A (%02x) */\n", cur_tabs, opcode); if ((opcode & 0x07) != 6) return opOUTsnd_A (opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); fprintf(codefile, "%s%s", cur_tabs, "if ((register_A & 0x1) == 1) {\n"); push_indent(" "); fprintf(codefile, "%s%s", cur_tabs, "if (!(~FromX & 0x0FFF)) {/* black */\n"); fprintf(codefile, "%s%s", cur_tabs, " vgColour = 0;\n"); fprintf(codefile, "%s%s", cur_tabs, "} else { /* non-black */\n"); fprintf(codefile, "%s%s", cur_tabs, " if ((~FromX & 0x0FFF) & 0x0888) /* bright */ vgColour = (((~FromX & 0x0FFF) >> 1) & 0x04) | (((~FromX & 0x0FFF) >> 6) & 0x02) | (((~FromX & 0x0FFF) >> 11) & 0x01) | 0x08;\n"); fprintf(codefile, "%s%s", cur_tabs, " else if ((~FromX & 0x0FFF) & 0x0444) /* dim bits */ vgColour = ((~FromX & 0x0FFF) & 0x04) | (((~FromX & 0x0FFF) >> 5) & 0x02) | (((~FromX & 0x0FFF) >> 10) & 0x01);\n"); fprintf(codefile, "%s%s", cur_tabs, "}\n"); pop_indent(" "); fprintf(codefile, "%s%s", cur_tabs, "} /* colour change? == 1 */\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opOUTsnd_B (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opOUTsnd_B (%02x) */\n", cur_tabs, opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opOUTbi_B_BB (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opOUTbi_B_BB (%02x) */\n", cur_tabs, opcode); if ((opcode & 0x07) != 0x06) return opOUTsnd_B (opcode); fprintf(codefile, "%s%s", cur_tabs, "vgColour = ((register_B & 0x01) << 3) | 0x07;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opOUT16_B_BB (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opOUT16_B_BB (%02x) */\n", cur_tabs, opcode); if ((opcode & 0x07) - 0x06) return opOUTsnd_B (opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); fprintf(codefile, "%s%s", cur_tabs, "if ((register_B & 0xFF) != 1)\n"); fprintf(codefile, "%s%s", cur_tabs, "{\n"); fprintf(codefile, "%s%s", cur_tabs, " vgColour = FromX & 0x0F;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, " if (!vgColour)\n"); fprintf(codefile, "%s%s", cur_tabs, " vgColour = 1;\n"); fprintf(codefile, "%s%s", cur_tabs, "}\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opOUT64_B_BB (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opOUT64_B_BB (%02x) */\n", cur_tabs, opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opOUTWW_B_BB (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opOUTWW_B_BB (%02x) */\n", cur_tabs, opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opLDAimm_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDAimm_A_AA (%02x) */\n", cur_tabs, opcode); if (opcode == 0 /* CLR */) { fprintf(codefile, "%s%s", cur_tabs, "cmp_old = flag_C = acc_a0 = register_A;\n"); fprintf(codefile, "%sregister_A = cmp_new = 0;\n", cur_tabs); register_A = 0; } else if (ImmOpd != 0xDEADBEEFUL) { /* Here is the first major bug - I was only assigning register_A, I forgot about all the other crud. MUST CHECK the other instructions for similar loss of side effects! */ fprintf(codefile, "%s%s", cur_tabs, "cmp_old = flag_C = acc_a0 = register_A;\n"); fprintf(codefile, "%sregister_A = cmp_new = 0x%04x;\n", cur_tabs, register_A = ImmOpd); } else { fprintf(codefile, "%s%s", cur_tabs, "cmp_old = flag_C = acc_a0 = register_A;\n"); fprintf(codefile, "%sregister_A = cmp_new = 0x%04x; /* pick up immediate value */\n", cur_tabs, register_A = ((opcode & 0x0F) << 8)); } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA; /* swap state and end opcode */\n"); return state = state_AA; } CINESTATE opLDAimm_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDAimm_B_AA (%02x) */\n", cur_tabs, opcode); if (opcode == 0 /* CLR */) { fprintf(codefile, "%s%s", cur_tabs, "flag_C = acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = register_B; /* step back cmp flag */\n"); fprintf(codefile, "%sregister_B = cmp_new = 0;\n", cur_tabs); register_B = 0; } else if (ImmOpd != 0xDEADBEEFUL) { /* Same bug, fixed */ fprintf(codefile, "%s%s", cur_tabs, "flag_C = acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = register_B; /* step back cmp flag */\n"); fprintf(codefile, "%sregister_B = cmp_new = 0x%04x;\n", cur_tabs, register_B = ImmOpd); } else { fprintf(codefile, "%s%s", cur_tabs, "flag_C = acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = register_B; /* step back cmp flag */\n"); fprintf(codefile, "%sregister_B = cmp_new = 0x%04x; /* pick up immediate value */\n", cur_tabs, register_B = ((opcode & 0x0F) << 8)); } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLDAdir_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDAdir_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = flag_C = acc_a0 = register_A; /* store old acc */\n"); if (register_P != 0xDEADBEEFUL) { fprintf(codefile, "%sregister_A = cmp_new = ram[register_I = 0x%02x]; /* set I register */\n", cur_tabs, register_I = (register_P << 4) + (opcode & 0x0f)); } else { fprintf(codefile, "%sregister_A = cmp_new = ram[register_I = (register_P << 4) + 0x%02x]; /* set I register */\n", cur_tabs, (opcode & 0x0f)); register_I = 0xDEADBEEFUL; } register_A = 0xDEADBEEFUL; fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLDAdir_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDAdir_B_AA (%02x) */\n", cur_tabs, opcode); /* remember to finish compressing the source code */ fprintf(codefile, "%sflag_C = acc_a0 = register_A;\n", cur_tabs); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = register_B; /* store old acc */\n"); if (register_P != 0xDEADBEEFUL) { fprintf(codefile, "%sregister_B = cmp_new = ram[register_I = (register_P << 4) + 0x%02x]; /* new acc value */\n", cur_tabs, opcode & 0x0F); register_I = ((register_P << 4) + (opcode & 0x0F)); } else { fprintf(codefile, "%sregister_B = cmp_new = ram[register_I = (register_P << 4) + 0x%02x]; /* new acc value */\n", cur_tabs, opcode & 0x0F); register_I = 0xDEADBEEFUL; } register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLDAirg_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDAirg_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%scmp_old = flag_C = acc_a0 = register_A;\n", cur_tabs); /* BUG FIX - add cmp_new */ fprintf(codefile, "%s%s", cur_tabs, "register_A = cmp_new = ram[register_I];\n"); register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLDAirg_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDAirg_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "flag_C = acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = register_B;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B = cmp_new = ram[register_I];\n"); register_B = 0xDEADBEEFUL; fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opADDimm_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opADDimm_A_AA (%02x) */\n", cur_tabs, opcode); if (register_A != 0xDEADBEEFUL) { register_A += (opcode & 0x0f); fprintf(codefile, "%scmp_new = 0x%01x; cmp_old = acc_a0 = register_A; ", cur_tabs, opcode&0x0f); if ((register_A & 0xf000) != 0) { /* Carry */ fprintf(codefile, "register_A = 0x%03x; flag_C = 0x1000;\n", register_A & 0xfff); } else { /* No carry */ fprintf(codefile, "register_A = flag_C = 0x%04x;\n", register_A); } } else { fprintf(codefile, "%sregister_A = (flag_C = ((cmp_old = acc_a0 = register_A) + (cmp_new = 0x%01x))) & 0xFFF; /* add values, save carry */\n", cur_tabs, (opcode & 0x0f)); } fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opADDimm_B_AA (int opcode) { internal_test(opcode); /* Still to optimise this one as above */ if (disp_opcodes) fprintf(codefile, "%s/* opADDimm_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sacc_a0 = register_A; /* save old accA bit0 */\n", cur_tabs); fprintf(codefile, "%scmp_old = register_B; /* store old acc for later */\n", cur_tabs); fprintf(codefile, "%sregister_B = (flag_C = (register_B + (cmp_new = 0x%02x))) & 0xFFF; /* add values */\n", cur_tabs, (opcode & 0x0F)); register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opADDimmX_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opADDimmX_A_AA (%02x) */\n", cur_tabs, opcode); if (ImmOpd == 0xDEADBEEFUL) { ImmOpd = rom[register_PC+1]; /* Why wasn't this picked up in the opcode decoding? */ } if (register_A != 0xDEADBEEFUL) { fprintf(codefile, "%scmp_old = register_A; cmp_new = 0x%02x;\n", cur_tabs, ImmOpd); /* BUG FIX */ if (((ImmOpd + register_A) >> 12) != 0) { fprintf(codefile, "%sregister_A = (flag_C = (acc_a0 = 0x%04x)) & 0xFFF;\n", cur_tabs, register_A = (ImmOpd+register_A)); register_A &= 0xFFF; } else { fprintf(codefile, "%sregister_A = flag_C = acc_a0 = 0x%04x;\n", cur_tabs, register_A = (ImmOpd+register_A)); } } else { fprintf(codefile, "%sregister_A = (flag_C = ((acc_a0 = cmp_old = register_A) + (cmp_new = 0x%04x))) & 0xFFF; /* add values */\n", cur_tabs, ImmOpd); register_A = 0xDEADBEEFUL; /* IS THIS BRACKETING CORRECT? */ } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opADDimmX_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opADDimmX_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%scmp_old = register_B; acc_a0 = register_A; /* save old accA bit0 */\n", cur_tabs); if (ImmOpd == 0xDEADBEEFUL) { ImmOpd = rom[register_PC+1]; /* Why wasn't this picked up in the opcode decoding? */ } if (register_B != 0xDEADBEEFUL) { fprintf(codefile, "%scmp_new = 0x%02x;\n", cur_tabs, ImmOpd); /* I assume the bug fix above is needed here too? */ if (((ImmOpd + register_B) >> 12) != 0) { fprintf(codefile, "%sregister_B = (flag_C = 0x%04x) & 0xFFF; cmp_new = 0x%02x\n", cur_tabs, register_B = (ImmOpd+register_B), ImmOpd); register_B &= 0xFFF; } else { fprintf(codefile, "%sregister_B = flag_C = 0x%04x; cmp_new = 0x%02x; /* No carry */\n", cur_tabs, register_B = (ImmOpd+register_B), ImmOpd); } } else { fprintf(codefile, "%sregister_B = (flag_C = (register_B + (cmp_new = 0x%02x))) & 0xFFF; /* add values */\n", cur_tabs, ImmOpd); /* Is this bracketing correct? */ register_B = 0xDEADBEEFUL; } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opADDdir_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opADDdir_A_AA (%02x) */\n", cur_tabs, opcode); if (register_P != 0xDEADBEEFUL) { fprintf(codefile, "%sregister_A = (flag_C = ((cmp_old = acc_a0 = register_A) + (cmp_new = ram[register_I = 0x%02x]))) & 0xFFF; /* do acc operation */\n", cur_tabs, register_I = (register_P << 4) + (opcode & 0x0F)); } else { fprintf(codefile, "%sregister_A = (flag_C = ((cmp_old = acc_a0 = register_A) + (cmp_new = ram[register_I = (register_P << 4) + 0x%01x]))) & 0xFFF; /* do acc operation */\n", cur_tabs, (opcode & 0x0F)); register_I = 0xDEADBEEFUL; } register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opADDdir_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opADDdir_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "acc_a0 = register_A; /* store old acc value */\n"); if (register_P != 0xDEADBEEFUL) { fprintf(codefile, "%sregister_B = (flag_C = ((cmp_old = register_B) + (cmp_new = ram[register_I = 0x%02x]))) & 0xFFF; /* do acc operation */\n", cur_tabs, register_I = ((register_P << 4) + (opcode & 0x0F))); } else { fprintf(codefile, "%sregister_B = (flag_C = ((cmp_old = register_B) + (cmp_new = ram[register_I = (register_P << 4) + 0x%02x]))) & 0xFFF; /* do acc operation */\n", cur_tabs, (opcode & 0x0F)); register_I = 0xDEADBEEFUL; } register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opAWDirg_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opAWDirg_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = acc_a0 = register_A;\n"); if (register_I != 0xDEADBEEFUL) { fprintf(codefile, "%sregister_A = (flag_C = (register_A + (cmp_new = ram[0x%02x]))) & 0xFFF;\n", cur_tabs, register_I); } else { fprintf(codefile, "%s%s", cur_tabs, "register_A = (flag_C = (register_A + (cmp_new = ram[register_I]))) & 0xFFF;\n"); } fprintf(codefile, "%s%s", cur_tabs, "set_watchdog();\n"); register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opAWDirg_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opAWDirg_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = register_B;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B = (flag_C = (register_B + (cmp_new = ram[register_I]))) & 0xFFF;\n"); register_B = 0xDEADBEEFUL; /* does this one also need to set the watchdog??? - original version of code didn't, and I have added it without checking too closely... */ fprintf(codefile, "%s%s", cur_tabs, "set_watchdog();\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opSUBimm_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opSUBimm_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = acc_a0 = register_A;\n"); fprintf(codefile, "%sregister_A = (flag_C = (register_A + (((cmp_new = 0x%01x) ^ 0xFFF) + 1))) & 0xFFF; /* 1's-comp add */\n", cur_tabs, (opcode & 0x0F)); register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opSUBimm_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opSUBimm_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sacc_a0 = register_A;\n", cur_tabs); fprintf(codefile, "%sregister_B = (flag_C = ((cmp_old = register_B) + ((cmp_new = 0x%01x) ^ 0xFFF) + 1)) & 0xFFF; /* 1's-comp add */\n", cur_tabs, (opcode & 0x0F)); register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opSUBimmX_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opSUBimmX_A_AA (%02x) */\n", cur_tabs, opcode); /* Question: is this the byte FOLLOWING the instruction? */ if (ImmOpd == 0xDEADBEEFUL) { ImmOpd = rom[register_PC+1]; /* Why wasn't this picked up in the opcode decoding? */ } fprintf(codefile, "%scmp_old = acc_a0 = register_A; /* back up regA */\n", cur_tabs); fprintf(codefile, "%sregister_A = (flag_C = (register_A + (((cmp_new = 0x%02x) ^ 0xFFF) + 1))) & 0xFFF; /* add */\n", cur_tabs, ImmOpd); register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opSUBimmX_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opSUBimmX_B_AA (%02x) */\n", cur_tabs, opcode); if (ImmOpd == 0xDEADBEEFUL) { ImmOpd = rom[register_PC+1]; /* Why wasn't this picked up in the opcode decoding? */ } fprintf(codefile, "%sacc_a0 = register_A;\n", cur_tabs); fprintf(codefile, "%sregister_B = (flag_C = ((cmp_old = register_B) + (((cmp_new = 0x%02x) ^ 0xFFF) + 1))) & 0xFFF; /* add */\n", cur_tabs, ImmOpd); register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opSUBdir_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opSUBdir_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = acc_a0 = register_A;\n"); if (register_P != 0xDEADBEEFUL) { fprintf(codefile, "%sregister_A = (flag_C = (register_A + ((cmp_new = ram[register_I = 0x%02x]) ^ 0xFFF) + 1)) & 0xFFF; /* set regI addr */\n", cur_tabs, register_I = (register_P << 4) + (opcode & 0x0F)); } else { fprintf(codefile, "%sregister_A = (flag_C = (register_A + ((cmp_new = ram[register_I = (register_P << 4) + 0x%01x]) ^ 0xFFF) + 1)) & 0xFFF; /* set regI addr */\n", cur_tabs, (opcode & 0x0F)); register_I = 0xDEADBEEFUL; } register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opSUBdir_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opSUBdir_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sacc_a0 = register_A;\n", cur_tabs); fprintf(codefile, "%sregister_B = (flag_C = ((cmp_old = register_B) + ((cmp_new = ram[register_I = (register_P << 4) + 0x%02x]) ^ 0xFFF) + 1)) & 0xFFF; /* ones compliment */\n", cur_tabs, (opcode & 0x0F)); register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opSUBirg_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opSUBirg_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "register_A = (flag_C = ((cmp_old = acc_a0 = register_A) + ((cmp_new = ram[register_I]) ^ 0xFFF) + 1)) & 0xFFF; /* ones compliment */\n"); register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opSUBirg_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opSUBirg_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sacc_a0 = register_A;\n", cur_tabs); fprintf(codefile, "%s%s", cur_tabs, "register_B = (flag_C = ((cmp_old = register_B) + ((cmp_new = ram[register_I]) ^ 0xFFF) + 1)) & 0xFFF; /* ones compliment */\n"); register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opCMPdir_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opCMPdir_A_AA (%02x) */\n", cur_tabs, opcode); if (comments) { fprintf(codefile, "%s%s", cur_tabs, "/*\n"); fprintf(codefile, "%s%s", cur_tabs, " * compare direct mode; don't modify regs, just set carry flag or not.\n"); fprintf(codefile, "%s%s", cur_tabs, " */\n"); } fprintf(codefile, "%scmp_old = acc_a0 = register_A; /* backup old acc */\n", cur_tabs); if (register_P == 0xDEADBEEFUL) { fprintf(codefile, "%sflag_C = (((cmp_new = ram[register_I = (register_P << 4) + 0x%01x]) ^ 0xFFF) + 1 + register_A);\n", cur_tabs, (opcode & 0x0F)); register_I = 0xDEADBEEFUL; } else { #ifdef NEVER fprintf(codefile, "%sif (register_P != 0x%01x) ERROR(\"register_P is faulty\\n\"); /* Optimisation assertion test */\n", cur_tabs, register_P); #endif fprintf(codefile, "%sflag_C = (((cmp_new = ram[register_I = 0x%02x]) ^ 0xFFF) + 1 + register_A);\n", cur_tabs, register_I = ((register_P << 4) + (opcode & 0x0f))); } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opCMPdir_B_AA (int opcode) { internal_test(opcode); /* SEE ABOVE */ if (disp_opcodes) fprintf(codefile, "%s/* opCMPdir_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "acc_a0 = register_A;\n"); fprintf(codefile, "%sflag_C = ((((cmp_new = ram[register_I = (register_P << 4) + 0x%01x]) ^ 0xFFF) + 1) + (cmp_old = register_B)); /* ones compliment */\n", cur_tabs, (opcode & 0x0F)); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opANDirg_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opANDirg_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = flag_C = acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_A &= (cmp_new = ram[register_I]);\n"); register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opANDirg_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opANDirg_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "flag_C = acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = register_B;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B &= (cmp_new = ram[register_I]);\n"); register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLDJimm_A_A (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDJimm_A_A (%02x) */\n", cur_tabs, opcode); if (ImmOpd == 0xDEADBEEFUL) { CINEWORD temp_byte = rom[register_PC+1]; temp_byte = ((temp_byte << 4) | ((temp_byte >> 4)&0xF)) & 0xFF; ImmOpd = (opcode & 0x0F) | (temp_byte << 4); } /* A DANGEROUS OPTIMISATION WOULD BE TO NOT OUTPUT THE NEXT LINE: !!! */ register_J = ImmOpd; #ifndef SUPEROPTIMISE fprintf(codefile, "%sregister_J = 0x%04x;\n", cur_tabs, register_J); #endif if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opLDJimm_B_BB (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDJimm_B_BB (%02x) */\n", cur_tabs, opcode); if (ImmOpd == 0xDEADBEEFUL) { CINEWORD temp_byte = rom[register_PC+1]; temp_byte = ((temp_byte << 4) | ((temp_byte >> 4)&0xF)) & 0xFF; ImmOpd = (opcode & 0x0F) | (temp_byte << 4); } /* A DANGEROUS OPTIMISATION WOULD BE TO NOT OUTPUT THE NEXT LINE: !!! */ register_J = ImmOpd; #ifndef SUPEROPTIMISE fprintf(codefile, "%sregister_J = 0x%04x;\n", cur_tabs, register_J); #endif if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opLDJirg_A_A (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDJirg_A_A (%02x) */\n", cur_tabs, opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); /*fprintf(stderr, "MANUAL ASSISTANCE: Look at dynamic jump through table at 0x%04x\n", register_PC);*/ if (pass == PASS_1) fprintf(codefile, "%s/* WARNING: DYNAMIC JUMP TABLE. NEEDS HAND-TWEAKING */\n", cur_tabs); fprintf(codefile, "%s%s", cur_tabs, "/* load J reg from value at last dir addr */\n"); if (register_I != 0xDEADBEEFUL) { fprintf(codefile, "%sregister_J = ram[0x%02x];\n", cur_tabs, register_I); } else { fprintf(codefile, "%s%s", cur_tabs, "register_J = ram[register_I];\n"); } fprintf(codefile, "%s%s", cur_tabs, "if ((register_J & (~0xfff)) != 0) ERROR(\"Ram value must have been > 12 bits!\\n\");\n"); if (debug) fprintf(codefile, "%sif (debug) fprintf(stderr, \"%%04x J set to 0x%%03x from ram[0x%%02x]\\n\", register_PC, register_J, register_I);\n", cur_tabs); register_J = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opLDJirg_B_BB (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDJirg_B_BB (%02x) */\n", cur_tabs, opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); /*fprintf(stderr, "MANUAL ASSISTANCE: Look at dynamic jump through table at 0x%04x\n", register_PC);*/ if (pass == PASS_1) fprintf(codefile, "%s/* WARNING: DYNAMIC JUMP TABLE. NEEDS HAND-TWEAKING */\n", cur_tabs); fprintf(codefile, "%s%s", cur_tabs, "/* load J reg from value at last dir addr */\n"); fprintf(codefile, "%s%s", cur_tabs, "register_J = ram[register_I] & 0xFFF;\n"); if (debug) fprintf(codefile, "%sif (debug) fprintf(stderr, \"%%04x J set to 0x%%03x from ram[0x%%02x]\\n\", register_PC, register_J, register_I);\n", cur_tabs); register_J = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opLDPimm_A_A (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDPimm_A_A (%02x) */\n", cur_tabs, opcode); if (ImmOpd != 0xDEADBEEFUL) { assert(ImmOpd < 16); assert(ImmOpd >= 0); if (register_P != ImmOpd) fprintf(codefile, "%sregister_P = 0x%01x; /* set page register */\n", cur_tabs, ImmOpd); register_P = ImmOpd; } else { if (register_P != (opcode&0x0f)) fprintf(codefile, "%sregister_P = 0x%01x; /* set page register */\n", opcode & 0x0F); /* ERROR - can't see why it would ever get here */ exit(1); } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opLDPimm_B_BB (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDPimm_B_BB (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "/* load page register from immediate */\n"); if (register_P != (opcode&0x0f)) fprintf(codefile, "%sregister_P = 0x%01x; /* set page register */\n", cur_tabs, opcode & 0x0F); register_P = opcode&0x0f; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opLDIdir_A_A (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDIdir_A_A (%02x) */\n", cur_tabs, opcode); if (register_P != 0xDEADBEEFUL) { fprintf(codefile, "%sregister_I = ram[0x%02x]&0xff; /* set new register_I (8 bits) */\n", cur_tabs, (register_P << 4) + (opcode & 0x0f)); register_I = 0xDEADBEEFUL; /* since we don't know what's in ram */ } else { fprintf(codefile, "%sregister_I = ram[(register_P << 4) + 0x%02x]&0xff; /* set/mask new register_I */\n", cur_tabs, (opcode & 0x0F)); register_I = 0xDEADBEEFUL; } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opLDIdir_B_BB (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLDIdir_B_BB (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "{\n"); fprintf(codefile, "%s%s", cur_tabs, "CINEBYTE temp_byte = (register_P << 4) + /* get ram page ... */\n"); fprintf(codefile, "%s (0x%02x & 0x0F); /* and imm half of ram addr.. */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "register_I = ram[temp_byte] & 0xFF; /* set/mask new register_I */\n"); fprintf(codefile, "%s%s", cur_tabs, "}\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); register_I = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opSTAdir_A_A (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opSTAdir_A_A (%02x) */\n", cur_tabs, opcode); if (register_P != 0xDEADBEEFUL) { assert(register_P < 16); assert(register_P >= 0); register_I = (register_P << 4) + (opcode & 0x0F); /* snag imm value */; fprintf(codefile, "%sram[register_I = 0x%02x] = ", cur_tabs, register_I); } else { fprintf(codefile, "%sram[register_I = (register_P << 4) + 0x%1x] = ", cur_tabs, (opcode & 0x0F)); register_I = 0xDEADBEEFUL; } if (register_A != 0xDEADBEEFUL) { assert((register_A & (~0xFFF)) == 0); fprintf(codefile, "0x%03x; /* store acc to RAM */\n", register_A); } else { fprintf(codefile, "register_A; /* store acc to RAM */\n"); } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opSTAdir_B_BB (int opcode) { internal_test(opcode); /* to be optimised as above */ if (disp_opcodes) fprintf(codefile, "%s/* opSTAdir_B_BB (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sram[register_I = (register_P << 4) + 0x%01x] = register_B; /* set I register and store B to ram */\n", cur_tabs, (opcode & 0x0F)); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); register_I = 0xDEADBEEFUL; return state = state_BB; } CINESTATE opSTAirg_A_A (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opSTAirg_A_A (%02x) */\n", cur_tabs, opcode); if (register_I != 0xDEADBEEFUL) { if (register_A != 0xDEADBEEFUL) { fprintf(codefile, "%sram[0x%02x] = 0x%03x; /* store acc */\n", cur_tabs, register_I, register_A); } else { fprintf(codefile, "%sram[0x%02x] = register_A; /* store acc */\n", cur_tabs, register_I); } } else { fprintf(codefile, "%s%s", cur_tabs, "ram[register_I] = register_A; /* store acc */\n"); } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opSTAirg_B_BB (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opSTAirg_B_BB (%02x) */\n", cur_tabs, opcode); if (register_I != 0xDEADBEEFUL) { if (register_B != 0xDEADBEEFUL) { fprintf(codefile, "%sram[0x%02x] = 0x%03x; /* store acc */\n", cur_tabs, register_I, register_B); } else { fprintf(codefile, "%sif (register_I != 0x%02x) ERROR(\"Error in I\\n\");\n", cur_tabs, register_I); fprintf(codefile, "%sram[0x%02x] = register_B; /* store acc */\n", cur_tabs, register_I); } } else { fprintf(codefile, "%s%s", cur_tabs, "ram[register_I] = register_B; /* store acc */\n"); } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opXLT_A_AA (int opcode) { internal_test(opcode); /* We should check the next opcode to see that it is a NOP. If not, need to look at this more closely */ if (disp_opcodes) fprintf(codefile, "%s/* opXLT_A_AA (%02x) */\n", cur_tabs, opcode); if (comments) { fprintf(codefile, "%s%s", cur_tabs, "/*\n"); fprintf(codefile, "%s%s", cur_tabs, " * XLT is weird; it loads the current accumulator with the bytevalue\n"); fprintf(codefile, "%s%s", cur_tabs, " * at ROM location pointed to by the accumulator; this allows the\n"); fprintf(codefile, "%s%s", cur_tabs, " * program to read the program itself..\n"); fprintf(codefile, "%s%s", cur_tabs, " * NOTE! Next opcode is *IGNORED!* because of a twisted side-effect\n"); fprintf(codefile, "%s%s", cur_tabs, " */\n"); } if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); register_A = 0xDEADBEEFUL; register_I = 0xDEADBEEFUL; register_P = 0xDEADBEEFUL; if (register_A != 0xDEADBEEFUL) { fprintf(codefile, "%scmp_old = register_A; register_A = cmp_new = 0x%02x; /* new acc value */\n", cur_tabs, register_A = rom[(register_PC & 0xF000) | register_A]); if (debug) fprintf(codefile, "%sif (debug) fprintf(stderr, \"%%04x A set using XLT but target known at compile time?\\n\");\n", cur_tabs); } else { if (debug) fprintf(codefile, "%sif (debug) fprintf(stderr, \"%%04x A set to 0x%%03x from rom[0x%%04x]\\n\", register_PC, rom[(register_PC & 0xF000) | register_A], (register_PC & 0xF000) | register_A);\n", cur_tabs); if ((register_PC & 0xF000) != 0) { fprintf(codefile, "%scmp_old = register_A; register_A = cmp_new = rom[0x%04x | register_A]; /* new acc value */\n", cur_tabs, register_PC & 0xF000); } else { fprintf(codefile, "%scmp_old = register_A; register_A = cmp_new = rom[register_A]; /* new acc value */\n", cur_tabs); } } if (rom[register_PC+1] == 0x5f /*NOP*/) { /* No point in making an explicit jump to the next instruction! */ if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); /* This note_state stuff is screwy. get rid of it. */ } else { fprintf(codefile, "%sregister_PC = 0x%04x; /* bump PC twice because XLT is fucked up */\n", cur_tabs, register_PC = register_PC+2); romFlags[register_PC] |= TAG_JUMPTARGET_A; register_A = 0xDEADBEEFUL; /* FOR NOW, UNLESS BETTER OPTIMISED */ fprintf(codefile, "%s%s;\n", cur_tabs, Jump()); } return state = state_AA; } CINESTATE opXLT_B_AA (int opcode) { assert(NOTUSED); /* Just as well, as this looks broken... */ internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opXLT_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "flag_C = acc_a0 = register_A; /* back up acc */\n", cur_tabs); fprintf(codefile, "%sregister_B = cmp_new = rom[(register_PC & 0xF000) | (cmp_old = register_B)]; /* new acc value */\n", cur_tabs); fprintf(codefile, "%sregister_PC = 0x%04x; /* bump PC twice because XLT is fucked up */\n", cur_tabs, register_PC = register_PC+2); romFlags[register_PC] |= TAG_JUMPTARGET_AA; register_B = 0xDEADBEEFUL; /* FOR NOW, UNLESS BETTER OPTIMISED */ if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opMULirg_A_AA (int opcode) { /* WARNING: check the SAR and <<, >> logic here. I am 99% sure it is assuming 16 bit integers and THAT THIS PROCEDURE IS BUGGY!!!!! Unfortunately it's too complicated for me to correct without advice... */ internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opMULirg_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "cmp_new = ram[register_I];\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B <<= 4; /* get sign bit 15 */\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B |= (register_A >> 8); /* bring in A high nibble */\n"); fprintf(codefile, "%sregister_A = ((register_A & 0xFF) << 8) | (0x%02x); /* pick up opcode */\n", cur_tabs, opcode & 0xFF); fprintf(codefile, "%s%s", cur_tabs, "if (register_A & 0x100) /* 1bit shifted out? */ {\n"); push_indent(" "); fprintf(codefile, "%s%s", cur_tabs, "acc_a0 = register_A = (register_A >> 8) | ((register_B & 0xFF) << 8);\n"); fprintf(codefile, "%s%s", cur_tabs, "register_A >>= 1;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_A &= 0xFFF;\n"); fprintf(codefile, "%sregister_B = %s;\n", cur_tabs, SAR("register_B","4")); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = register_B & 0x0F;\n"); fprintf(codefile, "%sregister_B = %s;\n", cur_tabs, SAR("register_B","1")); fprintf(codefile, "%s%s", cur_tabs, "register_B &= 0xFFF;\n"); fprintf(codefile, "%s%s", cur_tabs, "flag_C = (register_B += cmp_new);\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B &= 0xFFF;\n"); pop_indent(" "); fprintf(codefile, "%s%s", cur_tabs, "} else {\n"); push_indent(" "); fprintf(codefile, "%s%s", cur_tabs, "register_A = (register_A >> 8) | /* Bhigh | Alow */ ((register_B & 0xFF) << 8);\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = acc_a0 = register_A & 0xFFF;\n"); fprintf(codefile, "%s%s", cur_tabs, "flag_C = (cmp_old + cmp_new);\n"); fprintf(codefile, "%s%s", cur_tabs, "register_A >>= 1;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_A &= 0xFFF;\n"); fprintf(codefile, "%sregister_B = %s;\n", cur_tabs, SAR("register_B","5")); fprintf(codefile, "%s%s", cur_tabs, "register_B &= 0xFFF;\n"); pop_indent(" "); fprintf(codefile, "%s%s", cur_tabs, "}\n"); register_A = 0xDEADBEEFUL; register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opMULirg_B_AA (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opMULirg_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "cmp_new = ram[register_I]; cmp_old = register_B; acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B = SEX(register_B);\n"); fprintf(codefile, "%sregister_B = %s;\n", cur_tabs, SAR("register_B","1")); fprintf(codefile, "%s%s", cur_tabs, "flag_C = (register_B + temp_word);\n"); fprintf(codefile, "%s%s", cur_tabs, "if (register_A & 0x01) register_B = flag_C;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B &= 0xFFF;\n"); register_A = 0xDEADBEEFUL; register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLSRe_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLSRe_A_AA (%02x) */\n", cur_tabs, opcode); if (comments) { fprintf(codefile, "%s%s", cur_tabs, "/*\n"); fprintf(codefile, "%s%s", cur_tabs, " * EB; right shift pure; fill new bit with zero.\n"); fprintf(codefile, "%s%s", cur_tabs, " */\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); } fprintf(codefile, "%s%s", cur_tabs, "cmp_new = 0x0BEB; cmp_old = acc_a0 = register_A; flag_C = (0x0BEB + register_A);\n"); fprintf(codefile, "%s%s", cur_tabs, "register_A >>= 1;\n"); register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLSRe_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLSRe_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "cmp_new = 0x0BEB; acc_a0 = register_A; cmp_old = register_B; flag_C = (0x0BEB + register_B);\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B >>= 1;\n"); register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); fprintf(codefile, "%s%s", cur_tabs, "}\n"); return state = state_AA; } CINESTATE opLSRf_A_AA (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLSRf_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opLSRf 1\");\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLSRf_B_AA (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLSRf_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opLSRf 2\");\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLSLe_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLSLe_A_AA (%02x) */\n", cur_tabs, opcode); if (comments) { fprintf(codefile, "%s%s", cur_tabs, "/*\n"); fprintf(codefile, "%s%s", cur_tabs, " * EC; left shift pure; fill new bit with zero *\n"); fprintf(codefile, "%s%s", cur_tabs, " */\n"); } fprintf(codefile, "%s%s", cur_tabs, "cmp_new = 0x0CEC;\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "flag_C = (0x0CEC + register_A);\n"); fprintf(codefile, "%s%s", cur_tabs, "register_A = (register_A << 1) & 0x0FFF;\n"); register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLSLe_B_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLSLe_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "cmp_new = 0x0CEC; acc_a0 = register_A; cmp_old = register_B; flag_C = (0x0CEC + register_B);\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B = (register_B << 1) & 0xFFF;\n"); register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLSLf_A_AA (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLSLf_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opLSLf 1\");\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLSLf_B_AA (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLSLf_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opLSLf 2\");\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opASRe_A_AA (int opcode) { /* WARNING: check the SAR and <<, >> logic here. It may be assuming 16 bit integers */ internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opASRe_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "cmp_new = 0xDED; cmp_old = flag_C = acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_A = SEX(register_A); /* make signed */\n"); fprintf(codefile, "%sregister_A = (%s) & 0xFFF;\n", cur_tabs, SAR("register_A","1")); register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opASRe_B_AA (int opcode) { /* WARNING: check the SAR and <<, >> logic here. It may be assuming 16 bit integers */ internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opASRe_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "cmp_new = 0x0DED;\n"); fprintf(codefile, "%s%s", cur_tabs, "flag_C = acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = register_B;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B = SEX(register_B);\n"); fprintf(codefile, "%sregister_B = (%s)&0xFFF;\n", cur_tabs, SAR("register_B","1")); register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opASRf_A_AA (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opASRf_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opASRf 1\");\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opASRf_B_AA (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opASRf_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opASRf 2\");\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opASRDe_A_AA (int opcode) { /* WARNING: check the SAR and <<, >> logic here. It may be assuming 16 bit integers */ internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opASRDe_A_AA (%02x) */\n", cur_tabs, opcode); if (comments) { fprintf(codefile, "%s%s", cur_tabs, "/*\n"); fprintf(codefile, "%s%s", cur_tabs, " * Arithmetic shift right of D (A+B) .. B is high (sign bits).\n"); fprintf(codefile, "%s%s", cur_tabs, " * divide by 2, but leave the sign bit the same. (ie: 1010 -> 1001)\n"); fprintf(codefile, "%s%s", cur_tabs, " */\n"); } fprintf(codefile, "%s%s", cur_tabs, "cmp_new = 0x0EEE; cmp_old = acc_a0 = register_A; flag_C = (0x0EEE + register_A);\n"); /* My version */ fprintf(codefile, "%s%s", cur_tabs, "register_A = (register_A >> 1) | ((register_B & 1) << 11);\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B = (register_B >> 1) | (register_B & 0x800);\n"); register_A = 0xDEADBEEFUL; register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opASRDe_B_AA (int opcode) { assert(NOTUSED); /* WARNING: check the SAR and <<, >> logic here. It may be assuming 16 bit integers */ internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opASRDe_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "{\n"); fprintf(codefile, "%s%s", cur_tabs, "CINEWORD temp_word = 0x0EEE;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_new = temp_word;\n"); fprintf(codefile, "%s%s", cur_tabs, "acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = register_B;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "flag_C = (temp_word += register_B);\n"); #ifdef BUGGYORIGINAL fprintf(codefile, "%s%s", cur_tabs, "register_B <<= 4;\n"); fprintf(codefile, "%sregister_B = %s;\n", cur_tabs, SAR("register_B","5")); fprintf(codefile, "%s%s", cur_tabs, "register_B &= 0x0FFF;\n"); #else fprintf(codefile, "%s%s", cur_tabs, "register_B = SEX(register_B);\n"); fprintf(codefile, "%sregister_B = %s;\n", cur_tabs, SAR("register_B","1")); fprintf(codefile, "%s%s", cur_tabs, "register_B &= 0x0FFF;\n"); #endif fprintf(codefile, "%s%s", cur_tabs, "\n"); register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); fprintf(codefile, "%s%s", cur_tabs, "}\n"); return state = state_AA; } CINESTATE opASRDf_A_AA (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opASRDf_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opASRDf 1\");\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opASRDf_B_AA (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opASRDf_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opASRDf 2\");\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLSLDe_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLSLDe_A_AA (%02x) */\n", cur_tabs, opcode); if (comments) { fprintf(codefile, "%s%s", cur_tabs, "/* LSLDe -- Left shift through both accumulators; lossy in middle. */\n"); } fprintf(codefile, "%s%s", cur_tabs, "cmp_new = 0x0FEF; cmp_old = acc_a0 = register_A; flag_C = (0x0FEF + register_A);\n"); fprintf(codefile, "%s%s", cur_tabs, "register_A = (register_A << 1) & 0xFFF; register_B = (register_B << 1) & 0xFFF;\n"); register_A = 0xDEADBEEFUL; register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLSLDe_B_AA (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLSLDe_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opLSLD 1\");\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opLSLDf_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLSLDf_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "{\n"); fprintf(codefile, "%s%s", cur_tabs, "/* LSLDf */\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "CINEWORD temp_word = 0xFFF;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_new = temp_word;\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "flag_C = (temp_word + register_A);\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "register_A <<= 1;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_A &= 0x0FFF;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B <<= 1;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B &= 0x0FFF;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); register_A = 0xDEADBEEFUL; register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); fprintf(codefile, "%s%s", cur_tabs, "}\n"); return state = state_AA; } CINESTATE opLSLDf_B_AA (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLSLDf_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "{\n"); fprintf(codefile, "%s%s", cur_tabs, "/* not 'the same' as the A->AA version above */\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "CINEWORD temp_word = 0xFFF;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_new = temp_word;\n"); fprintf(codefile, "%s%s", cur_tabs, "acc_a0 = register_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "cmp_old = register_B;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "flag_C = (temp_word + register_B);\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B <<= 1;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_B &= 0x0FFF;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); register_A = 0xDEADBEEFUL; register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); fprintf(codefile, "%s%s", cur_tabs, "}\n"); return state = state_AA; } CINESTATE opJMP_A_A (int opcode) { internal_test(opcode); romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJMP_A_A (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s;\n", cur_tabs, Jump()); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); /* After a jump, next code is entirely unknown. We ought to handle this by setting flags on first pass, but for now, brute force and ignorance rules... */ register_P = 0xDEADBEEFUL; register_I = 0xDEADBEEFUL; register_A = 0xDEADBEEFUL; register_B = 0xDEADBEEFUL; return state = state_A; } CINESTATE opJMP_B_BB (int opcode) { assert(NOTUSED); internal_test(opcode); romFlags[register_PC] |= TAG_JUMPINST; /* Todo: steal code from opJMP_A_A */ if (disp_opcodes) fprintf(codefile, "%s/* opJMP_B_BB (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s;\n", cur_tabs, Jump()); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opJEI_A_A (int opcode) { int savedpc = register_PC; internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJEI_A_A (%02x) */\n", cur_tabs, opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); #ifdef NEVER fprintf(codefile, "%s%s", cur_tabs, "FromX = SEX(FromX);\n"); fprintf(codefile, "%s%s", cur_tabs, "if (!(CCPU_READPORT (CCPU_PORT_IOOUTPUTS) & 0x80))\n"); fprintf(codefile, "%s%s", cur_tabs, "{\n"); fprintf(codefile, "%s if ((CCPU_READPORT (CCPU_PORT_IN_JOYSTICKY) - (CINESWORD)FromX) < 0x800) %s /* Should this be '> 0' ? */\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "} else {\n"); fprintf(codefile, "%s if ((CCPU_READPORT (CCPU_PORT_IN_JOYSTICKX) - (CINESWORD)FromX) < 0x800) %s /* > 0 ? */\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "}\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); #else /* I DO NOT KNOW HOW THIS IS USED. It appears to be used only once, and has no effect whether the branch is take or not..? */ #endif if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opJEI_B_BB (int opcode) { int savedpc = register_PC; assert(NOTUSED); internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJEI_B_BB (%02x) */\n", cur_tabs, opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); fprintf(codefile, "%s%s", cur_tabs, "FromX = SEX(FromX);\n"); fprintf(codefile, "%s%s", cur_tabs, "if (!(CCPU_READPORT (CCPU_PORT_IOOUTPUTS) & 0x80))\n"); fprintf(codefile, "%s%s", cur_tabs, "{\n"); fprintf(codefile, "%s if ((CCPU_READPORT (CCPU_PORT_IN_JOYSTICKY) - (CINESWORD)FromX) < 0x800) %s /* > 0 ? */\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "} else {\n"); fprintf(codefile, "%s if ((CCPU_READPORT (CCPU_PORT_IN_JOYSTICKX) - (CINESWORD)FromX) < 0x800) %s /* > 0 ? */\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "}\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opJEI_A_B (int opcode) { int savedpc = register_PC; assert(NOTUSED); internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJEI_A_B (%02x) */\n", cur_tabs, opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); fprintf(codefile, "%s%s", cur_tabs, "FromX = SEX(FromX);\n"); fprintf(codefile, "%s%s", cur_tabs, "if (!(CCPU_READPORT (CCPU_PORT_IOOUTPUTS) & 0x80)) {\n"); fprintf(codefile, "%s if ((CCPU_READPORT (CCPU_PORT_IN_JOYSTICKY) - (CINESWORD)FromX) < 0x800) %s /* > 0? */\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "} else {\n"); fprintf(codefile, "%s if ((CCPU_READPORT (CCPU_PORT_IN_JOYSTICKX) - (CINESWORD)FromX) < 0x800) %s /* > 0 ? */\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "}\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } /* WARNING: THESE ARE THE FUNNY ONES SPECIFICALLY FOR TAILGUNNER */ /* These instructions require the saved 'cmp_new' from a previous instruction. Therefore on the first pass, we can tag that previous instruction so that it remembers the cmp_new value. Actually a better thing is to tag this instruction, and have the previous instruction do a lookahead test when it generates its code */ /* Not we have not yet optimised the saving of cmp_* so it's not yet necessary to set these flags. */ CINESTATE opJMI_A_A (int opcode) { int savedpc = register_PC; assert(NOTUSED); internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (pass == PASS_1) { romFlags[register_PC] |= (TAG_REQUIRES_CMP_OLD | TAG_REQUIRES_CMP_NEW); } if (disp_opcodes) fprintf(codefile, "%s/* opJMI_A_A (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "/*\n"); fprintf(codefile, "%s%s", cur_tabs, " * previous instruction was not an ACC instruction, nor was the\n"); fprintf(codefile, "%s%s", cur_tabs, " * instruction twice back a USB, therefore minus flag test the\n"); fprintf(codefile, "%s%s", cur_tabs, " * current A-reg\n"); fprintf(codefile, "%s%s", cur_tabs, " */\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "/* negative acc? */\n"); fprintf(codefile, "%sif ((register_A & 0x800) != 0) %s;\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opJMI_AA_A (int opcode) { int savedpc = register_PC; assert(NOTUSED); internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (pass == PASS_1) { romFlags[register_PC] |= (TAG_REQUIRES_CMP_OLD | TAG_REQUIRES_CMP_NEW); } if (disp_opcodes) fprintf(codefile, "%s/* opJMI_AA_A (%02x) */\n", cur_tabs, opcode); if (comments) fprintf(codefile, "%s%s", cur_tabs, "/* previous acc negative? Jump if so... */\n"); fprintf(codefile, "%sif ((cmp_old & 0x800) != 0) %s;\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opJMI_BB_A (int opcode) { int savedpc = register_PC; assert(NOTUSED); internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (pass == PASS_1) { romFlags[register_PC] |= (TAG_REQUIRES_CMP_OLD | TAG_REQUIRES_CMP_NEW); } if (disp_opcodes) fprintf(codefile, "%s/* opJMI_BB_A (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sif ((register_B & 0x800) != 0) %s;\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opJMI_B_BB (int opcode) { int savedpc = register_PC; assert(NOTUSED); internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (pass == PASS_1) { romFlags[register_PC] |= (TAG_REQUIRES_CMP_OLD | TAG_REQUIRES_CMP_NEW); } if (disp_opcodes) fprintf(codefile, "%s/* opJMI_B_BB (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sif ((register_A & 0x800) != 0) %s;\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } /* I am changing this from signed to unsigned as a test. */ CINESTATE opJLT_A_A (int opcode) { int savedpc = register_PC; internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (pass == PASS_1) { romFlags[register_PC] |= (TAG_REQUIRES_CMP_OLD | TAG_REQUIRES_CMP_NEW); } if (disp_opcodes) fprintf(codefile, "%s/* opJLT_A_A (%02x) */\n", cur_tabs, opcode); if (comments) fprintf(codefile, "%s%s", cur_tabs, "/* jump if old acc less than new acc */\n"); /*fprintf(codefile, "%sif (((cmp_new|cmp_old)>>12) != 0) ERROR(\"cmp_new/old out of range\");\n", cur_tabs);*/ fprintf(codefile, "%sif (cmp_new < cmp_old) %s;\n", cur_tabs, Jump()); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opJLT_B_BB (int opcode) { int savedpc = register_PC; internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (pass == PASS_1) { romFlags[register_PC] |= (TAG_REQUIRES_CMP_OLD | TAG_REQUIRES_CMP_NEW); } if (disp_opcodes) fprintf(codefile, "%s/* opJLT_B_BB (%02x) */\n", cur_tabs, opcode); /* fprintf(codefile, "%s%s", cur_tabs, "if (SEX(cmp_new) < SEX(cmp_old))\n");*/ /*fprintf(codefile, "%sif (((cmp_new|cmp_old)>>12) != 0) ERROR(\"cmp_new/old out of range\");\n", cur_tabs);*/ fprintf(codefile, "%sif (cmp_new < cmp_old) %s;\n", cur_tabs, Jump()); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opJEQ_A_A (int opcode) { int savedpc = register_PC; internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (pass == PASS_1) { romFlags[register_PC] |= (TAG_REQUIRES_CMP_OLD | TAG_REQUIRES_CMP_NEW); } if (disp_opcodes) fprintf(codefile, "%s/* opJEQ_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sif (cmp_new == cmp_old) %s;\n", cur_tabs, Jump()); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opJEQ_B_BB (int opcode) { int savedpc = register_PC; internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (pass == PASS_1) { romFlags[register_PC] |= (TAG_REQUIRES_CMP_OLD | TAG_REQUIRES_CMP_NEW); } if (disp_opcodes) fprintf(codefile, "%s/* opJEQ_B_BB (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sif (cmp_new == cmp_old) %s;\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opJA0_A_A (int opcode) { int savedpc = register_PC; internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; /* I am not convinced that we need this extra acc_a0 variable *as well as* an extra carry-flag remembering variable */ if (disp_opcodes) fprintf(codefile, "%s/* opJA0_A_A (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sif ((acc_a0 & 0x01) != 0) %s;\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opJA0_B_BB (int opcode) { int savedpc = register_PC; assert(NOTUSED); internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJA0_B_BB (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sif ((acc_a0 & 0x01) != 0) %s;\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opJNC_A_A (int opcode) { int savedpc = register_PC; internal_test(opcode); /* BUG: explore changes *all* the registers :-( */ explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJNC_A_AA (%02x) */\n", cur_tabs, opcode); /* Use this opcode to test new carry and new jump code */ fprintf(codefile, "%sif ((flag_C & CARRYBIT) == 0) %s;\n", cur_tabs, Jump()); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opJNC_B_BB (int opcode) { int savedpc = register_PC; assert(NOTUSED); internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJNC_B_BB (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sif ((flag_C & CARRYBIT) == 0) %s;\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opJDR_A_A (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opJDR_A_A (%02x) */\n", cur_tabs, opcode); if (comments) fprintf(codefile, "%s%s", cur_tabs, "/* We don't need to simulate this too accurately */\n"); register_A = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opJDR_B_BB (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opJDR_B_BB (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "/* We don't need to simulate this too accurately */\n"); register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opNOP_A_A (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opNOP_A_A (%02x) */\n", cur_tabs, opcode); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opNOP_B_BB (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opNOP_B_BB (%02x) */\n", cur_tabs, opcode); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opJPP32_A_B (int opcode) { assert(NOTUSED); internal_test(opcode); romFlags[register_PC] |= TAG_JUMPINST; /* AHA! Is this the *only* way we can jump between rom pages? If so, then can surely clean up the code of all the other jumps */ if (disp_opcodes) fprintf(codefile, "%s/* opJPP32_A_B (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "/*\n"); fprintf(codefile, "%s%s", cur_tabs, " * 00 = Offset 0000h\n"); fprintf(codefile, "%s%s", cur_tabs, " * 01 = Offset 1000h\n"); fprintf(codefile, "%s%s", cur_tabs, " * 02 = Offset 2000h\n"); fprintf(codefile, "%s%s", cur_tabs, " * 03 = Offset 3000h\n"); fprintf(codefile, "%s%s", cur_tabs, " * 04 = Offset 4000h\n"); fprintf(codefile, "%s%s", cur_tabs, " * 05 = Offset 5000h\n"); fprintf(codefile, "%s%s", cur_tabs, " * 06 = Offset 6000h\n"); fprintf(codefile, "%s%s", cur_tabs, " * 07 = Offset 7000h\n"); fprintf(codefile, "%s%s", cur_tabs, " */\n"); /* Need to inline and set tags */ fprintf(codefile, "%s%s", cur_tabs, "register_PC = register_J + ((register_P & 0x07) << 12);\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } CINESTATE opJPP32_B_BB (int opcode) { assert(NOTUSED); internal_test(opcode); romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJPP32_B_BB (%02x) */\n", cur_tabs, opcode); /* Need to inline and set tags */ fprintf(codefile, "%s%s", cur_tabs, "register_PC = register_J + ((register_P & 0x07) << 12);\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opJPP16_A_B (int opcode) { assert(NOTUSED); internal_test(opcode); romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJPP16_A_B (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "/*\n"); fprintf(codefile, "%s%s", cur_tabs, " * 00 = Offset 0000h\n"); fprintf(codefile, "%s%s", cur_tabs, " * 01 = Offset 1000h\n"); fprintf(codefile, "%s%s", cur_tabs, " * 02 = Offset 2000h\n"); fprintf(codefile, "%s%s", cur_tabs, " * 03 = Offset 3000h\n"); fprintf(codefile, "%s%s", cur_tabs, " */\n"); /* Need to inline and set tags */ fprintf(codefile, "%s%s", cur_tabs, "register_PC = register_J + ((register_P & 0x03) << 12);\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } CINESTATE opJPP16_B_BB (int opcode) { assert(NOTUSED); internal_test(opcode); romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJPP16_B_BB (%02x) */\n", cur_tabs, opcode); /* Need to inline and set tags */ fprintf(codefile, "%s%s", cur_tabs, "register_PC = register_J + ((register_P & 0x03) << 12);\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opJMP_A_B (int opcode) { internal_test(opcode); romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJMP_A_B (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s;\n", cur_tabs, Jump()); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } CINESTATE opJPP8_A_B (int opcode) { int savedpc = register_PC; internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJPP8_A_B (%02x) */\n", cur_tabs, opcode); if (comments) { fprintf(codefile, "%s%s", cur_tabs, "/*\n"); fprintf(codefile, "%s%s", cur_tabs, " * \"long jump\"; combine P and J to jump to a new far location (that can\n"); fprintf(codefile, "%s%s", cur_tabs, " * be more than 12 bits in address). After this jump, further jumps\n"); fprintf(codefile, "%s%s", cur_tabs, " * are local to this new page.\n"); fprintf(codefile, "%s%s", cur_tabs, " */\n"); } if (register_P != 0xDEADBEEFUL) { if ((register_P != 1) && (register_P != 2)) { fprintf(stderr, "%04x: Translated jump to a wrong page: P = 0x%02x\n", register_PC, register_P); exit(1); } if (register_J != 0xDEADBEEFUL) { fprintf(codefile, "%sregister_PC = 0x%04x; /* rom offset */\n", cur_tabs, register_PC = (register_J + (((register_P & 0x03) - 1) << 12)) & 0xFFFF); fprintf(stderr, "Setting TAG_JUMPTARGET_B bit on 0x%04x\n", register_PC); romFlags[register_PC] |= TAG_JUMPTARGET_B; explore(register_PC, endAdr); } else { fprintf(codefile, "%sregister_PC = register_J + 0x%04x; /* rom offset */\n", cur_tabs, ((register_P & 0x03) - 1) << 12); register_PC = 0xDEADBEEFUL; /* WHY -1 ??????????? */ fprintf(codefile, "%s%s", cur_tabs, "/* WARNING: UNKNOWN JUMP DESTINATION - MAY FOUL UP CODE OPTIMISATIONS */\n"); } } else { fprintf(codefile, "%s%s", cur_tabs, "register_PC = register_J + (((register_P & 0x03) - 1) << 12);\n"); } #ifdef NEVER /* Bug? */ if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B; /* Does this hold true after a jump? */\n"); #endif fprintf(codefile, "%s%s;\n", cur_tabs, Jump()); /* BUG fix. Or bodge? */ return state = state; /* Should be state_unknown */ /* SAME 'FIX' NEEDS TO BE APPLIED TO ALL UNCONDITIONAL JUMPS!!!! */ /*return state = state_B;*/ } CINESTATE opJPP8_B_BB (int opcode) { assert(NOTUSED); internal_test(opcode); romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJPP8_B_BB (%02x) */\n", cur_tabs, opcode); /* Need to inline and set tags */ if (register_P != 0xDEADBEEFUL) { if ((register_P != 1) && (register_P != 2)) { fprintf(stderr, "Translated jump to a wrong page: P = 0x%02x\n", register_P); exit(1); } /* insert optimised expansion here and explore() it! */ } fprintf(codefile, "%s%s", cur_tabs, "register_PC = register_J + (((register_P & 0x03) - 1) << 12);\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opJMI_A_B (int opcode) { int savedpc = register_PC; assert(NOTUSED); internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJMI_A_B (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sif ((register_A & 0x800) != 0) %s;\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } CINESTATE opJMI_AA_B (int opcode) { int savedpc = register_PC; assert(NOTUSED); internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJMI_AA_B (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opJMI 3\");\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } CINESTATE opJMI_BB_B (int opcode) { int savedpc = register_PC; assert(NOTUSED); internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJMI_BB_B (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opJMI 4\");\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } CINESTATE opJLT_A_B (int opcode) { int savedpc = register_PC; internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJLT_A_B (%02x) */\n", cur_tabs, opcode); /* fprintf(codefile, "%s%s", cur_tabs, "if (SEX(cmp_new) < SEX(cmp_old))\n"); */ /*fprintf(codefile, "%sif (((cmp_new|cmp_old)>>12) != 0) ERROR(\"cmp_new/old out of range\");\n", cur_tabs);*/ fprintf(codefile, "%sif (cmp_new < cmp_old) %s;\n", cur_tabs, Jump()); /* Pretty sure this is a bugfix */ fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } CINESTATE opJEQ_A_B (int opcode) { int savedpc = register_PC; internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJEQ_A_B (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "if (cmp_new == cmp_old) %s;\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } CINESTATE opJA0_A_B (int opcode) { int savedpc = register_PC; internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJA0_A_B (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sif ((acc_a0 & A0BIT) != 0) %s;\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } CINESTATE opJNC_A_B (int opcode) { int savedpc = register_PC; internal_test(opcode); explore(register_PC+1, endAdr); register_PC = savedpc; romFlags[register_PC] |= TAG_JUMPINST; if (disp_opcodes) fprintf(codefile, "%s/* opJNC_A_B (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%sif ((flag_C & CARRYBIT) == 0) %s;\n", cur_tabs, Jump()); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } CINESTATE opJDR_A_B (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opJDR_A_B (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "/* register_PC++; */\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } CINESTATE opNOP_A_B (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opNOP_A_B (%02x) */\n", cur_tabs, opcode); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_B;\n"); return state = state_B; } CINESTATE opLLT_A_AA (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLLT_A_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "{int temp_byte = 0;\n"); push_indent(" "); fprintf(codefile, "%s%s", cur_tabs, "for (;;) {\n"); push_indent(" "); fprintf(codefile, "%s%s", cur_tabs, "if ( ((((register_A >> 8) & 0x0A) != 0) && ((((register_A >> 8) & 0x0A) ^ 0x0A)) != 0)\n"); fprintf(codefile, "%s%s", cur_tabs, " || ((((register_B >> 8) & 0x0A) != 0) && ((((register_B >> 8) & 0x0A) ^ 0x0A)) != 0) ) break;\n"); fprintf(codefile, "%s%s", cur_tabs, "register_A <<= 1; register_B <<= 1;\n"); fprintf(codefile, "%s%s", cur_tabs, "temp_byte = (temp_byte+1) & 0xff; if (temp_byte == 0) break /* This may not be correct */;\n"); pop_indent(" "); fprintf(codefile, "%s%s", cur_tabs, "}\n"); fprintf(codefile, "%s%s", cur_tabs, "vgShiftLength = temp_byte & 0xfff; register_A &= 0x0FFF; register_B &= 0x0FFF;\n"); register_A = 0xDEADBEEFUL; register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); pop_indent(" "); fprintf(codefile, "%s%s", cur_tabs, "}\n"); return state = state_AA; } CINESTATE opLLT_B_AA (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opLLT_B_AA (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opLLT 1\");\n"); register_A = 0xDEADBEEFUL; register_B = 0xDEADBEEFUL; if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_AA;\n"); return state = state_AA; } CINESTATE opVIN_A_A (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opVIN_A_A (%02x) */\n", cur_tabs, opcode); if (comments) fprintf(codefile, "%s%s", cur_tabs, "/* set the starting address of a vector */\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "FromX = register_A & 0xFFF; /* regA goes to x-coord */\n"); fprintf(codefile, "%s%s", cur_tabs, "FromY = register_B & 0xFFF; /* regB goes to y-coord */\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opVIN_B_BB (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opVIN_B_BB (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "FromX = register_A & 0xFFF; /* regA goes to x-coord */\n"); fprintf(codefile, "%s%s", cur_tabs, "FromY = register_B & 0xFFF; /* regB goes to y-coord */\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE opWAI_A_A (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opWAI_A_A (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "/* wait for a tick on the watchdog */\n"); if (debug) fprintf(codefile, "%s%s", cur_tabs, "fprintf(stderr, \"%04x ClearScreen();\\n\", register_PC);\n"); fprintf(codefile, "%s%s", cur_tabs, "CinemaClearScreen();\n"); fprintf(codefile, "%s%s", cur_tabs, "bNewFrame = 1;\n"); fprintf(codefile, "%s%s", cur_tabs, "bailOut = TRUE;\n"); /* some dodgy code here */ if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); fprintf(codefile, "%sregister_PC = 0x%04x;\n", cur_tabs, register_PC = register_PC+1); romFlags[register_PC] |= TAG_JUMPTARGET_A; fprintf(codefile, "%s%s; /* NOT REALLY A JUMP - ACTUALLY FOR GETTING BACK TO POLLING LOOP - NEEDS WORK */\n", cur_tabs, return_or_continue_or_break); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); return state = state_A; } CINESTATE opWAI_B_BB (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opWAI_B_BB (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "CinemaClearScreen();\n"); fprintf(codefile, "%s%s", cur_tabs, "bNewFrame = 1;\n"); fprintf(codefile, "%s%s", cur_tabs, "bailOut = TRUE;\n"); /* some more dodgy code here */ if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state;\n"); fprintf(codefile, "%sregister_PC = 0x%04x;\n", cur_tabs, register_PC = register_PC+1); romFlags[register_PC] |= TAG_JUMPTARGET_A; fprintf(codefile, "%s%s; /* NOT REALLY A JUMP - ACTUALLY FOR GETTING BACK TO POLLING LOOP - NEEDS WORK */\n", cur_tabs, return_or_continue_or_break); return state = state_BB; } CINESTATE opVDR_A_A (int opcode) { internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opVDR_A_A (%02x) */\n", cur_tabs, opcode); if (slave_pc) fprintf(codefile, "%sregister_PC = 0x%04x /* Force consistency */;\n", cur_tabs, register_PC); fprintf(codefile, "%s%s", cur_tabs, "{\n"); fprintf(codefile, "%s%s", cur_tabs, "/* set ending points and draw the vector, or buffer for a later draw. */\n"); fprintf(codefile, "%s%s", cur_tabs, "int ToX = register_A & 0xFFF;\n"); fprintf(codefile, "%s%s", cur_tabs, "int ToY = register_B & 0xFFF;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "/* Sign extend from 20 bit CCPU to 32bit target machine */\n"); fprintf(codefile, "%s%s", cur_tabs, "FromX = SEX(FromX);\n"); fprintf(codefile, "%s%s", cur_tabs, "ToX = SEX(ToX);\n"); fprintf(codefile, "%s%s", cur_tabs, "FromY = SEX(FromY);\n"); fprintf(codefile, "%s%s", cur_tabs, "ToY = SEX(ToY);\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "/* figure out the vector */\n"); fprintf(codefile, "%s%s", cur_tabs, "ToX -= FromX;\n"); fprintf(codefile, "%sToX = %s;\n", cur_tabs, SAR("ToX","vgShiftLength")); fprintf(codefile, "%s%s", cur_tabs, "ToX += FromX;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "ToY -= FromY;\n"); fprintf(codefile, "%sToY = %s;\n", cur_tabs, SAR("ToY","vgShiftLength")); fprintf(codefile, "%s%s", cur_tabs, "ToY += FromY;\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); fprintf(codefile, "%s%s", cur_tabs, "/* render the line */\n"); fprintf(codefile, "%s%s", cur_tabs, "CinemaVectorData (FromX, FromY, ToX, ToY, vgColour);\n"); fprintf(codefile, "%s%s", cur_tabs, "\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_A;\n"); fprintf(codefile, "%s%s", cur_tabs, "}\n"); return state = state_A; } CINESTATE opVDR_B_BB (int opcode) { assert(NOTUSED); internal_test(opcode); if (disp_opcodes) fprintf(codefile, "%s/* opVDR_B_BB (%02x) */\n", cur_tabs, opcode); fprintf(codefile, "%s%s", cur_tabs, "UNFINISHED (\"opVDR B 1\");\n"); if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "state = state_BB;\n"); return state = state_BB; } CINESTATE tJPP_A_B (int opcode) { internal_test(opcode); switch (ccpu_msize) { case CCPU_MEMSIZE_4K: case CCPU_MEMSIZE_8K: return opJPP8_A_B (opcode); case CCPU_MEMSIZE_16K: return opJPP16_A_B (opcode); case CCPU_MEMSIZE_32K: return opJPP32_A_B (opcode); default: fprintf(codefile, "%s%s", cur_tabs, "fprintf (stderr, \"Out of range JPP!\\n\");\n"); return opJPP32_A_B (opcode); } } CINESTATE tJPP_B_BB (int opcode) { internal_test(opcode); switch (ccpu_msize) { case CCPU_MEMSIZE_4K: case CCPU_MEMSIZE_8K: return opJPP8_B_BB (opcode); case CCPU_MEMSIZE_16K: return opJPP16_B_BB (opcode); case CCPU_MEMSIZE_32K: return opJPP32_B_BB (opcode); default: fprintf(stderr, "Out of range JPP!\n"); } if (require_note_state(register_PC)) fprintf(codefile, "%s%s", cur_tabs, "/* state = state; */\n"); return state = state; } CINESTATE tJMI_A_B (int opcode) { internal_test(opcode); /* again, all compile-time tests */ return (ccpu_jmi_dip) ? opJMI_A_B (opcode) : opJEI_A_B (opcode); } CINESTATE tJMI_A_A (int opcode) { internal_test(opcode); return (ccpu_jmi_dip) ? opJMI_A_A (opcode) : opJEI_A_A (opcode); } CINESTATE tJMI_AA_B (int opcode) { internal_test(opcode); return (ccpu_jmi_dip) ? opJMI_AA_B (opcode) : opJEI_AA_B (opcode); } CINESTATE tJMI_AA_A (int opcode) { internal_test(opcode); return (ccpu_jmi_dip) ? opJMI_AA_A (opcode) : opJEI_A_A (opcode); } CINESTATE tJMI_B_BB1 (int opcode) { internal_test(opcode); return (ccpu_jmi_dip) ? opJMI_B_BB (opcode) : opJEI_B_BB (opcode); } CINESTATE tJMI_BB_B (int opcode) { internal_test(opcode); return (ccpu_jmi_dip) ? opJMI_BB_B (opcode) : opJEI_A_B (opcode); } CINESTATE tJMI_BB_A (int opcode) { internal_test(opcode); return (ccpu_jmi_dip) ? opJMI_BB_A (opcode) : opJEI_A_A (opcode); } CINESTATE tOUT_A_A (int opcode) { internal_test(opcode); switch (ccpu_monitor) { /* Known at translate time */ case CCPU_MONITOR_16LEV: return opOUT16_A_A (opcode); case CCPU_MONITOR_64LEV: return opOUT64_A_A (opcode); case CCPU_MONITOR_WOWCOL: return opOUTWW_A_A (opcode); default: /* This for tailgunner */ return opOUTbi_A_A (opcode); } } CINESTATE tOUT_B_BB (int opcode) { internal_test(opcode); /* see above */ switch (ccpu_monitor) { /* These three are in error if tailgunner */ case CCPU_MONITOR_16LEV: return opOUT16_B_BB (opcode); case CCPU_MONITOR_64LEV: return opOUT64_B_BB (opcode); case CCPU_MONITOR_WOWCOL: return opOUTWW_B_BB (opcode); default: /* Tailgunner */ return opOUTbi_B_BB (opcode); } }