view emu/mem.c @ 42:792da050d8c4 tip

more dox
author james <jb302@eecs.qmul.ac.uk>
date Tue, 22 Apr 2014 14:25:14 +0100
parents 4411dee34085
children
line wrap: on
line source
/* mem.c
 * functions for accessing emulator memory */
#include "mem.h"

/* get flag value
 * if invalid flag is requested value is 0 */
BYTE
get_flag(BYTE flag) {
    if (flag > 7) {
        return 0;
    }
    else {
        return GBIT(flags, flag);
    }
}

/*  set flag to 0 if on == 0
 *  otherwise set flag to 1 */
void
set_flag(BYTE flag, BYTE on) {
    if (flag <= 7) {
        if (on == 0x00) {
            flags = CBIT(flags, flag);
        }
        else {
            flags = SBIT(flags, flag);
        }
    }
}

/* sets zero and parity flags based on content of byte */
void
set_zp(BYTE val){
    if (val == 0) {
        set_flag(Z, 1);
        set_flag(P, 0);
    }
    else {
        /* check parity
         * think of this as folding */
        val ^= val >> 4;
        val ^= val >> 2;
        val ^= val >> 1;
        val &= 1;
        if (val == 0) {
            set_flag(P, 1);
        }
        else {
            set_flag(P, 0);
        }
    }
}

WIDE
get_wide(BYTE reg) {
    /* high, low */
    return MWIDE(regs[reg + 4], regs[reg + 12]);
}

void
set_wide(BYTE reg, WIDE val) {
    regs[reg + 4] = GHIGH(val); /* high */
    regs[reg + 12] = GLOW(val); /* low */
}

void 
inc_pc(BYTE n) {
    if ((regs[PCL] + n) > 0xFF) {
        regs[PCH]++;
    }
    regs[PCL] += n;
}

BYTE 
fetch(void) {
    BYTE val = mem[get_wide(PC)];
    inc_pc(1);
    return val;
}

WIDE
fetch_wide(void) {
    WIDE val = MWIDE(mem[get_wide(PC)], mem[get_wide(PC) + 1]);
    inc_pc(2);
    return val;
}

/* 0b000 = R0
 * 0b001 = R1
 * 0b010 = R2
 * 0b011 = R3
 * 0b100 = DPH
 * 0b101 = DPL
 * 0b110 = SPH
 * 0b111 = SPL */
BYTE 
get_reg(BYTE reg) {
    if (reg < 4) {
        return regs[reg | (get_flag(BS) << 3)];
    }
    else {
        switch (reg) {
            
            case 4:
                return regs[DPH];
            case 5:
                return regs[DPL];
            case 6:
                return regs[SPH];
            case 7:
                return regs[SPL];
            default:
                return 0;
        }
    }
}

void
set_reg(BYTE reg, BYTE val) {
    if (reg < 4) {
        regs[reg | (get_flag(BS) << 3)] = val;
    }
    else {
        switch (reg) {
            
            case 4:
                regs[DPH] = val;
                break;
            case 5:
                regs[DPL] = val;
                break;
            case 6:
                regs[SPH] = val;
                break;
            case 7:
                regs[SPL] = val;
                break;
            default:
                break;
        }
    }
}