📄 cbus.c
字号:
#endif switch (reg) { case RETU_REG_IDR: s->irqst ^= val; retu_interrupt_update(s); break; case RETU_REG_IMR: s->irqen = val; retu_interrupt_update(s); break; case RETU_REG_RTCDSR: case RETU_REG_RTCHMAR: /* TODO */ break; case RETU_REG_RTCCALR: s->rtc.cal = val; break; case RETU_REG_ADCR: s->channel = (val >> 10) & 0xf; s->irqst |= 1 << retu_int_adcs; retu_interrupt_update(s); break; case RETU_REG_ADCSCR: s->sample &= ~val; break; case RETU_REG_AFCR: case RETU_REG_ANTIFR: case RETU_REG_CALIBR: case RETU_REG_CCR1: s->cc[0] = val; break; case RETU_REG_CCR2: s->cc[1] = val; break; case RETU_REG_RCTRL_CLR: case RETU_REG_RCTRL_SET: /* TODO */ break; case RETU_REG_WATCHDOG: if (val == 0 && (s->cc[0] & 2)) qemu_system_shutdown_request(); break; case RETU_REG_TXCR: case RETU_REG_AUDTXR: case RETU_REG_AUDPAR: case RETU_REG_AUDRXR1: case RETU_REG_AUDRXR2: case RETU_REG_SGR1: case RETU_REG_SCR1: case RETU_REG_SGR2: case RETU_REG_SCR2: /* TODO */ break; default: cpu_abort(cpu_single_env, "%s: bad register %02x\n", __FUNCTION__, reg); }}static void retu_io(void *opaque, int rw, int reg, uint16_t *val){ struct cbus_retu_s *s = (struct cbus_retu_s *) opaque; if (rw) *val = retu_read(s, reg); else retu_write(s, reg, *val);}void *retu_init(qemu_irq irq, int vilma){ struct cbus_retu_s *s = (struct cbus_retu_s *) qemu_mallocz(sizeof(*s)); s->irq = irq; s->irqen = 0xffff; s->irqst = 0x0000; s->status = 0x0020; s->is_vilma = !!vilma; s->rtc.cal = 0x01; s->result[retu_adc_bsi] = 0x3c2; s->result[retu_adc_batt_temp] = 0x0fc; s->result[retu_adc_chg_volt] = 0x165; s->result[retu_adc_head_det] = 123; s->result[retu_adc_hook_det] = 1023; s->result[retu_adc_rf_gp] = 0x11; s->result[retu_adc_tx_det] = 0x11; s->result[retu_adc_batt_volt] = 0x250; s->result[retu_adc_sens] = 2; s->result[retu_adc_sens_temp] = 0x11; s->result[retu_adc_bbatt_volt] = 0x3d0; s->result[retu_adc_self_temp] = 0x330; s->cbus.opaque = s; s->cbus.io = retu_io; s->cbus.addr = 1; return &s->cbus;}void retu_key_event(void *retu, int state){ struct cbus_slave_s *slave = (struct cbus_slave_s *) retu; struct cbus_retu_s *s = (struct cbus_retu_s *) slave->opaque; s->irqst |= 1 << retu_int_pwr; retu_interrupt_update(s); if (state) s->status &= ~(1 << 5); else s->status |= 1 << 5;}void retu_head_event(void *retu, int state){ struct cbus_slave_s *slave = (struct cbus_slave_s *) retu; struct cbus_retu_s *s = (struct cbus_retu_s *) slave->opaque; if ((s->cc[0] & 0x500) == 0x500) { /* TODO: Which bits? */ /* TODO: reissue the interrupt every 100ms or so. */ s->irqst |= 1 << retu_int_head; retu_interrupt_update(s); } if (state) s->result[retu_adc_head_det] = 50; else s->result[retu_adc_head_det] = 123;}void retu_hook_event(void *retu, int state){ struct cbus_slave_s *slave = (struct cbus_slave_s *) retu; struct cbus_retu_s *s = (struct cbus_retu_s *) slave->opaque; if ((s->cc[0] & 0x500) == 0x500) { /* TODO: reissue the interrupt every 100ms or so. */ s->irqst |= 1 << retu_int_hook; retu_interrupt_update(s); } if (state) s->result[retu_adc_hook_det] = 50; else s->result[retu_adc_hook_det] = 123;}/* Tahvo/Betty */struct cbus_tahvo_s { uint16_t irqst; uint16_t irqen; uint8_t charger; uint8_t backlight; uint16_t usbr; uint16_t power; int is_betty; qemu_irq irq; struct cbus_slave_s cbus;};static void tahvo_interrupt_update(struct cbus_tahvo_s *s){ qemu_set_irq(s->irq, s->irqst & ~s->irqen);}#define TAHVO_REG_ASICR 0x00 /* (RO) ASIC ID & revision */#define TAHVO_REG_IDR 0x01 /* (T) Interrupt ID */#define TAHVO_REG_IDSR 0x02 /* (RO) Interrupt status */#define TAHVO_REG_IMR 0x03 /* (RW) Interrupt mask */#define TAHVO_REG_CHAPWMR 0x04 /* (RW) Charger PWM */#define TAHVO_REG_LEDPWMR 0x05 /* (RW) LED PWM */#define TAHVO_REG_USBR 0x06 /* (RW) USB control */#define TAHVO_REG_RCR 0x07 /* (RW) Some kind of power management */#define TAHVO_REG_CCR1 0x08 /* (RW) Common control register 1 */#define TAHVO_REG_CCR2 0x09 /* (RW) Common control register 2 */#define TAHVO_REG_TESTR1 0x0a /* (RW) Test register 1 */#define TAHVO_REG_TESTR2 0x0b /* (RW) Test register 2 */#define TAHVO_REG_NOPR 0x0c /* (RW) Number of periods */#define TAHVO_REG_FRR 0x0d /* (RO) FR */static inline uint16_t tahvo_read(struct cbus_tahvo_s *s, int reg){#ifdef DEBUG printf("TAHVO read at %02x\n", reg);#endif switch (reg) { case TAHVO_REG_ASICR: return 0x0021 | (s->is_betty ? 0x0b00 : 0x0300); /* 22 in N810 */ case TAHVO_REG_IDR: case TAHVO_REG_IDSR: /* XXX: what does this do? */ return s->irqst; case TAHVO_REG_IMR: return s->irqen; case TAHVO_REG_CHAPWMR: return s->charger; case TAHVO_REG_LEDPWMR: return s->backlight; case TAHVO_REG_USBR: return s->usbr; case TAHVO_REG_RCR: return s->power; case TAHVO_REG_CCR1: case TAHVO_REG_CCR2: case TAHVO_REG_TESTR1: case TAHVO_REG_TESTR2: case TAHVO_REG_NOPR: case TAHVO_REG_FRR: return 0x0000; default: cpu_abort(cpu_single_env, "%s: bad register %02x\n", __FUNCTION__, reg); }}static inline void tahvo_write(struct cbus_tahvo_s *s, int reg, uint16_t val){#ifdef DEBUG printf("TAHVO write of %04x at %02x\n", val, reg);#endif switch (reg) { case TAHVO_REG_IDR: s->irqst ^= val; tahvo_interrupt_update(s); break; case TAHVO_REG_IMR: s->irqen = val; tahvo_interrupt_update(s); break; case TAHVO_REG_CHAPWMR: s->charger = val; break; case TAHVO_REG_LEDPWMR: if (s->backlight != (val & 0x7f)) { s->backlight = val & 0x7f; printf("%s: LCD backlight now at %i / 127\n", __FUNCTION__, s->backlight); } break; case TAHVO_REG_USBR: s->usbr = val; break; case TAHVO_REG_RCR: s->power = val; break; case TAHVO_REG_CCR1: case TAHVO_REG_CCR2: case TAHVO_REG_TESTR1: case TAHVO_REG_TESTR2: case TAHVO_REG_NOPR: case TAHVO_REG_FRR: break; default: cpu_abort(cpu_single_env, "%s: bad register %02x\n", __FUNCTION__, reg); }}static void tahvo_io(void *opaque, int rw, int reg, uint16_t *val){ struct cbus_tahvo_s *s = (struct cbus_tahvo_s *) opaque; if (rw) *val = tahvo_read(s, reg); else tahvo_write(s, reg, *val);}void *tahvo_init(qemu_irq irq, int betty){ struct cbus_tahvo_s *s = (struct cbus_tahvo_s *) qemu_mallocz(sizeof(*s)); s->irq = irq; s->irqen = 0xffff; s->irqst = 0x0000; s->is_betty = !!betty; s->cbus.opaque = s; s->cbus.io = tahvo_io; s->cbus.addr = 2; return &s->cbus;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -