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