trunk/src/emu/cpu/h8/h83008.c
| r29200 | r29201 | |
| 1 | #include "emu.h" |
| 2 | #include "h83008.h" |
| 3 | #include "h8_adc.h" |
| 4 | |
| 5 | const device_type H83008 = &device_creator<h83008_device>; |
| 6 | |
| 7 | h83008_device::h83008_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 8 | h8h_device(mconfig, H83008, "H8/3008", tag, owner, clock, "h83008", __FILE__, address_map_delegate(FUNC(h83008_device::map), this)), |
| 9 | intc(*this, "intc"), |
| 10 | adc(*this, "adc"), |
| 11 | port4(*this, "port4"), |
| 12 | port6(*this, "port6"), |
| 13 | port7(*this, "port7"), |
| 14 | port8(*this, "port8"), |
| 15 | port9(*this, "port9"), |
| 16 | porta(*this, "porta"), |
| 17 | portb(*this, "portb"), |
| 18 | timer16(*this, "timer16"), |
| 19 | timer16_0(*this, "timer16:0"), |
| 20 | timer16_1(*this, "timer16:1"), |
| 21 | timer16_2(*this, "timer16:2"), |
| 22 | sci0(*this, "sci0"), |
| 23 | sci1(*this, "sci1") |
| 24 | { |
| 25 | } |
| 26 | |
| 27 | static MACHINE_CONFIG_FRAGMENT(h83008) |
| 28 | MCFG_H8H_INTC_ADD("intc") |
| 29 | MCFG_H8_ADC_3006_ADD("adc", "intc", 23) |
| 30 | MCFG_H8_PORT_ADD("port4", h8_device::PORT_4, 0x00, 0x00) |
| 31 | MCFG_H8_PORT_ADD("port6", h8_device::PORT_6, 0x80, 0x80) |
| 32 | MCFG_H8_PORT_ADD("port7", h8_device::PORT_7, 0xff, 0x00) |
| 33 | MCFG_H8_PORT_ADD("port8", h8_device::PORT_8, 0xf0, 0xe0) |
| 34 | MCFG_H8_PORT_ADD("port9", h8_device::PORT_9, 0xc0, 0xc0) |
| 35 | MCFG_H8_PORT_ADD("porta", h8_device::PORT_A, 0x80, 0x00) |
| 36 | MCFG_H8_PORT_ADD("portb", h8_device::PORT_B, 0x00, 0x00) |
| 37 | MCFG_H8_TIMER16_ADD("timer16", 3, 0xf8) |
| 38 | MCFG_H8H_TIMER16_CHANNEL_ADD("timer16:0", 2, 2, "intc", 24) |
| 39 | MCFG_H8H_TIMER16_CHANNEL_ADD("timer16:1", 2, 2, "intc", 28) |
| 40 | MCFG_H8H_TIMER16_CHANNEL_ADD("timer16:2", 2, 2, "intc", 32) |
| 41 | MCFG_H8_SCI_ADD("sci0", "intc", 52, 53, 54, 55) |
| 42 | MCFG_H8_SCI_ADD("sci1", "intc", 56, 57, 58, 59) |
| 43 | MACHINE_CONFIG_END |
| 44 | |
| 45 | DEVICE_ADDRESS_MAP_START(map, 16, h83008_device) |
| 46 | AM_RANGE(0xfee002, 0xfee003) AM_DEVWRITE8( "port4", h8_port_device, ddr_w, 0x00ff) |
| 47 | AM_RANGE(0xfee004, 0xfee005) AM_DEVWRITE8( "port6", h8_port_device, ddr_w, 0x00ff) |
| 48 | AM_RANGE(0xfee006, 0xfee007) AM_DEVWRITE8( "port8", h8_port_device, ddr_w, 0x00ff) |
| 49 | AM_RANGE(0xfee008, 0xfee009) AM_DEVWRITE8( "port9", h8_port_device, ddr_w, 0xff00) |
| 50 | AM_RANGE(0xfee008, 0xfee009) AM_DEVWRITE8( "porta", h8_port_device, ddr_w, 0x00ff) |
| 51 | AM_RANGE(0xfee00a, 0xfee00b) AM_DEVWRITE8( "portb", h8_port_device, ddr_w, 0xff00) |
| 52 | |
| 53 | AM_RANGE(0xfee012, 0xfee013) AM_READWRITE8( syscr_r, syscr_w, 0xff00) |
| 54 | AM_RANGE(0xfee014, 0xfee015) AM_DEVREADWRITE8("intc", h8h_intc_device, iscr_r, iscr_w, 0xff00) |
| 55 | AM_RANGE(0xfee014, 0xfee015) AM_DEVREADWRITE8("intc", h8h_intc_device, ier_r, ier_w, 0x00ff) |
| 56 | AM_RANGE(0xfee016, 0xfee017) AM_DEVREADWRITE8("intc", h8h_intc_device, isr_r, isr_w, 0xff00) |
| 57 | AM_RANGE(0xfee018, 0xfee019) AM_DEVREADWRITE8("intc", h8h_intc_device, icr_r, icr_w, 0xffff) |
| 58 | |
| 59 | AM_RANGE(0xfee03e, 0xfee03f) AM_DEVREADWRITE8("port4", h8_port_device, pcr_r, pcr_w, 0xff00) |
| 60 | |
| 61 | AM_RANGE(0xffef20, 0xffff1f) AM_RAM |
| 62 | |
| 63 | AM_RANGE(0xffff60, 0xffff61) AM_DEVREADWRITE8("timer16", h8_timer16_device, tstr_r, tstr_w, 0xff00) |
| 64 | AM_RANGE(0xffff60, 0xffff61) AM_DEVREADWRITE8("timer16", h8_timer16_device, tsyr_r, tsyr_w, 0x00ff) |
| 65 | AM_RANGE(0xffff62, 0xffff63) AM_DEVREADWRITE8("timer16", h8_timer16_device, tmdr_r, tmdr_w, 0xff00) |
| 66 | AM_RANGE(0xffff62, 0xffff63) AM_DEVWRITE8( "timer16", h8_timer16_device, tolr_w, 0x00ff) |
| 67 | AM_RANGE(0xffff64, 0xffff65) AM_DEVREADWRITE8("timer16", h8_timer16_device, tisr_r, tisr_w, 0xffff) |
| 68 | AM_RANGE(0xffff66, 0xffff67) AM_DEVREADWRITE8("timer16", h8_timer16_device, tisrc_r, tisrc_w, 0xff00) |
| 69 | AM_RANGE(0xffff68, 0xffff69) AM_DEVREADWRITE8("timer16:0", h8_timer16_channel_device, tcr_r, tcr_w, 0xff00) |
| 70 | AM_RANGE(0xffff68, 0xffff69) AM_DEVREADWRITE8("timer16:0", h8_timer16_channel_device, tior_r, tior_w, 0x00ff) |
| 71 | AM_RANGE(0xffff6a, 0xffff6b) AM_DEVREADWRITE( "timer16:0", h8_timer16_channel_device, tcnt_r, tcnt_w ) |
| 72 | AM_RANGE(0xffff6c, 0xffff6f) AM_DEVREADWRITE( "timer16:0", h8_timer16_channel_device, tgr_r, tgr_w ) |
| 73 | AM_RANGE(0xffff70, 0xffff71) AM_DEVREADWRITE8("timer16:1", h8_timer16_channel_device, tcr_r, tcr_w, 0xff00) |
| 74 | AM_RANGE(0xffff70, 0xffff71) AM_DEVREADWRITE8("timer16:1", h8_timer16_channel_device, tior_r, tior_w, 0x00ff) |
| 75 | AM_RANGE(0xffff72, 0xffff73) AM_DEVREADWRITE( "timer16:1", h8_timer16_channel_device, tcnt_r, tcnt_w ) |
| 76 | AM_RANGE(0xffff74, 0xffff77) AM_DEVREADWRITE( "timer16:1", h8_timer16_channel_device, tgr_r, tgr_w ) |
| 77 | AM_RANGE(0xffff78, 0xffff79) AM_DEVREADWRITE8("timer16:2", h8_timer16_channel_device, tcr_r, tcr_w, 0xff00) |
| 78 | AM_RANGE(0xffff78, 0xffff79) AM_DEVREADWRITE8("timer16:2", h8_timer16_channel_device, tior_r, tior_w, 0x00ff) |
| 79 | AM_RANGE(0xffff7a, 0xffff7b) AM_DEVREADWRITE( "timer16:2", h8_timer16_channel_device, tcnt_r, tcnt_w ) |
| 80 | AM_RANGE(0xffff7c, 0xffff7f) AM_DEVREADWRITE( "timer16:2", h8_timer16_channel_device, tgr_r, tgr_w ) |
| 81 | |
| 82 | AM_RANGE(0xffffb0, 0xffffb1) AM_DEVREADWRITE8("sci0", h8_sci_device, smr_r, smr_w, 0xff00) |
| 83 | AM_RANGE(0xffffb0, 0xffffb1) AM_DEVREADWRITE8("sci0", h8_sci_device, brr_r, brr_w, 0x00ff) |
| 84 | AM_RANGE(0xffffb2, 0xffffb3) AM_DEVREADWRITE8("sci0", h8_sci_device, scr_r, scr_w, 0xff00) |
| 85 | AM_RANGE(0xffffb2, 0xffffb3) AM_DEVREADWRITE8("sci0", h8_sci_device, tdr_r, tdr_w, 0x00ff) |
| 86 | AM_RANGE(0xffffb4, 0xffffb5) AM_DEVREADWRITE8("sci0", h8_sci_device, ssr_r, ssr_w, 0xff00) |
| 87 | AM_RANGE(0xffffb4, 0xffffb5) AM_DEVREAD8( "sci0", h8_sci_device, rdr_r, 0x00ff) |
| 88 | AM_RANGE(0xffffb6, 0xffffb7) AM_DEVREADWRITE8("sci0", h8_sci_device, scmr_r, scmr_w, 0xff00) |
| 89 | AM_RANGE(0xffffb8, 0xffffb9) AM_DEVREADWRITE8("sci1", h8_sci_device, smr_r, smr_w, 0xff00) |
| 90 | AM_RANGE(0xffffb8, 0xffffb9) AM_DEVREADWRITE8("sci1", h8_sci_device, brr_r, brr_w, 0x00ff) |
| 91 | AM_RANGE(0xffffba, 0xffffbb) AM_DEVREADWRITE8("sci1", h8_sci_device, scr_r, scr_w, 0xff00) |
| 92 | AM_RANGE(0xffffba, 0xffffbb) AM_DEVREADWRITE8("sci1", h8_sci_device, tdr_r, tdr_w, 0x00ff) |
| 93 | AM_RANGE(0xffffbc, 0xffffbd) AM_DEVREADWRITE8("sci1", h8_sci_device, ssr_r, ssr_w, 0xff00) |
| 94 | AM_RANGE(0xffffbc, 0xffffbd) AM_DEVREAD8( "sci1", h8_sci_device, rdr_r, 0x00ff) |
| 95 | AM_RANGE(0xffffbe, 0xffffbf) AM_DEVREADWRITE8("sci1", h8_sci_device, scmr_r, scmr_w, 0xff00) |
| 96 | AM_RANGE(0xffffd2, 0xffffd3) AM_DEVREADWRITE8("port4", h8_port_device, port_r, dr_w, 0x00ff) |
| 97 | AM_RANGE(0xffffd4, 0xffffd5) AM_DEVREADWRITE8("port6", h8_port_device, port_r, dr_w, 0x00ff) |
| 98 | AM_RANGE(0xffffd6, 0xffffd7) AM_DEVREADWRITE8("port7", h8_port_device, port_r, dr_w, 0xff00) |
| 99 | AM_RANGE(0xffffd6, 0xffffd7) AM_DEVREADWRITE8("port8", h8_port_device, port_r, dr_w, 0x00ff) |
| 100 | AM_RANGE(0xffffd8, 0xffffd9) AM_DEVREADWRITE8("port9", h8_port_device, port_r, dr_w, 0xff00) |
| 101 | AM_RANGE(0xffffd8, 0xffffd9) AM_DEVREADWRITE8("porta", h8_port_device, port_r, dr_w, 0x00ff) |
| 102 | AM_RANGE(0xffffda, 0xffffdb) AM_DEVREADWRITE8("portb", h8_port_device, port_r, dr_w, 0xff00) |
| 103 | |
| 104 | AM_RANGE(0xffffe0, 0xffffe7) AM_DEVREAD8( "adc", h8_adc_device, addr8_r, 0xffff) |
| 105 | AM_RANGE(0xffffe8, 0xffffe9) AM_DEVREADWRITE8("adc", h8_adc_device, adcsr_r, adcsr_w, 0xff00) |
| 106 | AM_RANGE(0xffffe8, 0xffffe9) AM_DEVREADWRITE8("adc", h8_adc_device, adcr_r, adcr_w, 0x00ff) |
| 107 | ADDRESS_MAP_END |
| 108 | |
| 109 | machine_config_constructor h83008_device::device_mconfig_additions() const |
| 110 | { |
| 111 | return MACHINE_CONFIG_NAME(h83008); |
| 112 | } |
| 113 | |
| 114 | void h83008_device::execute_set_input(int inputnum, int state) |
| 115 | { |
| 116 | intc->set_input(inputnum, state); |
| 117 | } |
| 118 | |
| 119 | int h83008_device::trapa_setup() |
| 120 | { |
| 121 | if(syscr & 0x08) |
| 122 | CCR |= F_I; |
| 123 | else |
| 124 | CCR |= F_I|F_UI; |
| 125 | return 8; |
| 126 | } |
| 127 | |
| 128 | void h83008_device::irq_setup() |
| 129 | { |
| 130 | if(syscr & 0x08) |
| 131 | CCR |= F_I; |
| 132 | else |
| 133 | CCR |= F_I|F_UI; |
| 134 | } |
| 135 | |
| 136 | void h83008_device::update_irq_filter() |
| 137 | { |
| 138 | switch(syscr & 0x08) { |
| 139 | case 0x00: |
| 140 | if((CCR & (F_I|F_UI)) == (F_I|F_UI)) |
| 141 | intc->set_filter(2, -1); |
| 142 | else if(CCR & F_I) |
| 143 | intc->set_filter(1, -1); |
| 144 | else |
| 145 | intc->set_filter(0, -1); |
| 146 | break; |
| 147 | case 0x08: |
| 148 | if(CCR & F_I) |
| 149 | intc->set_filter(2, -1); |
| 150 | else |
| 151 | intc->set_filter(0, -1); |
| 152 | break; |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | void h83008_device::interrupt_taken() |
| 157 | { |
| 158 | standard_irq_callback(intc->interrupt_taken(taken_irq_vector)); |
| 159 | } |
| 160 | |
| 161 | void h83008_device::internal_update(UINT64 current_time) |
| 162 | { |
| 163 | UINT64 event_time = 0; |
| 164 | |
| 165 | add_event(event_time, adc->internal_update(current_time)); |
| 166 | add_event(event_time, sci0->internal_update(current_time)); |
| 167 | add_event(event_time, sci1->internal_update(current_time)); |
| 168 | add_event(event_time, timer16_0->internal_update(current_time)); |
| 169 | add_event(event_time, timer16_1->internal_update(current_time)); |
| 170 | add_event(event_time, timer16_2->internal_update(current_time)); |
| 171 | |
| 172 | recompute_bcount(event_time); |
| 173 | } |
| 174 | |
| 175 | void h83008_device::device_start() |
| 176 | { |
| 177 | h8h_device::device_start(); |
| 178 | } |
| 179 | |
| 180 | void h83008_device::device_reset() |
| 181 | { |
| 182 | h8h_device::device_reset(); |
| 183 | syscr = 0x09; |
| 184 | } |
| 185 | |
| 186 | |
| 187 | READ8_MEMBER(h83008_device::syscr_r) |
| 188 | { |
| 189 | return syscr; |
| 190 | } |
| 191 | |
| 192 | WRITE8_MEMBER(h83008_device::syscr_w) |
| 193 | { |
| 194 | syscr = data; |
| 195 | update_irq_filter(); |
| 196 | logerror("%s: syscr = %02x\n", tag(), data); |
| 197 | } |
trunk/src/emu/cpu/h8/h83008.h
| r29200 | r29201 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | h83008.h |
| 4 | |
| 5 | H8/3008 |
| 6 | |
| 7 | H8/300H-based mcu. |
| 8 | |
| 9 | **************************************************************************** |
| 10 | |
| 11 | Copyright Olivier Galibert |
| 12 | All rights reserved. |
| 13 | |
| 14 | Redistribution and use in source and binary forms, with or without |
| 15 | modification, are permitted provided that the following conditions are |
| 16 | met: |
| 17 | |
| 18 | * Redistributions of source code must retain the above copyright |
| 19 | notice, this list of conditions and the following disclaimer. |
| 20 | * Redistributions in binary form must reproduce the above copyright |
| 21 | notice, this list of conditions and the following disclaimer in |
| 22 | the documentation and/or other materials provided with the |
| 23 | distribution. |
| 24 | * Neither the name 'MAME' nor the names of its contributors may be |
| 25 | used to endorse or promote products derived from this software |
| 26 | without specific prior written permission. |
| 27 | |
| 28 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR |
| 29 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 30 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 31 | DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT, |
| 32 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 33 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 34 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 35 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 36 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 37 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 38 | POSSIBILITY OF SUCH DAMAGE. |
| 39 | |
| 40 | ***************************************************************************/ |
| 41 | |
| 42 | #ifndef __H83008_H__ |
| 43 | #define __H83008_H__ |
| 44 | |
| 45 | #include "h8h.h" |
| 46 | #include "h8_adc.h" |
| 47 | #include "h8_port.h" |
| 48 | #include "h8_intc.h" |
| 49 | #include "h8_sci.h" |
| 50 | #include "h8_timer16.h" |
| 51 | |
| 52 | class h83008_device : public h8h_device { |
| 53 | public: |
| 54 | h83008_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); |
| 55 | h83008_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 56 | |
| 57 | DECLARE_READ8_MEMBER(syscr_r); |
| 58 | DECLARE_WRITE8_MEMBER(syscr_w); |
| 59 | |
| 60 | protected: |
| 61 | required_device<h8h_intc_device> intc; |
| 62 | required_device<h8_adc_device> adc; |
| 63 | required_device<h8_port_device> port4; |
| 64 | required_device<h8_port_device> port6; |
| 65 | required_device<h8_port_device> port7; |
| 66 | required_device<h8_port_device> port8; |
| 67 | required_device<h8_port_device> port9; |
| 68 | required_device<h8_port_device> porta; |
| 69 | required_device<h8_port_device> portb; |
| 70 | required_device<h8_timer16_device> timer16; |
| 71 | required_device<h8h_timer16_channel_device> timer16_0; |
| 72 | required_device<h8h_timer16_channel_device> timer16_1; |
| 73 | required_device<h8h_timer16_channel_device> timer16_2; |
| 74 | required_device<h8_sci_device> sci0; |
| 75 | required_device<h8_sci_device> sci1; |
| 76 | |
| 77 | UINT8 syscr; |
| 78 | |
| 79 | virtual void update_irq_filter(); |
| 80 | virtual void interrupt_taken(); |
| 81 | virtual int trapa_setup(); |
| 82 | virtual void irq_setup(); |
| 83 | virtual void internal_update(UINT64 current_time); |
| 84 | virtual machine_config_constructor device_mconfig_additions() const; |
| 85 | DECLARE_ADDRESS_MAP(map, 16); |
| 86 | |
| 87 | virtual void device_start(); |
| 88 | virtual void device_reset(); |
| 89 | virtual void execute_set_input(int inputnum, int state); |
| 90 | }; |
| 91 | |
| 92 | extern const device_type H83008; |
| 93 | |
| 94 | #endif |