diff --git a/csr.c b/csr.c index dd11cc1..99adcee 100644 --- a/csr.c +++ b/csr.c @@ -129,7 +129,7 @@ int csr_try_mbus_held(csr_t *csr) { return 1; } -void csr_set_access_error(csr_t *csr, int cpu, int type) { +void csr_set_access_error(csr_t *csr, int cpu, int type, int addr, int is_write) { int v=0; if (cpu==0) { if (type&ACCESS_ERROR_U) v|=ERR_UBE_DMA; @@ -138,10 +138,18 @@ void csr_set_access_error(csr_t *csr, int cpu, int type) { if (type&ACCESS_ERROR_U) v|=ERR_UBE_JOB; if (type&ACCESS_ERROR_A) v|=ERR_ABE_JOB; } - if (type&ACCESS_ERROR_MBTO) v|=ERR_MBTO; + if (type&ACCESS_ERROR_MBTO) { + v|=ERR_MBTO; + if (emu_get_mb_diag()) { + emu_raise_int(INT_VECT_MB_IF_ERR, INT_LEVEL_MB_IF_ERR, 1); + csr->reg[CSR_I_MBERR/2]=(addr>>11)&0xfe; + if (!is_write) csr->reg[CSR_I_MBERR/2]|=0x1; + } + } csr->reg[CSR_I_ERR/2]|=v; } + void csr_set_parity_error(csr_t *c, int hl) { c->reg[CSR_I_PERR1/2]&=~((1<<12)|(1<<13)); if (hl&2) c->reg[CSR_I_PERR1/2]|=(1<<12); @@ -165,6 +173,8 @@ void csr_write16(void *obj, unsigned int a, unsigned int val) { emu_enable_mapper(!(val&MISC_ENMAP)); if ((val&MISC_HOLDMBUS)==0) { val&=~MISC_TBUSY; + } else { + val|=MISC_TBUSY; } int v=0; if ((val&MISC_SCSIDL)==0) v|=SCSI_DIAG_LATCH; @@ -177,6 +187,7 @@ void csr_write16(void *obj, unsigned int a, unsigned int val) { v=0; if (val&MISC_DIAGPL) v|=1; if (val&MISC_DIAGPH) v|=2; + emu_set_force_parity_error(v); emu_set_mb_diag(val&MISC_DIAGMB); } else if (a==CSR_O_KILL) { //kill @@ -299,12 +310,9 @@ void csr_write16_mmio(void *obj, unsigned int a, unsigned int val) { } } -void csr_raise_error(csr_t *c, int error, unsigned int addr) { - if (error==CSR_ERR_MBUS) { - emu_raise_int(INT_VECT_MB_IF_ERR, INT_LEVEL_MB_IF_ERR, 1); - c->reg[CSR_I_MBERR/2]=(addr>>11)&0xfe; - if (addr&EMU_MBUS_ERROR_READ) c->reg[CSR_I_MBERR/2]|=0x1; - } +unsigned int csr_read16_mmio(void *obj, unsigned int a) { + csr_write16_mmio(obj, a, 0); + return 0; } diff --git a/csr.h b/csr.h index 188b7ac..58f4be1 100644 --- a/csr.h +++ b/csr.h @@ -9,21 +9,18 @@ void csr_write8(void *obj, unsigned int a, unsigned int val); void csr_write16(void *obj, unsigned int a, unsigned int val); void csr_write32(void *obj, unsigned int a, unsigned int val); void csr_write16_mmio(void *obj, unsigned int a, unsigned int val); +unsigned int csr_read16_mmio(void *obj, unsigned int a); csr_t *csr_new(scsi_t *scsi); int csr_cpu_is_reset(csr_t *csr, int cpu); int csr_get_rtc_int_ena(csr_t *csr, int cpu); int csr_try_mbus_held(csr_t *csr); - -#define CSR_ERR_MBUS 1 -void csr_raise_error(csr_t *c, int error, unsigned int addr); - #define ACCESS_ERROR_OK 0 #define ACCESS_ERROR_U 1 #define ACCESS_ERROR_A 2 #define ACCESS_ERROR_MBTO 3 -void csr_set_access_error(csr_t *csr, int cpu, int type); +void csr_set_access_error(csr_t *csr, int cpu, int type, int addr, int is_write); void csr_set_parity_error(csr_t *c, int hl); \ No newline at end of file diff --git a/emu.c b/emu.c index 25d184c..7edd228 100644 --- a/emu.c +++ b/emu.c @@ -174,7 +174,7 @@ static int check_can_access(mem_range_t *m, unsigned int address) { ret=0; } if (!ret) { - csr_set_access_error(csr, cur_cpu, ACCESS_ERROR_A); + csr_set_access_error(csr, cur_cpu, ACCESS_ERROR_A, address, 0); m68k_pulse_bus_error(); } return ret; @@ -307,17 +307,17 @@ void emu_set_cur_mapid(uint8_t id) { //thing to actually throw the error. static int check_mem_access(unsigned int address, int flags) { - static int recursive_error=0; if (!mapper_enabled) return 1; if ((fc_bits&3)==2) flags=ACCESS_X; if (fc_bits&4) flags|=ACCESS_SYSTEM; int access=mapper_access_allowed(mapper, address, flags); if (access!=ACCESS_ERROR_OK) { - EMU_LOG_DEBUG("Bus error! Access %x\n", address); -// if (address==0x1000) do_tracefile=1; - dump_cpu_state(); - dump_callstack(); - csr_set_access_error(csr, cur_cpu, access); + if (log_level_active(LOG_SRC_MAPPER, LOG_DEBUG)) { + EMU_LOG_INFO("Illegal access! Access %x\n", address); + dump_cpu_state(); + dump_callstack(); + } + csr_set_access_error(csr, cur_cpu, access, address, flags&ACCESS_W); //note THIS WILL NOT RETURN! //(m68ki_exception_bus_error ends with a longjmp) @@ -455,13 +455,9 @@ int emu_write_byte(int addr, int val) { } void emu_mbus_error(unsigned int addr) { - mem_range_t *r=find_range_by_name("CSR"); - if (addr&EMU_MBUS_ERROR_TIMEOUT) { - csr_set_access_error(csr, 1, ACCESS_ERROR_MBTO); + csr_set_access_error(csr, 1, ACCESS_ERROR_MBTO, addr&0xffffff, !(addr&EMU_MBUS_ERROR_READ)); + if (addr&EMU_MBUS_BUSERROR) { emu_bus_error(); - } else { - csr_t *c=(csr_t*)r->obj; - csr_raise_error(c, CSR_ERR_MBUS, addr); } } @@ -537,6 +533,7 @@ csr_t *setup_csr(const char *name, const char *mmio_name, const char *scsi_name) m->read16=csr_read16; m->read8=csr_read8; mm->write16=csr_write16_mmio; + mm->read16=csr_read16_mmio; return r; } @@ -604,9 +601,7 @@ void setup_mbus(const char *name, const char *ioname) { //1 if held int emu_try_mbus_held() { - mem_range_t *r=find_range_by_name("CSR"); - csr_t *c=(csr_t*)r->obj; - return csr_try_mbus_held(c); + return csr_try_mbus_held(csr); } void setup_nop(const char *name) { diff --git a/emu.h b/emu.h index cfea314..24bb3de 100644 --- a/emu.h +++ b/emu.h @@ -35,5 +35,5 @@ void emu_start(emu_cfg_t *cfg); void emu_schedule_int_us(int us); #define EMU_MBUS_ERROR_READ 0x80000000 -#define EMU_MBUS_ERROR_TIMEOUT 0x40000000 +#define EMU_MBUS_BUSERROR 0x40000000 void emu_mbus_error(unsigned int addr); diff --git a/log.c b/log.c index ee57e6c..0e76221 100644 --- a/log.c +++ b/log.c @@ -46,6 +46,10 @@ void log_set_level(enum log_source source, enum log_level msg_level) { log_channel_verbose_level[source]=msg_level; } +int log_level_active(enum log_source source, enum log_level msg_level) { + return log_channel_verbose_level[source] >= msg_level; +} + int log_printf(enum log_source source, enum log_level msg_level, const char *format, ...) { static_assert(sizeof(log_channel_verbose_level)/sizeof(log_channel_verbose_level[0])==LOG_SRC_MAX, "log_channel_verbose_level missing an entry"); diff --git a/log.h b/log.h index 8024edf..e1af0ee 100644 --- a/log.h +++ b/log.h @@ -28,5 +28,6 @@ enum log_level { void log_set_level(enum log_source source, enum log_level msg_level); int log_printf(enum log_source source, enum log_level msg_level, const char *format, ...); +int log_level_active(enum log_source source, enum log_level msg_level); #endif diff --git a/mapper.c b/mapper.c index d5a0432..056c37b 100644 --- a/mapper.c +++ b/mapper.c @@ -94,7 +94,7 @@ int mapper_access_allowed(mapper_t *m, unsigned int a, int access_flags) { assert(p<=2048 && "out of range addr"); if (access_flags&ACCESS_SYSTEM) p+=2048; int r=access_allowed_page(m, p, access_flags); - if (r) { + if (r && log_level_active(LOG_SRC_MAPPER, LOG_DEBUG)) { MAPPER_LOG_DEBUG("Mapper: Access fault at addr %x page %d. CPU state:\n", a, p); dump_cpu_state(); dump_callstack(); diff --git a/mbus.c b/mbus.c index 4f3135a..9c89df5 100644 --- a/mbus.c +++ b/mbus.c @@ -21,54 +21,37 @@ but they obvs can't do that for 8-bit writes/reads. So 16-bit writes go through transparently, but a write/read to 8-bit address x happens to x^1 :X */ - - - static int mbus_held() { if (!emu_try_mbus_held()) return 0; MBUS_LOG_DEBUG("Blocking op: bus held\n"); return 1; } -static int on_wrong_cpu(int addr) { - int r=emu_get_cur_cpu(); - if (r==1) return 0; - MBUS_LOG_NOTICE("Mbus access to %x from wrong CPU\n", addr); - emu_bus_error(); - return 1; -} - - - void mbus_write8(void *obj, unsigned int a, unsigned int val) { - if (on_wrong_cpu(a)) return; MBUS_LOG_DEBUG("MBUS: wb %x->%x %x\n", a, a+0x780000, val); if (mbus_held()) { MBUS_LOG_NOTICE("MBUS: ^^ write held.\n"); return; } if (!emu_get_mb_diag()){ -// emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT); return; } int r=emu_write_byte((a+0x780000)^1, val); - if (!r) emu_mbus_error(a); + if (r==-1) emu_mbus_error(a); } void mbus_write16(void *obj, unsigned int a, unsigned int val) { - if (on_wrong_cpu(a)) return; MBUS_LOG_DEBUG("MBUS: ww %x->%x %x\n", a, a+0x780000, val); if (mbus_held()) { MBUS_LOG_NOTICE("MBUS: ^^ write held.\n"); return; } if (!emu_get_mb_diag()){ -// emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT); return; } int r=emu_write_byte((a+0x780000), val>>8); - r&=emu_write_byte((a+0x780001), val); - if (!r) emu_mbus_error(a); + r+=emu_write_byte((a+0x780001), val); + if (r<0) emu_mbus_error(a); } void mbus_write32(void *obj, unsigned int a, unsigned int val) { @@ -77,21 +60,18 @@ void mbus_write32(void *obj, unsigned int a, unsigned int val) { } unsigned int mbus_read8(void *obj, unsigned int a) { - if (on_wrong_cpu(a)) return 0; MBUS_LOG_DEBUG("MBUS: rb %x->%x\n", a, a+0x780000); + if (!emu_get_mb_diag()) return 0; //Mbus in diag modes errors with a MBTO. - emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT); + emu_mbus_error(a|EMU_MBUS_BUSERROR); return 0; } unsigned int mbus_read16(void *obj, unsigned int a) { - if (on_wrong_cpu(a)) return 0; MBUS_LOG_DEBUG("MBUS: rw %x->%x\n", a, a+0x780000); - if (!emu_get_mb_diag()){ - return 0; - } + if (!emu_get_mb_diag()) return 0; //Mbus in diag modes errors with a MBTO. - emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT); + emu_mbus_error(a|EMU_MBUS_BUSERROR); return 0; } @@ -101,13 +81,14 @@ unsigned int mbus_read32(void *obj, unsigned int a) { void mbus_io_write(void *obj, unsigned int a, unsigned int val) { if (emu_get_mb_diag()) return; -// printf("mbio wr %x\n", a); - emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT); + MBUS_LOG_DEBUG("mbio wr %x\n", a); + emu_mbus_error(a|EMU_MBUS_BUSERROR); } unsigned int mbus_io_read(void *obj, unsigned int a) { if (emu_get_mb_diag()) return 0; - emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT); + MBUS_LOG_DEBUG("mbio rd %x\n", a); + emu_mbus_error(a|EMU_MBUS_ERROR_READ|EMU_MBUS_BUSERROR); return 0; } diff --git a/rtc.c b/rtc.c index 942dd3f..6804de3 100644 --- a/rtc.c +++ b/rtc.c @@ -111,7 +111,8 @@ void rtc_write8(void *obj, unsigned int a, unsigned int val) { } handle_irq(r); if (a!=CALREGC && a!=CALREGD) r->reg[a]=val; - rtc_sanitize_vals(r); + //Sanitize values if clock is running + if (!(r->reg[CALREGB]&0x80)) rtc_sanitize_vals(r); } void rtc_write16(void *obj, unsigned int a, unsigned int val) {