jb302@36: /* mem.c jb302@36: * functions for accessing emulator memory */ jb302@36: #include "mem.h" jb302@36: jb302@36: /* get flag value jb302@36: * if invalid flag is requested value is 0 */ jb302@36: BYTE jb302@36: get_flag(BYTE flag) { jb302@36: if (flag > 7) { jb302@36: return 0; jb302@36: } jb302@36: else { jb302@36: return GBIT(flags, flag); jb302@36: } jb302@36: } jb302@36: jb302@36: /* set flag to 0 if on == 0 jb302@36: * otherwise set flag to 1 */ jb302@36: void jb302@36: set_flag(BYTE flag, BYTE on) { jb302@36: if (flag <= 7) { jb302@36: if (on == 0x00) { jb302@36: flags = CBIT(flags, flag); jb302@36: } jb302@36: else { jb302@36: flags = SBIT(flags, flag); jb302@36: } jb302@36: } jb302@36: } jb302@36: jb302@36: /* sets zero and parity flags based on content of byte */ jb302@36: void jb302@36: set_zp(BYTE val){ jb302@36: if (val == 0) { jb302@36: set_flag(Z, 1); jb302@36: set_flag(P, 0); jb302@36: } jb302@36: else { jb302@36: /* check parity jb302@36: * think of this as folding */ jb302@36: val ^= val >> 4; jb302@36: val ^= val >> 2; jb302@36: val ^= val >> 1; jb302@36: val &= 1; jb302@36: if (val == 0) { jb302@36: set_flag(P, 1); jb302@36: } jb302@36: else { jb302@36: set_flag(P, 0); jb302@36: } jb302@36: } jb302@36: } jb302@36: jb302@36: WIDE jb302@36: get_wide(BYTE reg) { jb302@36: /* high, low */ jb302@36: return MWIDE(regs[reg + 4], regs[reg + 12]); jb302@36: } jb302@36: jb302@36: void jb302@36: set_wide(BYTE reg, WIDE val) { jb302@36: regs[reg + 4] = GHIGH(val); /* high */ jb302@36: regs[reg + 12] = GLOW(val); /* low */ jb302@36: } jb302@36: jb302@36: void jb302@36: inc_pc(BYTE n) { jb302@36: if ((regs[PCL] + n) > 0xFF) { jb302@36: regs[PCH]++; jb302@36: } jb302@36: regs[PCL] += n; jb302@36: } jb302@36: jb302@36: BYTE jb302@36: fetch(void) { jb302@36: BYTE val = mem[get_wide(PC)]; jb302@36: inc_pc(1); jb302@36: return val; jb302@36: } jb302@36: jb302@36: WIDE jb302@36: fetch_wide(void) { jb302@36: WIDE val = MWIDE(mem[get_wide(PC)], mem[get_wide(PC) + 1]); jb302@36: inc_pc(2); jb302@36: return val; jb302@36: } jb302@36: jb302@36: /* 0b000 = R0 jb302@36: * 0b001 = R1 jb302@36: * 0b010 = R2 jb302@36: * 0b011 = R3 jb302@36: * 0b100 = DPH jb302@36: * 0b101 = DPL jb302@36: * 0b110 = SPH jb302@36: * 0b111 = SPL */ jb302@36: BYTE jb302@36: get_reg(BYTE reg) { jb302@36: if (reg < 4) { jb302@36: return regs[reg | (get_flag(BS) << 3)]; jb302@36: } jb302@36: else { jb302@36: switch (reg) { jb302@36: jb302@36: case 4: jb302@36: return regs[DPH]; jb302@36: case 5: jb302@36: return regs[DPL]; jb302@36: case 6: jb302@36: return regs[SPH]; jb302@36: case 7: jb302@36: return regs[SPL]; jb302@36: default: jb302@36: return 0; jb302@36: } jb302@36: } jb302@36: } jb302@36: jb302@36: void jb302@36: set_reg(BYTE reg, BYTE val) { jb302@36: if (reg < 4) { jb302@36: regs[reg | (get_flag(BS) << 3)] = val; jb302@36: } jb302@36: else { jb302@36: switch (reg) { jb302@36: jb302@36: case 4: jb302@36: regs[DPH] = val; jb302@36: break; jb302@36: case 5: jb302@36: regs[DPL] = val; jb302@36: break; jb302@36: case 6: jb302@36: regs[SPH] = val; jb302@36: break; jb302@36: case 7: jb302@36: regs[SPL] = val; jb302@36: break; jb302@36: default: jb302@36: break; jb302@36: } jb302@36: } jb302@36: }