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