/***************************************************************************************1* Genesis Plus2* Z80 bank access to 68k bus3*4* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)5* Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX)6*7* Redistribution and use of this code or any derivative works are permitted8* provided that the following conditions are met:9*10* - Redistributions may not be sold, nor may they be used in a commercial11* product or activity.12*13* - Redistributions that are modified from the original source must include the14* complete source code, including the source code for all components used by a15* binary built from the modified sources. However, as a special exception, the16* source code distributed need not include anything that is normally distributed17* (in either source or binary form) with the major components (compiler, kernel,18* and so on) of the operating system on which the executable runs, unless that19* component itself accompanies the executable.20*21* - Redistributions must reproduce the above copyright notice, this list of22* conditions and the following disclaimer in the documentation and/or other23* materials provided with the distribution.24*25* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"26* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE27* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE28* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE29* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR30* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF31* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS32* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN33* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)34* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE35* POSSIBILITY OF SUCH DAMAGE.36*37****************************************************************************************/3839#include "shared.h"4041/*42Handlers for access to unused addresses and those which make the43machine lock up.44*/4546unsigned int zbank_unused_r(unsigned int address)47{48#ifdef LOGERROR49error("Z80 bank unused read %06X (%x)\n", address, Z80.pc.d);50#endif51return 0xFF;52}5354void zbank_unused_w(unsigned int address, unsigned int data)55{56#ifdef LOGERROR57error("Z80 bank unused write %06X = %02X (%x)\n", address, data, Z80.pc.d);58#endif59}6061unsigned int zbank_lockup_r(unsigned int address)62{63#ifdef LOGERROR64error("Z80 bank lockup read %06X (%x)\n", address, Z80.pc.d);65#endif66if (!config.force_dtack)67{68Z80.cycles = 0xFFFFFFFF;69zstate = 0;70}71return 0xFF;72}7374void zbank_lockup_w(unsigned int address, unsigned int data)75{76#ifdef LOGERROR77error("Z80 bank lockup write %06X = %02X (%x)\n", address, data, Z80.pc.d);78#endif79if (!config.force_dtack)80{81Z80.cycles = 0xFFFFFFFF;82zstate = 0;83}84}8586/* I/O & Control registers */87unsigned int zbank_read_ctrl_io(unsigned int address)88{89switch ((address >> 8) & 0xFF)90{91case 0x00: /* I/O chip */92{93if (!(address & 0xE0))94{95return (io_68k_read((address >> 1) & 0x0F));96}97return zbank_unused_r(address);98}99100case 0x11: /* BUSACK */101{102if (address & 1)103{104return zbank_unused_r(address);105}106return 0xFF;107}108109case 0x30: /* TIME */110{111if (cart.hw.time_r)112{113unsigned int data = cart.hw.time_r(address);114if (address & 1)115{116return (data & 0xFF);117}118return (data >> 8);119}120return zbank_unused_r(address);121}122123case 0x41: /* OS ROM */124{125if (address & 1)126{127return (gen_bankswitch_r() | 0xFE);128}129return zbank_unused_r(address);130}131132case 0x10: /* MEMORY MODE */133case 0x12: /* RESET */134case 0x20: /* MEGA-CD */135case 0x40: /* TMSS */136case 0x44: /* RADICA */137case 0x50: /* SVP REGISTERS */138{139return zbank_unused_r(address);140}141142default: /* Invalid address */143{144return zbank_lockup_r(address);145}146}147}148149void zbank_write_ctrl_io(unsigned int address, unsigned int data)150{151switch ((address >> 8) & 0xFF)152{153case 0x00: /* I/O chip */154{155/* get /LWR only */156if ((address & 0xE1) == 0x01)157{158io_68k_write((address >> 1) & 0x0F, data);159return;160}161zbank_unused_w(address, data);162return;163}164165case 0x11: /* BUSREQ */166{167if (!(address & 1))168{169gen_zbusreq_w(data & 1, Z80.cycles);170return;171}172zbank_unused_w(address, data);173return;174}175176case 0x12: /* RESET */177{178if (!(address & 1))179{180gen_zreset_w(data & 1, Z80.cycles);181return;182}183zbank_unused_w(address, data);184return;185}186187case 0x30: /* TIME */188{189cart.hw.time_w(address, data);190return;191}192193case 0x41: /* OS ROM */194{195if ((config.bios & 1) && (address & 1))196{197gen_bankswitch_w(data & 1);198return;199}200zbank_unused_w(address, data);201return;202}203204case 0x10: /* MEMORY MODE */205case 0x20: /* MEGA-CD */206case 0x40: /* TMSS */207case 0x44: /* RADICA */208case 0x50: /* SVP REGISTERS */209{210zbank_unused_w(address, data);211return;212}213214default: /* Invalid address */215{216zbank_lockup_w(address, data);217return;218}219}220}221222223/* VDP */224unsigned int zbank_read_vdp(unsigned int address)225{226switch (address & 0xFD)227{228case 0x00: /* DATA */229{230return (vdp_68k_data_r() >> 8);231}232233case 0x01: /* DATA */234{235return (vdp_68k_data_r() & 0xFF);236}237238case 0x04: /* CTRL */239{240return (((vdp_68k_ctrl_r(Z80.cycles) >> 8) & 3) | 0xFC);241}242243case 0x05: /* CTRL */244{245return (vdp_68k_ctrl_r(Z80.cycles) & 0xFF);246}247248case 0x08: /* HVC */249case 0x0C:250{251return (vdp_hvc_r(Z80.cycles) >> 8);252}253254case 0x09: /* HVC */255case 0x0D:256{257return (vdp_hvc_r(Z80.cycles) & 0xFF);258}259260case 0x18: /* Unused */261case 0x19:262case 0x1C:263case 0x1D:264{265return zbank_unused_r(address);266}267268default: /* Invalid address */269{270return zbank_lockup_r(address);271}272}273}274275void zbank_write_vdp(unsigned int address, unsigned int data)276{277switch (address & 0xFC)278{279case 0x00: /* Data port */280{281vdp_68k_data_w(data << 8 | data);282return;283}284285case 0x04: /* Control port */286{287vdp_68k_ctrl_w(data << 8 | data);288return;289}290291case 0x10: /* PSG */292case 0x14:293{294if (address & 1)295{296SN76489_Write(Z80.cycles, data);297return;298}299zbank_unused_w(address, data);300return;301}302303case 0x18: /* Unused */304{305zbank_unused_w(address, data);306return;307}308309case 0x1C: /* TEST register */310{311vdp_test_w(data << 8 | data);312return;313}314315default: /* Invalid address */316{317zbank_lockup_w(address, data);318return;319}320}321}322323324