X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=simavr%2Fsim%2Fsim_core.c;h=31c2ab35c94fb9c5b628e3461d11d3e9ad80396b;hb=2f67001d;hp=a8df91d2dca9ed62dc799c3ed94ab8ef77fa6a71;hpb=163dd8199d1c63b6321ea54bb382339a3b35a5e3;p=simavr diff --git a/simavr/sim/sim_core.c b/simavr/sim/sim_core.c index a8df91d..31c2ab3 100644 --- a/simavr/sim/sim_core.c +++ b/simavr/sim/sim_core.c @@ -130,10 +130,10 @@ static inline void _avr_set_r(avr_t * avr, uint8_t r, uint8_t v) REG_TOUCH(avr, r); if (r == R_SREG) { - avr->data[r] = v; + avr->data[R_SREG] = v; // unsplit the SREG for (int i = 0; i < 8; i++) - avr->sreg[i] = (avr->data[R_SREG] & (1 << i)) != 0; + avr->sreg[i] = (v & (1 << i)) != 0; SREG(); } if (r > 31) { @@ -181,8 +181,22 @@ static inline void _avr_set_ram(avr_t * avr, uint16_t addr, uint8_t v) */ static inline uint8_t _avr_get_ram(avr_t * avr, uint16_t addr) { - if (addr > 31 && addr < 256) { + if (addr == R_SREG) { + /* + * SREG is special it's reconstructed when read + * while the core itself uses the "shortcut" array + */ + avr->data[R_SREG] = 0; + for (int i = 0; i < 8; i++) + if (avr->sreg[i] > 1) { + printf("** Invalid SREG!!\n"); + CRASH(); + } else if (avr->sreg[i]) + avr->data[R_SREG] |= (1 << i); + + } else if (addr > 31 && addr < 256) { uint8_t io = AVR_DATA_TO_IO(addr); + if (avr->io[io].r.c) avr->data[addr] = avr->io[io].r.c(avr, addr, avr->io[io].r.param); @@ -301,7 +315,7 @@ void avr_dump_state(avr_t * avr) #define get_r_d_10(o) \ const uint8_t r = ((o >> 5) & 0x10) | (o & 0xf); \ const uint8_t d = (o >> 4) & 0x1f;\ - const uint8_t vd = avr->data[d], vr =avr->data[r]; + const uint8_t vd = avr->data[d], vr = avr->data[r]; #define get_k_r16(o) \ const uint8_t r = 16 + ((o >> 4) & 0xf); \ const uint8_t k = ((o & 0x0f00) >> 4) | (o & 0xf); @@ -1197,15 +1211,12 @@ uint16_t avr_run_one(avr_t * avr) uint8_t r = (opcode >> 4) & 0x1f; uint8_t A = ((((opcode >> 9) & 3) << 4) | ((opcode) & 0xf)) + 32; STATE("out %s, %s[%02x]\n", avr_regname(A), avr_regname(r), avr->data[r]); - // todo: store to IO register _avr_set_ram(avr, A, avr->data[r]); - // avr->data[A] = ; } break; case 0xb000: { // IN Rd,A 1011 0AAr rrrr AAAA uint8_t r = (opcode >> 4) & 0x1f; uint8_t A = ((((opcode >> 9) & 3) << 4) | ((opcode) & 0xf)) + 32; STATE("in %s, %s[%02x]\n", avr_regname(r), avr_regname(A), avr->data[A]); - // todo: get the IO register _avr_set_r(avr, r, _avr_get_ram(avr, A)); } break; default: _avr_invalid_opcode(avr);