Mercurial > hg > ede
annotate emu/mem.c @ 30:c0c2e99b6bb0
fixed negative rel8 address bug in assembler
author | james <jb302@eecs.qmul.ac.uk> |
---|---|
date | Tue, 15 Apr 2014 12:21:22 +0100 |
parents | 83e80c2c489c |
children | 4411dee34085 |
rev | line source |
---|---|
jb302@28 | 1 /* mem.c |
jb302@28 | 2 * functions for accessing emulator memory */ |
jb302@28 | 3 #include "mem.h" |
jb302@28 | 4 |
jb302@28 | 5 /* get flag value |
jb302@28 | 6 * if invalid flag is requested value is 0 */ |
jb302@28 | 7 BYTE |
jb302@28 | 8 get_flag(BYTE flag) { |
jb302@28 | 9 if (flag > 7) { |
jb302@28 | 10 return 0; |
jb302@28 | 11 } |
jb302@28 | 12 else { |
jb302@28 | 13 return GBIT(flags, flag); |
jb302@28 | 14 } |
jb302@28 | 15 } |
jb302@28 | 16 |
jb302@28 | 17 /* set flag to 0 if on == 0 |
jb302@28 | 18 * otherwise set flag to 1 */ |
jb302@28 | 19 void |
jb302@28 | 20 set_flag(BYTE flag, BYTE on) { |
jb302@28 | 21 if (flag <= 7) { |
jb302@29 | 22 if (on == 0x00) { |
jb302@29 | 23 flags = CBIT(flags, flag); |
jb302@29 | 24 } |
jb302@29 | 25 else { |
jb302@29 | 26 flags = SBIT(flags, flag); |
jb302@28 | 27 } |
jb302@28 | 28 } |
jb302@28 | 29 } |
jb302@28 | 30 |
jb302@30 | 31 /* sets zero and parity flags based on content of byte */ |
jb302@30 | 32 void |
jb302@30 | 33 set_zp(BYTE val){ |
jb302@30 | 34 if (val == 0) { |
jb302@30 | 35 set_flag(Z, 1); |
jb302@30 | 36 set_flag(P, 0); |
jb302@30 | 37 } |
jb302@30 | 38 else { |
jb302@30 | 39 /* think of this as folding */ |
jb302@30 | 40 val ^= val >> 4; |
jb302@30 | 41 val ^= val >> 2; |
jb302@30 | 42 val ^= val >> 1; |
jb302@30 | 43 val &= 1; |
jb302@30 | 44 if (val == 0) { |
jb302@30 | 45 set_flag(P, 1); |
jb302@30 | 46 } |
jb302@30 | 47 else { |
jb302@30 | 48 set_flag(P, 0); |
jb302@30 | 49 } |
jb302@30 | 50 } |
jb302@30 | 51 } |
jb302@30 | 52 |
jb302@28 | 53 WIDE |
jb302@28 | 54 get_wide(BYTE reg) { |
jb302@29 | 55 /* high, low */ |
jb302@29 | 56 return MWIDE(regs[reg + 4], regs[reg + 12]); |
jb302@28 | 57 } |
jb302@28 | 58 |
jb302@28 | 59 void |
jb302@28 | 60 set_wide(BYTE reg, WIDE val) { |
jb302@29 | 61 regs[reg + 4] = GHIGH(val); /* high */ |
jb302@29 | 62 regs[reg + 12] = GLOW(val); /* low */ |
jb302@28 | 63 } |
jb302@28 | 64 |
jb302@28 | 65 void |
jb302@28 | 66 inc_pc(BYTE n) { |
jb302@28 | 67 if ((regs[PCL] + n) > 0xFF) { |
jb302@28 | 68 regs[PCH]++; |
jb302@28 | 69 } |
jb302@28 | 70 regs[PCL] += n; |
jb302@28 | 71 } |
jb302@28 | 72 |
jb302@28 | 73 BYTE |
jb302@28 | 74 fetch(void) { |
jb302@28 | 75 BYTE val = mem[get_wide(PC)]; |
jb302@28 | 76 inc_pc(1); |
jb302@28 | 77 return val; |
jb302@28 | 78 } |
jb302@28 | 79 |
jb302@28 | 80 WIDE |
jb302@28 | 81 fetch_wide(void) { |
jb302@30 | 82 WIDE val = MWIDE(mem[get_wide(PC)], mem[get_wide(PC) + 1]); |
jb302@28 | 83 inc_pc(2); |
jb302@28 | 84 return val; |
jb302@28 | 85 } |
jb302@28 | 86 |
jb302@29 | 87 /* 0b000 = R0 |
jb302@29 | 88 * 0b001 = R1 |
jb302@29 | 89 * 0b010 = R2 |
jb302@29 | 90 * 0b011 = R3 |
jb302@29 | 91 * 0b100 = DPH |
jb302@29 | 92 * 0b101 = DPL |
jb302@29 | 93 * 0b110 = SPH |
jb302@29 | 94 * 0b111 = SPL */ |
jb302@29 | 95 BYTE |
jb302@29 | 96 get_reg(BYTE reg) { |
jb302@29 | 97 if (reg < 4) { |
jb302@29 | 98 return regs[reg | (get_flag(BS) << 3)]; |
jb302@29 | 99 } |
jb302@29 | 100 else { |
jb302@29 | 101 switch (reg) { |
jb302@29 | 102 |
jb302@29 | 103 case 4: |
jb302@29 | 104 return regs[DPH]; |
jb302@29 | 105 case 5: |
jb302@29 | 106 return regs[DPL]; |
jb302@29 | 107 case 6: |
jb302@29 | 108 return regs[SPH]; |
jb302@29 | 109 case 7: |
jb302@29 | 110 return regs[SPL]; |
jb302@29 | 111 default: |
jb302@29 | 112 return 0; |
jb302@29 | 113 } |
jb302@29 | 114 } |
jb302@29 | 115 } |
jb302@28 | 116 |
jb302@29 | 117 void |
jb302@29 | 118 set_reg(BYTE reg, BYTE val) { |
jb302@29 | 119 if (reg < 4) { |
jb302@29 | 120 regs[reg | (get_flag(BS) << 3)] = val; |
jb302@29 | 121 } |
jb302@29 | 122 else { |
jb302@29 | 123 switch (reg) { |
jb302@29 | 124 |
jb302@29 | 125 case 4: |
jb302@29 | 126 regs[DPH] = val; |
jb302@29 | 127 break; |
jb302@29 | 128 case 5: |
jb302@29 | 129 regs[DPL] = val; |
jb302@29 | 130 break; |
jb302@29 | 131 case 6: |
jb302@29 | 132 regs[SPH] = val; |
jb302@29 | 133 break; |
jb302@29 | 134 case 7: |
jb302@29 | 135 regs[SPL] = val; |
jb302@29 | 136 break; |
jb302@29 | 137 default: |
jb302@29 | 138 break; |
jb302@29 | 139 } |
jb302@29 | 140 } |
jb302@29 | 141 } |