diff options
-rw-r--r-- | src/devices/cpu/h8/h8.cpp | 6 | ||||
-rw-r--r-- | src/devices/cpu/h8/h8.lst | 12 | ||||
-rw-r--r-- | src/devices/cpu/h8/h83002.cpp | 57 | ||||
-rw-r--r-- | src/devices/cpu/h8/h83002.h | 18 | ||||
-rw-r--r-- | src/devices/cpu/h8/h8_dma.cpp | 123 | ||||
-rw-r--r-- | src/devices/cpu/h8/h8_dma.h | 32 |
6 files changed, 233 insertions, 15 deletions
diff --git a/src/devices/cpu/h8/h8.cpp b/src/devices/cpu/h8/h8.cpp index 6d62453a2ff..f572063e186 100644 --- a/src/devices/cpu/h8/h8.cpp +++ b/src/devices/cpu/h8/h8.cpp @@ -145,9 +145,9 @@ void h8_device::set_current_dma(h8_dma_state *state) if(!state) logerror("DMA done\n"); else - logerror("New current dma s=%x d=%x is=%d id=%d count=%x m=%d\n", + logerror("New current dma s=%x d=%x is=%d id=%d count=%x m=%d autoreq=%d\n", state->source, state->dest, state->incs, state->incd, - state->count, state->mode_16 ? 16 : 8); + state->count, state->mode_16 ? 16 : 8, state->autoreq); } @@ -620,7 +620,7 @@ void h8_device::prefetch_done() if(requested_state != -1) { inst_state = requested_state; requested_state = -1; - } else if(current_dma) + } else if(current_dma && !current_dma->suspended) inst_state = STATE_DMA; else if(current_dtc) inst_state = STATE_DTC; diff --git a/src/devices/cpu/h8/h8.lst b/src/devices/cpu/h8/h8.lst index 600deb94c95..3edcc8c35e6 100644 --- a/src/devices/cpu/h8/h8.lst +++ b/src/devices/cpu/h8/h8.lst @@ -176,6 +176,8 @@ macro jsr32 %opc %spreg prefetch_noirq(); 10003 dma + if(current_dma->count == 1) + dma_device->count_last(current_dma->id); if(current_dma->mode_16) { TMP1 = read16(current_dma->source); write16(current_dma->dest, TMP1); @@ -186,6 +188,8 @@ macro jsr32 %opc %spreg current_dma->source += current_dma->incs; current_dma->dest += current_dma->incd; current_dma->count--; + if(!current_dma->autoreq) + current_dma->suspended = true; if(!current_dma->count) { uint8_t id = current_dma->id; current_dma = nullptr; @@ -2441,22 +2445,22 @@ macro jsr32 %opc %spreg prefetch(); 7b5c598f ffffffff 0 eepmov.b - - o - while(r8_r(4)) { + while(r8_r(4+8)) { TMP1 = read8(r16_r(5)); write8(r16_r(6), TMP1); r16_w(5, r16_r(5)+1); r16_w(6, r16_r(6)+1); - r8_w(4, r8_r(4)-1); + r8_w(4+8, r8_r(4+8)-1); } prefetch(); 7b5c598f ffffffff 0 eepmov.b - - h - while(r8_r(4)) { + while(r8_r(4+8)) { TMP1 = read8(r32_r(5)); write8(r32_r(6), TMP1); r32_w(5, r32_r(5)+1); r32_w(6, r32_r(6)+1); - r8_w(4, r8_r(4)-1); + r8_w(4+8, r8_r(4+8)-1); } prefetch(); diff --git a/src/devices/cpu/h8/h83002.cpp b/src/devices/cpu/h8/h83002.cpp index cc2ca77860e..569e78cec41 100644 --- a/src/devices/cpu/h8/h83002.cpp +++ b/src/devices/cpu/h8/h83002.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Olivier Galibert +// copyright-holders:Olivier Galibert #include "emu.h" #include "h83002.h" @@ -9,6 +9,9 @@ h83002_device::h83002_device(const machine_config &mconfig, const char *tag, dev h8h_device(mconfig, H83002, "H8/3002", tag, owner, clock, "h83002", __FILE__, address_map_delegate(FUNC(h83002_device::map), this)), intc(*this, "intc"), adc(*this, "adc"), + dma(*this, "dma"), + dma0(*this, "dma:0"), + dma1(*this, "dma:1"), port4(*this, "port4"), port6(*this, "port6"), port7(*this, "port7"), @@ -24,7 +27,9 @@ h83002_device::h83002_device(const machine_config &mconfig, const char *tag, dev timer16_4(*this, "timer16:4"), sci0(*this, "sci0"), sci1(*this, "sci1"), - watchdog(*this, "watchdog") + watchdog(*this, "watchdog"), + tend0_cb(*this), + tend1_cb(*this) { syscr = 0; } @@ -32,6 +37,10 @@ h83002_device::h83002_device(const machine_config &mconfig, const char *tag, dev static MACHINE_CONFIG_FRAGMENT(h83002) MCFG_H8H_INTC_ADD("intc") MCFG_H8_ADC_3337_ADD("adc", "intc", 60) + MCFG_H8_DMA_ADD("dma") + // (H8/2002.pdf) Table 8-11 DMAC Activation Sources + MCFG_H8_DMA_CHANNEL_ADD("dma:0", "intc", 44, h8_dma_channel_device::NONE, 24, h8_dma_channel_device::DREQ_EDGE, h8_dma_channel_device::DREQ_LEVEL, 28, 32, 36, 54, 53, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE) + MCFG_H8_DMA_CHANNEL_ADD("dma:1", "intc", 46, h8_dma_channel_device::NONE, 24, h8_dma_channel_device::DREQ_EDGE, h8_dma_channel_device::DREQ_LEVEL, 28, 32, 36, 54, 53, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE) MCFG_H8_PORT_ADD("port4", h8_device::PORT_4, 0x00, 0x00) MCFG_H8_PORT_ADD("port6", h8_device::PORT_6, 0x80, 0x80) MCFG_H8_PORT_ADD("port7", h8_device::PORT_7, 0x00, 0x00) @@ -53,6 +62,24 @@ MACHINE_CONFIG_END DEVICE_ADDRESS_MAP_START(map, 16, h83002_device) AM_RANGE(0xfffd10, 0xffff0f) AM_RAM + // DMA: only full address mode supported + AM_RANGE(0xffff20, 0xffff21) AM_DEVREADWRITE( "dma:0", h8_dma_channel_device, marah_r, marah_w ) + AM_RANGE(0xffff22, 0xffff23) AM_DEVREADWRITE( "dma:0", h8_dma_channel_device, maral_r, maral_w ) + AM_RANGE(0xffff24, 0xffff25) AM_DEVREADWRITE( "dma:0", h8_dma_channel_device, etcra_r, etcra_w ) + AM_RANGE(0xffff26, 0xffff27) AM_DEVREADWRITE8("dma:0", h8_dma_channel_device, dtcra_r, dtcra_w, 0x00ff ) + AM_RANGE(0xffff28, 0xffff29) AM_DEVREADWRITE( "dma:0", h8_dma_channel_device, marbh_r, marbh_w ) + AM_RANGE(0xffff2a, 0xffff2b) AM_DEVREADWRITE( "dma:0", h8_dma_channel_device, marbl_r, marbl_w ) + AM_RANGE(0xffff2c, 0xffff2d) AM_DEVREADWRITE( "dma:0", h8_dma_channel_device, etcrb_r, etcrb_w ) + AM_RANGE(0xffff2e, 0xffff2f) AM_DEVREADWRITE8("dma:0", h8_dma_channel_device, dtcrb_r, dtcrb_w, 0x00ff ) + AM_RANGE(0xffff30, 0xffff31) AM_DEVREADWRITE( "dma:1", h8_dma_channel_device, marah_r, marah_w ) + AM_RANGE(0xffff32, 0xffff33) AM_DEVREADWRITE( "dma:1", h8_dma_channel_device, maral_r, maral_w ) + AM_RANGE(0xffff34, 0xffff35) AM_DEVREADWRITE( "dma:1", h8_dma_channel_device, etcra_r, etcra_w ) + AM_RANGE(0xffff36, 0xffff37) AM_DEVREADWRITE8("dma:1", h8_dma_channel_device, dtcra_r, dtcra_w, 0x00ff ) + AM_RANGE(0xffff38, 0xffff39) AM_DEVREADWRITE( "dma:1", h8_dma_channel_device, marbh_r, marbh_w ) + AM_RANGE(0xffff3a, 0xffff3b) AM_DEVREADWRITE( "dma:1", h8_dma_channel_device, marbl_r, marbl_w ) + AM_RANGE(0xffff3c, 0xffff3d) AM_DEVREADWRITE( "dma:1", h8_dma_channel_device, etcrb_r, etcrb_w ) + AM_RANGE(0xffff3e, 0xffff3f) AM_DEVREADWRITE8("dma:1", h8_dma_channel_device, dtcrb_r, dtcrb_w, 0x00ff ) + AM_RANGE(0xffff60, 0xffff61) AM_DEVREADWRITE8("timer16", h8_timer16_device, tstr_r, tstr_w, 0xff00) AM_RANGE(0xffff60, 0xffff61) AM_DEVREADWRITE8("timer16", h8_timer16_device, tsyr_r, tsyr_w, 0x00ff) AM_RANGE(0xffff62, 0xffff63) AM_DEVREADWRITE8("timer16", h8_timer16_device, tmdr_r, tmdr_w, 0xff00) @@ -94,6 +121,7 @@ DEVICE_ADDRESS_MAP_START(map, 16, h83002_device) AM_RANGE(0xffffa8, 0xffffa9) AM_DEVREADWRITE( "watchdog", h8_watchdog_device, wd_r, wd_w ) AM_RANGE(0xffffaa, 0xffffab) AM_DEVREADWRITE( "watchdog", h8_watchdog_device, rst_r, rst_w ) + AM_RANGE(0xffffac, 0xffffad) AM_READWRITE8( rtmcsr_r,rtmcsr_w,0x00ff) AM_RANGE(0xffffb0, 0xffffb1) AM_DEVREADWRITE8("sci0", h8_sci_device, smr_r, smr_w, 0xff00) AM_RANGE(0xffffb0, 0xffffb1) AM_DEVREADWRITE8("sci0", h8_sci_device, brr_r, brr_w, 0x00ff) @@ -140,7 +168,14 @@ machine_config_constructor h83002_device::device_mconfig_additions() const void h83002_device::execute_set_input(int inputnum, int state) { - intc->set_input(inputnum, state); + if(inputnum == H8_INPUT_LINE_TEND0 && !tend0_cb.isnull()) + tend0_cb(state); + else if(inputnum == H8_INPUT_LINE_TEND1 && !tend1_cb.isnull()) + tend1_cb(state); + else if(inputnum >= H8_INPUT_LINE_DREQ0 && inputnum <= H8_INPUT_LINE_DREQ3) + dma->set_input(inputnum, state); + else + intc->set_input(inputnum, state); } int h83002_device::trapa_setup() @@ -205,6 +240,10 @@ void h83002_device::internal_update(uint64_t current_time) void h83002_device::device_start() { h8h_device::device_start(); + dma_device = dma; + + tend0_cb.resolve(); + tend1_cb.resolve(); } void h83002_device::device_reset() @@ -224,3 +263,15 @@ WRITE8_MEMBER(h83002_device::syscr_w) update_irq_filter(); logerror("syscr = %02x\n", data); } + +READ8_MEMBER(h83002_device::rtmcsr_r) +{ + // set bit 7 -- Compare Match Flag (CMF): This status flag indicates that the RTCNT and RTCOR values have matched. + return rtmcsr | 0x80; +} + +WRITE8_MEMBER(h83002_device::rtmcsr_w) +{ + rtmcsr = data; + logerror("rtmcsr = %02x\n", data); +} diff --git a/src/devices/cpu/h8/h83002.h b/src/devices/cpu/h8/h83002.h index 4f524c6f0b9..0b0b1a2c76c 100644 --- a/src/devices/cpu/h8/h83002.h +++ b/src/devices/cpu/h8/h83002.h @@ -16,22 +16,37 @@ #include "h8h.h" #include "h8_adc.h" +#include "h8_dma.h" #include "h8_port.h" #include "h8_intc.h" #include "h8_timer16.h" #include "h8_sci.h" #include "h8_watchdog.h" +#define MCFG_H83002_TEND0_CALLBACK(_devcb) \ + devcb = &h83002_device::set_tend0_callback(*device, DEVCB_##_devcb); +#define MCFG_H83002_TEND1_CALLBACK(_devcb) \ + devcb = &h83002_device::set_tend1_callback(*device, DEVCB_##_devcb); + class h83002_device : public h8h_device { public: h83002_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + template<class _Object> static devcb_base &set_tend0_callback(device_t &device, _Object object) { return downcast<h83002_device&>(device).tend0_cb.set_callback(object); } + template<class _Object> static devcb_base &set_tend1_callback(device_t &device, _Object object) { return downcast<h83002_device&>(device).tend1_cb.set_callback(object); } + DECLARE_READ8_MEMBER(syscr_r); DECLARE_WRITE8_MEMBER(syscr_w); + DECLARE_READ8_MEMBER(rtmcsr_r); + DECLARE_WRITE8_MEMBER(rtmcsr_w); + protected: required_device<h8h_intc_device> intc; required_device<h8_adc_device> adc; + optional_device<h8_dma_device> dma; + optional_device<h8_dma_channel_device> dma0; + optional_device<h8_dma_channel_device> dma1; required_device<h8_port_device> port4; required_device<h8_port_device> port6; required_device<h8_port_device> port7; @@ -50,6 +65,9 @@ protected: required_device<h8_watchdog_device> watchdog; uint8_t syscr; + uint8_t rtmcsr; + + devcb_write_line tend0_cb, tend1_cb; virtual void update_irq_filter() override; virtual void interrupt_taken() override; diff --git a/src/devices/cpu/h8/h8_dma.cpp b/src/devices/cpu/h8/h8_dma.cpp index af27444c64c..28e245e43c4 100644 --- a/src/devices/cpu/h8/h8_dma.cpp +++ b/src/devices/cpu/h8/h8_dma.cpp @@ -21,6 +21,7 @@ void h8_dma_device::device_reset() { dmabcr = 0x0000; dmawer = 0x00; + dreq[0] = dreq[1] = false; } bool h8_dma_device::trigger_dma(int vector) @@ -32,6 +33,14 @@ bool h8_dma_device::trigger_dma(int vector) return start0 || start1; } +void h8_dma_device::count_last(int id) +{ + if(id & 2) + dmach1->count_last(id & 1); + else + dmach0->count_last(id & 1); +} + void h8_dma_device::count_done(int id) { if(id & 2) @@ -45,6 +54,26 @@ void h8_dma_device::clear_dte(int id) dmabcr &= ~(0x0010 << id); } +void h8_dma_device::set_input(int inputnum, int state) +{ + if(inputnum == H8_INPUT_LINE_DREQ0) { + if(state == ASSERT_LINE) { + dmach0->start_test(h8_dma_channel_device::DREQ_LEVEL); + if(!dreq[0]) + dmach0->start_test(h8_dma_channel_device::DREQ_EDGE); + } + dreq[0] = (state == ASSERT_LINE); + } else if(inputnum == H8_INPUT_LINE_DREQ1) { + if(state == ASSERT_LINE) { + dmach1->start_test(h8_dma_channel_device::DREQ_LEVEL); + if(!dreq[1]) + dmach1->start_test(h8_dma_channel_device::DREQ_EDGE); + } + dreq[1] = (state == ASSERT_LINE); + } else + logerror("input line %d not supported for h8_dma_device\n", inputnum); +} + READ8_MEMBER(h8_dma_device::dmawer_r) { logerror("dmawer_r %02x\n", dmawer); @@ -133,7 +162,6 @@ void h8_dma_channel_device::set_id(int id) { state[0].id = id; state[1].id = id | 1; - } READ16_MEMBER(h8_dma_channel_device::marah_r) @@ -247,6 +275,75 @@ WRITE16_MEMBER(h8_dma_channel_device::dmacr_w) start_test(-1); } +// H8H DMA +READ8_MEMBER(h8_dma_channel_device::dtcra_r) +{ + logerror("dtcra_r %02x\n", dtcr[0]); + return dtcr[0]; +} + +WRITE8_MEMBER(h8_dma_channel_device::dtcra_w) +{ + dtcr[0] = data; + logerror("dtcra_w %02x\n", dtcr[0]); + if((dtcr[0] & 0x80) && (dtcr[1] & 0x80)) { // if both DTME and DTE are set, start DMA + h8h_sync(); + } +} + +READ8_MEMBER(h8_dma_channel_device::dtcrb_r) +{ + logerror("dtcrb_r %02x\n", dtcr[1]); + return dtcr[1]; +} + +WRITE8_MEMBER(h8_dma_channel_device::dtcrb_w) +{ + dtcr[1] = data; + logerror("dtcrb_w %02x\n", dtcr[1]); + if((dtcr[0] & 0x80) && (dtcr[1] & 0x80)) { // if both DTME and DTE are set, start DMA + h8h_sync(); + } +} + +void h8_dma_channel_device::h8h_sync() +{ + // update DMACR + dmacr = 0; + if(BIT(dtcr[0], 6)) dmacr |= 1 << 15; // DTSZ + dmacr |= ((dtcr[0] & 0b110000) >> 4) << 13; // SAID, SAIDE + if(BIT(dtcr[0], 0)) dmacr |= 1 << 11; // BLKE + if(BIT(dtcr[1], 3)) dmacr |= 1 << 12; // BLKDIR (TMS) + dmacr |= ((dtcr[1] & 0b110000) >> 4) << 5; // DAID, DAIDE + if(BIT(dmacr, 11)) { + // Block Transfer Mode + switch(dtcr[1] & 0b111) { // DTS + case 0b000: dmacr |= 0b1000; break; // ITU channel 0 + case 0b001: dmacr |= 0b1001; break; // ITU channel 1 + case 0b010: dmacr |= 0b1010; break; // ITU channel 2 + case 0b011: dmacr |= 0b1011; break; // ITU channel 3 + case 0b110: dmacr |= 0b1000; break; // DREQ falling edge + } + } else { + // Normal Mode + switch(dtcr[1] & 0b111) { // DTS + case 0b000: dmacr |= 0b0111; break; // Auto-request (burst mode) + case 0b010: dmacr |= 0b0110; break; // Auto-request (cycle-steal mode) + case 0b110: dmacr |= 0b0010; break; // DREQ falling edge + case 0b111: dmacr |= 0b0011; break; // DREQ low-level + } + } + + // set_bcr + bool _fae = (dtcr[0] & 0b110) == 0b110; // A channel operates in full address mode when DTS2A and DTS1A are both set to 1. + uint8_t _dta = 0; // don't support + uint8_t _dte = BIT(dtcr[0], 7) ? 0b11 : 0b00; + uint8_t _dtie = BIT(dtcr[0], 3) ? 0b11 : 0b00; + set_bcr(_fae, !_fae, _dta, _dte, _dtie); + + start_test(-1); +} + void h8_dma_channel_device::set_bcr(bool _fae, bool _sae, uint8_t _dta, uint8_t _dte, uint8_t _dtie) { fae = _fae; @@ -267,11 +364,18 @@ bool h8_dma_channel_device::start_test(int vector) if(dmacr & 0x0800) throw emu_fatalerror("%s: DMA startup test in full address/block mode unimplemented.\n", tag()); else { - if((dmacr & 0x0006) == 0x0006) { + // Normal Mode + if(vector == -1) { start(0); return true; - } else - throw emu_fatalerror("%s: DMA startup test in full address/normal mode/dreq unimplemented.\n", tag()); + } else { + // DREQ trigger + if(((dmacr & 0b111) == 0b0010 && vector == DREQ_EDGE) || ((dmacr & 0b111) == 0b0011 && vector == DREQ_LEVEL)) { + state[0].suspended = false; + return true; + } + } + return false; } } else { if(dte == 0) @@ -291,6 +395,8 @@ void h8_dma_channel_device::start(int submodule) state[submodule].dest = mar[1]; state[submodule].count = etcr[0] ? etcr[0] : 0x10000; state[submodule].mode_16 = dmacr & 0x8000; + state[submodule].autoreq = (dmacr & 6) == 6; + state[submodule].suspended = !state[submodule].autoreq; // non-auto-request transfers start suspended int32_t step = state[submodule].mode_16 ? 2 : 1; state[submodule].incs = dmacr & 0x2000 ? dmacr & 0x4000 ? -step : step : 0; state[submodule].incd = dmacr & 0x0020 ? dmacr & 0x0040 ? -step : step : 0; @@ -301,16 +407,25 @@ void h8_dma_channel_device::start(int submodule) } } +void h8_dma_channel_device::count_last(int submodule) +{ + logerror("count last on %d\n", submodule); + if(!state[submodule].autoreq) // "The TEND signal goes low during the last write cycle." + cpu->set_input_line(H8_INPUT_LINE_TEND0 + (state[submodule].id >> 1), ASSERT_LINE); +} void h8_dma_channel_device::count_done(int submodule) { logerror("count done on %d\n", submodule); + if(!state[submodule].autoreq) + cpu->set_input_line(H8_INPUT_LINE_TEND0 + (state[submodule].id >> 1), CLEAR_LINE); if(fae) { if(dmacr & 0x0800) throw emu_fatalerror("%s: DMA count done full address/block mode unimplemented.\n", tag()); else { dte &= ~1; dmac->clear_dte(state[0].id); + dtcr[0] &= ~0x80; // clear DTE (for H8H) if(dtie & 1) throw emu_fatalerror("%s: DMA end-of-transfer interrupt in full address/normal mode unimplemented.\n", tag()); } diff --git a/src/devices/cpu/h8/h8_dma.h b/src/devices/cpu/h8/h8_dma.h index 7ffd415b2de..e703f14b52c 100644 --- a/src/devices/cpu/h8/h8_dma.h +++ b/src/devices/cpu/h8/h8_dma.h @@ -19,6 +19,8 @@ struct h8_dma_state { int32_t incs, incd; uint32_t count; int id; + bool autoreq; // activate by auto-request + bool suspended; bool mode_16; }; @@ -31,6 +33,19 @@ struct h8_dma_state { class h8_dma_channel_device; +enum { + // mind the order, all DREQ, TEND need to be sequential + H8_INPUT_LINE_DREQ0 = INPUT_LINE_IRQ9 + 1, + H8_INPUT_LINE_DREQ1, + H8_INPUT_LINE_DREQ2, + H8_INPUT_LINE_DREQ3, + + H8_INPUT_LINE_TEND0, + H8_INPUT_LINE_TEND1, + H8_INPUT_LINE_TEND2, + H8_INPUT_LINE_TEND3, +}; + class h8_dma_device : public device_t { public: h8_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -43,15 +58,20 @@ public: DECLARE_WRITE16_MEMBER(dmabcr_w); bool trigger_dma(int vector); + void count_last(int id); void count_done(int id); void clear_dte(int id); + void set_input(int inputnum, int state); + protected: required_device<h8_dma_channel_device> dmach0, dmach1; virtual void device_start() override; virtual void device_reset() override; + bool dreq[2]; + uint8_t dmawer, dmatcr; uint16_t dmabcr; }; @@ -96,9 +116,16 @@ public: DECLARE_READ16_MEMBER(dmacr_r); DECLARE_WRITE16_MEMBER(dmacr_w); + // H8H DMA + DECLARE_READ8_MEMBER(dtcra_r); + DECLARE_WRITE8_MEMBER(dtcra_w); + DECLARE_READ8_MEMBER(dtcrb_r); + DECLARE_WRITE8_MEMBER(dtcrb_w); + void set_id(int id); void set_bcr(bool fae, bool sae, uint8_t dta, uint8_t dte, uint8_t dtie); bool start_test(int vector); + void count_last(int submodule); void count_done(int submodule); protected: required_device<h8_dma_device> dmac; @@ -112,12 +139,15 @@ protected: uint32_t mar[2]; uint16_t ioar[2], etcr[2], dmacr; + uint8_t dtcr[2]; // H8H uint8_t dta, dte, dtie; - bool fae, sae; + bool fae; // Full-Address Mode + bool sae; // Short-Address Mode virtual void device_start() override; virtual void device_reset() override; + void h8h_sync(); // call set_bcr with contents from DTCR void start(int submodule); }; |